设计模式之工厂模式

工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。 
工厂模式可以分为三类: 

1)简单工厂模式(Simple Factory) 
2)工厂方法模式(Factory Method) 
3)抽象工厂模式(Abstract Factory) 

 这三种模式从上到下逐步抽象,并且更具一般性。 

GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。

(1)简单工厂模式

背景:一个用户要生产不同类型的车,如宝马、奥迪、奔驰等,用户不用在自己的类中直接new,而是通过简单的工厂进行生产,但是成产的车辆强依赖于用户的传参需求。类图如下

 

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.simpefactory;

/**
 * @author admin
 * @version $Id Car.java, v 0.1 2015-10-18 下午1:02 admin Exp $$
 */
public class Car {
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.simpefactory;

/**
 * @author admin
 * @version $Id Audi.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public class Audi extends Car {
    public Audi() {
        System.out.println("Product AudiBusiness!");
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.simpefactory;

import com.sun.tools.doclets.internal.toolkit.util.SourceToHTMLConverter;

/**
 * @author admin
 * @version $Id Benz.java, v 0.1 2015-10-18 下午1:04 admin Exp $$
 */
public class Benz extends Car {
    public Benz() {
        super();
        System.out.println("Product BenzBusiness!");
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.simpefactory;

/**
 * @author admin
 * @version $Id Bmw.java, v 0.1 2015-10-18 下午1:03 admin Exp $$
 */
public class Bmw extends Car {
    public Bmw() {
        super();
        System.out.println("Product BmwBusiness!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.simpefactory;


/**
 * @author admin
 * @version $Id CarFactory.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public class CarFactory {
    public static Car createCar(String type){
        if (type.equals("AudiBusiness")){
            return new Audi();
        }else if (type.equals("BenzBusiness")){
            return new Benz();
        }else if (type.equals("BmwBusiness")){
            return new Bmw();
        }
        return null;
    }

}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.simpefactory;

/**
 * @author admin
 * @version $Id Customer.java, v 0.1 2015-10-18 下午1:16 admin Exp $$
 */
public class Customer {
    public static void main(String[] args) {
        //生产一个宝马
        Car car = CarFactory.createCar("BmwBusiness");
        if (car == null) {
            System.out.println("Procuct BmwBusiness failed!");
        }
        //生产一个奥迪
        Car car1 = CarFactory.createCar("AudiBusiness");
        if (car1 == null) {
            System.out.println("Product AudiBusiness failed!");
        }
        //生产一个奔驰
        Car car2 = CarFactory.createCar("BenzBusiness");
        if (car2 == null) {
            System.out.println("Product BenzBusiness failed!");
        }
        //生产一个大众
        Car car3 = CarFactory.createCar("dazhong");
        if (car3 == null) {
            System.out.println("Product 大众 failed!");
        }

    }
}

运行结果:

Product BmwBusiness!
Product AudiBusiness!
Product BenzBusiness!
Product 大众 failed!

 

 

(2)工厂模式

对于简单的工厂强依赖于用户输入,而且当增加了一个新的车辆种类时,对于工厂需要进行修改容易破坏原来的代码逻辑,不符合开闭原则。如下是工厂模式

每一种车型都已一种对应的工厂,当新增车型时只用扩展,不用修改就能够完成新的车型工厂生产。

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id Car.java, v 0.1 2015-10-18 下午1:02 admin Exp $$
 */
public class Car {
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id Audi.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public class Audi extends Car {
    public Audi() {
        System.out.println("Product AudiBusiness!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id Benz.java, v 0.1 2015-10-18 下午1:04 admin Exp $$
 */
public class Benz extends Car {
    public Benz() {
        super();
        System.out.println("Product BenzBusiness!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id Bmw.java, v 0.1 2015-10-18 下午1:03 admin Exp $$
 */
public class Bmw extends Car {
    public Bmw() {
        super();
        System.out.println("Product BmwBusiness!");
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;


/**
 * @author admin
 * @version $Id CarFactory.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public interface CarFactory {
    public Car createCar();
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id AudiFactory.java, v 0.1 2015-10-18 下午1:35 admin Exp $$
 */
public class AudiFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Audi();
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id BenzFactory.java, v 0.1 2015-10-18 下午1:36 admin Exp $$
 */
public class BenzFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Benz();
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id BmwFactory.java, v 0.1 2015-10-18 下午1:36 admin Exp $$
 */
public class BmwFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Bmw();
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.factorymethod;

/**
 * @author admin
 * @version $Id Customer.java, v 0.1 2015-10-18 下午1:16 admin Exp $$
 */
public class Customer {
    public static void main(String[] args) {
        //生产一个宝马
        CarFactory carFactory = new BmwFactory();
        Car car = carFactory.createCar();
        if (car == null) {
            System.out.println("Procuct BmwBusiness failed!");
        }
        //生产一个奥迪
        carFactory = new AudiFactory();
        Car car1 = carFactory.createCar();
        if (car1 == null) {
            System.out.println("Product AudiBusiness failed!");
        }
        //生产一个奔驰
        carFactory = new BenzFactory();
        Car car2 = carFactory.createCar();
        if (car2 == null) {
            System.out.println("Product BenzBusiness failed!");
        }
    }
}

运行结果:

Product BmwBusiness!
Product AudiBusiness!
Product BenzBusiness!

(3)抽象工厂模式

抽象工厂使用的时候主要是业务比较复杂的时候才会考虑,比如当车的种类已经不仅仅是一个维度了,除了车的品牌,还要涉及到车的类型,如跑车、商务车等。此时车也要拆分到多个维度、跑车,商务车等。

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BusinessCar.java, v 0.1 2015-10-18 下午2:00 admin Exp $$
 */
public class BusinessCar {
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id SportsCar.java, v 0.1 2015-10-18 下午2:01 admin Exp $$
 */
public class SportsCar {
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id AudiBusiness.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public class AudiBusiness extends BusinessCar {
    public AudiBusiness() {
        System.out.println("Product AudiBusiness!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BenzBusiness.java, v 0.1 2015-10-18 下午1:04 admin Exp $$
 */
public class BenzBusiness extends BusinessCar {
    public BenzBusiness() {
        super();
        System.out.println("Product BenzBusiness!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BmwBusiness.java, v 0.1 2015-10-18 下午1:03 admin Exp $$
 */
public class BmwBusiness extends BusinessCar {
    public BmwBusiness() {
        super();
        System.out.println("Product BmwBusiness!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id AudiBusiness.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public class AudiSports extends SportsCar {
    public AudiSports() {
        System.out.println("Product AudiSports!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BenzSports.java, v 0.1 2015-10-18 下午1:04 admin Exp $$
 */
public class BenzSports extends SportsCar {
    public BenzSports() {
        super();
        System.out.println("Product BenzSports!");
    }
}

/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BmwSports.java, v 0.1 2015-10-18 下午1:03 admin Exp $$
 */
public class BmwSports extends SportsCar {
    public BmwSports() {
        super();
        System.out.println("Product BmwSports!");
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id CarFactory.java, v 0.1 2015-10-18 下午1:06 admin Exp $$
 */
public interface CarFactory {

    public SportsCar createSportsCar();

    public BusinessCar createBusinessCar();
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id AudiFactory.java, v 0.1 2015-10-18 下午2:15 admin Exp $$
 */
public class AudiFactory implements CarFactory {
    @Override
    public SportsCar createSportsCar() {
        return new AudiSports();
    }

    @Override
    public BusinessCar createBusinessCar() {
        return new AudiBusiness();
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BenzFactory.java, v 0.1 2015-10-18 下午2:17 admin Exp $$
 */
public class BenzFactory implements CarFactory {
    @Override
    public SportsCar createSportsCar() {
        return new BenzSports();
    }

    @Override
    public BusinessCar createBusinessCar() {
        return new BenzBusiness();
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id BmwFactory.java, v 0.1 2015-10-18 下午2:18 admin Exp $$
 */
public class BmwFactory implements CarFactory {
    @Override
    public SportsCar createSportsCar() {
        return new BmwSports();
    }

    @Override
    public BusinessCar createBusinessCar() {
        return new BmwBusiness();
    }
}


/**
 * Open Free.
 * Code for Open Community, free to use!
 */
package designpattern.abstractfactory;

/**
 * @author admin
 * @version $Id Customer.java, v 0.1 2015-10-18 下午1:16 admin Exp $$
 */
public class Customer {
    public static void main(String[] args) {
        /**生产宝马*/
        CarFactory carFactory = new BmwFactory();
        //跑车
        SportsCar sportsCar = carFactory.createSportsCar();
        //商务车
        BusinessCar businessCar = carFactory.createBusinessCar();

        /**生产奥迪*/
        carFactory = new AudiFactory();
        //跑车
        sportsCar = carFactory.createSportsCar();
        //商务车
        businessCar = carFactory.createBusinessCar();

        /**生产一个奔驰*/
        carFactory = new BmwFactory();
        //跑车
        sportsCar = carFactory.createSportsCar();
        //商务车
        businessCar = carFactory.createBusinessCar();

    }
}

1.一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。

2.这个系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。

3.同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。

4.系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。

分离接口和实现

客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。

 

posted on 2015-10-18 15:51  NewPanderKing  阅读(417)  评论(0编辑  收藏  举报

导航