看了些教程和相应的代码,网上又看了些博客,主要是想了解这种思想,下面从代码的演进来说明三种工厂模式.
工厂模式在《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.不要覆盖基类已实现的方法,基类实现的应该是程序的通性,覆盖的话会使其失去其意义
当然具体情况具体对待