【设计模式】4. 工厂方法模式、抽象工厂模式

简单工厂


简单工厂不是一个设计模式,而是一种编程习惯。

使用场景:

当客户端需要实例化一个类,但究竟实例化哪个类,要在运行时由一些条件来决定。

找出变化的方面(实例化哪个类),把他们从不变的部分分离出来,交由“简单工厂”完成。

 

public class PizzaStore{
    SimplePizzaFactory factory;
    Public PizzaStore(SimplePizzaFactory factory){
        this.factory = factory;    
    }
    public Pizza orderPizza(String type){
        Pizza pizza = factory.createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
}

//简单工厂
public class SimplePizzaFactory{
    public Pizza createPizza(String type){
        Pizza pizza = null;
        if(type.equals("cheese"))
            pizza = new CheesePizza();
        else if(type.equals("veggie"))
            pizza = new VeggiePizza();
        ...... 
        return pizza;   
    }
}

工厂方法模式

定义:

Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

工厂方法模式定义了一个创建对象的接口,但由子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类。

——所谓“决定”,是指在编写Creator时并不知道实际要创建的Product是哪一个,选择了使用哪个子类,就决定了实际创建的Product是什么。


类图:


//Product
public abstract class Pizza {

}
//Concrete Product
public class NYStyleCheesePizza extends Pizza {

}

//Creator
public abstract class PizzaStore{
    public Pizza orderPizza(String type){

        Pizza pizza = createPizza(type);

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza;
    }
 
    //Factory Method    
    protected abstract Pizza createPizza(String type);

    /*
     工厂方法的参数,可为String、Enum、Class;例如:   
    */
    public  T createHuman(Class c);
 }

//ConcreteCreator 
public class NYPizzaStore extends PizzaStore{
    Pizza createPizza(String type){
        if(type.equals("cheese"))
            return new NYStyleCheesePizza();
        else if...
        ...
    }
}

注:这里每个Product都对应了一个Factory(多工厂);当然也可以所有Product实现类都对应同一个Factory(单工厂),只是这样这个Factory会非常庞大。

角色:

1)抽象产品类

        负责定义产品共性

2)具体产品类

3)抽象工厂类

4)具体工厂类

 

优点:

  • 封装性:客户端不用知道创建对象的艰辛过程
  • 扩展性:若要增加产品类,只需修改具体的工厂类,或扩展一个工厂类;——若工厂方法参数为Class,则只需增加具体产品类即可,工厂类无需修改!
  • 屏蔽产品类:产品类的实现如何变化,客户端都无需关心,只需要关心产品的接口
  • 是典型的解耦框架,符合迪米特法则、依赖倒置原则、里氏替换原则

缺点:

 

使用场景:

         所有需要生成对象的地方都可以使用。当需要灵活的可扩展的框架时可考虑使用。


抽象工厂模式

 定义:

Provide an interface for creating families of related or dependent objects without specifying their concrete classes.

为创建一组相关的或互相依赖的对象(即:产品族)提供一个接口,而且无需指定这组对象的具体类。


类图:

 


public interface VehicheFactory{
    public AbstractCar createCar();//通常以“工厂方法”来实现,将实例化延迟到子类。
    public AbstractBus createBus();
    public AbstractTruck createTruck();
}

public class BenzFactory implements VehicheFactory{
    public AbstractCar createCar(){
        return new BenzCar();
    }
    ...
}

public class BmwFactory implements VehicheFactory{
    public AbstractCar createCar(){
        return new BmwCar();
    }
    ...
}


角色:

1)抽象产品类

2)具体产品类

3)抽象工厂类

        有几个产品族,则在抽象工厂类中就应该有几个创建方法

4)具体工厂类


优点:

  • 封装性    
  • 产品族内的约束是非公开状态的      


缺点:

  •  产品族的扩展非常困难;例如增加一个Motor产品族,需要修改AbstractCreator、ConcreteCreator


使用场景:

        抽象工厂模式是工厂方法模式的升级版本,当有多个业务品种、业务分类时,并且产品族内都有相同的约束时,则可使用该模式。

 

比较

工厂方法使用继承来创建对象;抽象工厂则通过对象的组合

抽象工厂可以将一群相关的产品集合起来。

你可能感兴趣的:(【Design,Patterns】,设计模式)