设计模式---工厂模式

看了些教程和相应的代码,网上又看了些博客,主要是想了解这种思想,下面从代码的演进来说明三种工厂模式.

工厂模式在《Java与模式》中分为三类:
1)简单工厂模式(Simple Factory):不利于产生系列产品;

2)工厂方法模式(Factory Method):又称为多形性工厂;

3)抽象工厂模式(Abstract Factory):又称为工具箱,产生产品族,但不利于产生新的产品;
这三种模式从上到下逐步抽象,并且更具一般性。
GOF在《设计模式》一书中将工厂模式分为两类:工厂方法模式(Factory Method)与抽象工厂模式(Abstract Factory)。将简单工厂模式(Simple Factory)看为工厂方法模式的一种特例,两者归为一类。

案例:pizza店有CheesePizza和GreekPizza,有一个PizzaStore,通过OrderPizza来销售这两种Pizza.

一.简单工厂模式

简单来说就是定义实例,封装创建对象的代码,把不动的代码和会动的代码分开
//简单工厂代码,封装了创建OrderPizza这个类里面的CreatePizza
//这样做的目的就是把会改动的代码单独封装,比如可能增加新的Pizza种类,那么直接在这里面改变即可.
public class SimplePizzaFactory {

    public Pizza CreatePizza(String ordertype) {
        Pizza pizza = null;

        if (ordertype.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (ordertype.equals("greek")) {
            pizza = new GreekPizza();
        } else if (ordertype.equals("pepper")) {
            pizza = new PepperPizza();
        }
        return pizza;

    }

}

被封装的OrderPizza

//里面主要封装Pizza的制作等方法(本Demo认为Pizza制作方法一样),通过工厂类来实现创建不同的Pizza
public class OrderPizza {
    SimplePizzaFactory mSimplePizzaFactory;

    public OrderPizza(SimplePizzaFactory mSimplePizzaFactory) {

        setFactory(mSimplePizzaFactory);
    }

    public void setFactory(SimplePizzaFactory mSimplePizzaFactory) {
        Pizza pizza = null;
        String ordertype;

        this.mSimplePizzaFactory = mSimplePizzaFactory;

        do {
            ordertype = gettype();
            pizza = mSimplePizzaFactory.CreatePizza(ordertype);
            if (pizza != null) {
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }

        } while (true);

    }

    private String gettype() {
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(
                    System.in));
            System.out.println("input pizza type:");
            String str = strin.readLine();

            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

}

下面是PizzaStore直接进行点餐

public class PizzaStroe {
    public static void main(String[] args) {
        SimplePizzaFactory mSimplePizzaFactory;
        OrderPizza mOrderPizza;
        mOrderPizza=new OrderPizza(new SimplePizzaFactory());
    }
}
目前扩大经营,需要在London开设分店,那么原程序就很难维护,几乎需要重写,所以引进工厂方法模式

二.工厂方法模式

定义创建对象的抽象方法,由子类决定要实例化的类

把OrderPizza设为抽象类,CreatePizza设为抽象方法,那么每一个分店继承OrderPizza都会创建属于自己的CreatePizza方法

//定义为抽象类
public abstract class OrderPizza {

    public OrderPizza() {
        Pizza pizza = null;
        String ordertype;

        do {
            ordertype = gettype();
            pizza = createPizza(ordertype);

            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        } while (true);
    }
//这里需要子类实现的抽象方法
    abstract Pizza createPizza(String ordertype);

    private String gettype() {
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(
                    System.in));
            System.out.println("input pizza type:");
            String str = strin.readLine();

            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

}

LondonPizza的实现

public class LDOrderPizza extends OrderPizza {

    @Override
    Pizza createPizza(String ordertype) {
        Pizza pizza = null;

        if (ordertype.equals("cheese")) {
            pizza = new LDCheesePizza();
        } else if (ordertype.equals("pepper")) {
            pizza = new LDPepperPizza();
        }
        return pizza;

    }

}

PizzaStore

public class PizzaStroe {
    public static void main(String[] args) {

        OrderPizza mOrderPizza;
        mOrderPizza=new NYOrderPizza();
    }
}

三.抽象工厂模式

定义一个接口,用于创建相关或有依赖关系的对象族,无需明确具体类.

创建抽象工厂,把CreatePizza抽象出来

public interface AbsFactory {
    public Pizza CreatePizza(String ordertype) ;
}

OrderPizza以当前抽象工厂为对象,创建Pizza

public class OrderPizza {
    AbsFactory mFactory;

    public OrderPizza(AbsFactory mFactory) {

        setFactory(mFactory);
    }

    public void setFactory(AbsFactory mFactory) {
        Pizza pizza = null;
        String ordertype;

        this.mFactory = mFactory;

        do {
            ordertype = gettype();
            pizza = mFactory.CreatePizza(ordertype);
            if (pizza != null) {
                pizza.prepare();
                pizza.bake();
                pizza.cut();
                pizza.box();
            }

        } while (true);

    }

    private String gettype() {
        try {
            BufferedReader strin = new BufferedReader(new InputStreamReader(
                    System.in));
            System.out.println("input pizza type:");
            String str = strin.readLine();

            return str;
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

}

具体到每一种Pizza,需要其实现抽象工厂接口

public class LDFactory implements AbsFactory {

    @Override
    public Pizza CreatePizza(String ordertype) {
        Pizza pizza = null;

        if (ordertype.equals("cheese")) {
            pizza = new LDCheesePizza();
        } else if (ordertype.equals("pepper")) {
            pizza = new LDPepperPizza();
        }
        return pizza;

    }

}

PizzaStore直接创建即可

public class PizzaStroe {
    public static void main(String[] args) {

        OrderPizza mOrderPizza;
        mOrderPizza=new OrderPizza(new LDFactory());
    }
}

四.总结

(1)简单工厂模式是由一个具体的类去创建其他类的实例,父类是相同的,父类是具体的。 
(2)工厂方法模式是有一个抽象的父类定义公共接口,子类负责生成具体的对象,这样做的目的是将类的实例化操作延迟到子类中完成。 
(3)抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。它针对的是有多个产品的等级结构。而工厂方法模式针对的是一个产品的等级结构。

五.补充

依赖抽象原则
1.变量不要持有具体类的引用,比如CheesePizza = new CheesePizza (),这样就不太好.
2.不要让类继承自具体类,要继承抽象类或者接口,这个主要是便于维护.
3.不要覆盖基类已实现的方法,基类实现的应该是程序的通性,覆盖的话会使其失去其意义

当然具体情况具体对待

你可能感兴趣的:(设计模式,工厂模式)