关于简单工厂、工厂方法和抽象工厂

这一章节的内容暂时看了两遍,还没有在具体实际的代码中使用过,但是鉴于初期对它们的了解,作为后期的温故基础,故先做个简单基础的归纳总结。
关于这三个名字,其中简单工厂并不是工厂模式。工厂方法和抽象工厂属于工厂模式。


简单工厂

总的来说,简单工厂仅仅是一种编程习惯—–也就是把经常变动的一部分代码提取出来封装为一个独立的模块,如果后期要对这相关信息进行修改,只需要来这个独立的模块修改即可。也就是说,将代码中实例化具体类的代码从应用中抽离,然后封装起来。例如:
“如何实现对扩展开放,对修改关闭呢?”

public class PizzaStore{
    Pizza orderPizza(String type){
        Pizza pizza;

        //这里经常变动的地方,比如添加一种类型的pizza的时候。将经常变动的这些代码提取出来进行封装。
        if(type = "cheese"){
            pizza = new CheesePizza();
        }else if(type = "greek"){
            pizza = new GreekPizza();
        }else if(type = "pepperoni"){
            pizza = new PepperoniPizza();
        }

        //这里的“准备、烘烤、切片、包装” 操作,不管什么类型的pizza,都要在最终进行这些程序,所以不提取。
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
}

上面的代码,经过简单工厂的调整,代码如下:

public class PizzaStore{
    SimplePizzaFactory factory;
    public PizzaStore(SimplePizzaFactory factory){
        this.factory = factory;
    }

    Pizza orderPizza(String type){
        Pizza pizza;
        //这里调用封装起来的方法
        pizza = factory.createPizza(type);

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

//封装创建不同类型的pizza代码
public class SimplePizzaFactory{
    public Pizza createPizza(String pizza){
        Pizza pizza = null;

        if(type = "cheese"){
            pizza = new CheesePizza();
        }else if(type = "greek"){
            pizza = new GreekPizza();
        }else if(type = "pepperoni"){
            pizza = new PepperoniPizza();
        }

        return pizza
    }
}

简单的流程图示这样的:
PizzaStore的orderPizza( )——SimplePizzaFactory的createPizza( )—–orderPizza中的共有步骤。



工厂方法—加盟pizza店

in a word:工厂方法用来处理对象的具体操作,并将这样的行为封装在子类中。在父类中提供一个抽象方法,以供给子类重写它。每个不同的子工厂针对同一操作,有具体的自己的实现。所有的工厂模式都是用来封装对象的创建的。工厂方法模式通过让子类决定该创建对象是什么,来达到对象创建的过程封装的目的
同样还是举书上Pizza的例子:
步骤如下:
(1)PizzaStore是总店,有了加盟店之后,这些加盟店作为PizzaStore的子店,允许子类做决定,也就是说:针对父类中提供的createPizza方法,进行自定义创建什么样的Pizza。
(2)将变动的那部分createPizza()方法重新写会PizzaStore中,定义为抽象方法,宾语子类重写这个方法
*orderPizza()负责处理订单
(3)想要让createPizza()方法应对不同种类的Pizza的变化来创建正确的Pizza的解决办法:让PizzaStore的具体子类,负责定义自己的createPizza方法。
(4)顾客去哪个店消费,就使用哪个区域的createPizza方法。
(5)下面有一点生成Pizza的伪代码流程。

public class PizzaStore{

    Pizza orderPizza(String type){
        Pizza pizza;

        pizza = createPizza(type);

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

    protected abstract Pizza createPizza(String type);
}

public class NYPizzaStore{
    public Pizza createPizza(String type){
        //此处为type类型pizza的创建过程自定义
    }
}

//需要创建纽约芝士风味的pizza,伪代码
PizzaStore nyPizzaStore = new NYPizzaStore();
nyPizzaStore.orderPizza("cheese");
Pizza pizza = createPizza("cheese");
//最后进过orderPizza的公用几步,pizza就完成了

工厂方法模式:将实现推迟到子类,父类不需要知道子类是怎么实现的。
简单工厂:吧全部的事情,在一个地方处理完。
而工厂发方法模式,是创建一个框架,让多个子类覆盖父类的方法,即子类决定如何去实现。


由“依赖倒置原则”引出“抽象工厂模式”

依赖导致原则—要依赖接口,不要依赖具体的类

(1)给原料家族创建原料工厂和子工厂,其中定义每个原料的create方法,而每个子Factory中每个原料都有自己的create方法;
(2)将Pizza定义为一个接口;
(3)Pizza的子类,使用某个区域的工厂 如NYPizzaFactory作为构造函数的参数,之后即可以通过这个变量来调用其中的create方法。
(4)Pizza的子类是不同口味的Pizza,参数是某个从工厂,这样就可以创建某个区域的某个口味的Pizza。因为不管是什么区域的Pizza 同一种口味的pizza原料是一样的,只是每个工厂对每个原料的创建方式不同。所以产生的相同口味的不同区域的Pizza各不一样。
下面是代码的实例:

Pizza(不同口味的Pizza,包含create抽象方法,参数为某个工厂)------子类:CheesePizza,ChicagoPizza
PizzaFactory(各种原料的抽象create方法)-----子类:NYPizzaFactory,ChicagoPizzaFactory
***------------------------------------------------------------------------//code
public interface PizzaFactory{
    public Dough createDough();
    public Sauce createSauce();
    public Cheese createCheese();
    public Veggies[] createVeggies();
    public Pepperoni createPepperoni();
    public Clams createClam();
}

public class NYPizzaFactory{
    public Cheese createCheese(){
        return new ReggianoCheese();
    }
    ......
}

public acstract class Pizza{
    String name;
    Dough dough;
    Sauce sauce;
    Veggies veggies;
    Cheese cheese;

    abstract void prepare();

    void bake(){...}
    void cut(){...}
    void box(){...}

    void setName(String name){this.name = name}

    String getName(){return name}
    ...
}

public CheesePizza extends Pizza{
    PizzaFactory factory;
    public CheesePizza(PizzaFactory factory){
        this.factory = factory;
    }

    void prepare(){
        //prepare方法一步步的创建芝士披萨,每当需要原料的时候,就问工厂要。
        //比如这里的芝士披萨总共有三个原料制成。在具体制作的时候,根据factory的不同,有不同的地域风味
        dough = factory.createDough();
        sauce = factory.createSauce();
        cheese = factory.createChess();
    }
}

//----------------下面是具体的创建Pizza  伪代码
PizzaFactory nyFactory = new NYPizzaFactory();
Pizza Pizza =  new CheesePizza(nyFactory);
void prepare(){
    dough = nyFactory.createDough();
    sauce = nyFactory.createSauce();
    cheese = nyFactory.createChess();
}
最后调用order的公用步骤即可。

基础总结先这样,后期会修改。

猜你喜欢

转载自blog.csdn.net/amethyst128/article/details/78471586