《Head First》介绍了工厂模式的3个内容:
一、简单工厂
简单工厂并非一个模式,反而像是一个编程习惯,其本质是抽出了对象复杂多变的实例化过程到另外一个单独的类,以保证其他代码的不变。
通常是实例化的对象是拥有多类型的情况:
案例:可以用实例化水果派的例子
public class PatternDemo {
public static void main(String[] args) {
SimplePieFactory factory = new SimplePieFactory();
Pie pie = factory.createPie(SimplePieFactory.TYPE_APPLE);
System.out.println("Pie: " + pie.getName());
pie = factory.createPie(SimplePieFactory.TYPE_BANANA);
System.out.println("Pie: " + pie.getName());
pie = factory.createPie(SimplePieFactory.TYPE_PINEAPPLE);
System.out.println("Pie: " + pie.getName());
}
}
public class SimplePieFactory {
public static final int TYPE_APPLE = 0;
public static final int TYPE_BANANA = 1;
public static final int TYPE_PINEAPPLE = 2;
public SimplePieFactory() {
}
public Pie createPie(int type) {
Pie pie = null;
if (type == TYPE_APPLE) {
pie = new ApplePie();
} else if (type == TYPE_BANANA) {
pie = new BananaPie();
} else if (type == TYPE_PINEAPPLE) {
pie = new PineapplePie();
}
return pie;
}
}
public abstract class Pie {
public Pie() {}
public abstract String getName();
}
public class ApplePie extends Pie {
@Override
public String getName() {
return "Apple Pie";
}
}
另外两个类似。
二、工厂方法模式
工厂方法模式:定义了一个创建对象的接口, 但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类
其本质是虚基类中存在统一的操作或者处理对象实例的方法,但是实例化生成对象实例的方法是抽象方法,需要子类通过继承后实现
为的是满足不同的需求下的实例化对象不同的情况
案例:同样是水果派,但是A店改进工艺后有了AStyle的Pie,同样的B店也有了BStyle的,但是制作过程是一样的,只是馅料会有A和B自己的不同
因此只要让AB两家各自实现抽象基类里的createPie方法就可以有他们各自的特色,然后再用抽象基类里面统一的制作过程
代码:
public class PatternDemo {
public static void main(String[] args) {
AStore aStore = new AStore();
aStore.cooking();
BStore bStore = new BStore();
bStore.cooking();
}
}
public abstract class Store {
public void cooking() {
System.out.println("cooking......");
Pie pie = null;
pie = createPie();
System.out.println("Pie: " + pie.getName());
System.out.println("cooked......");
}
protected abstract Pie createPie();
}
public class AStore extends Store {
@Override
protected Pie createPie() {
return new AStylePie();
}
}
public class AStylePie extends Pie {
@Override
public String getName() {
return "A StyleP ie";
}
}
B的代码类似
设计原理6:要依赖抽象,不要依赖具体类(其作用是为了实现“依赖倒置原则”)
如何理解呢?
1、如果不用工厂方法模式,那么我们就用不到Pie的抽象类,然后我们会分别去根据要求用很多if-else去实例化各种各样的Pie,这个时候可以理解为Store是依赖于各种各样具体的Pie的。
2、有了抽象Pie类后,Store会依赖于抽象的Pie,而这个时候所有的具体Pie会依赖于抽象的Pie,这样就可以理解为倒置了
如何遵循“依赖倒置原则”,只是尽了遵循,因为绝对是不可能的
1、变量不可以持有具体类的引用
2、不要让类派生自具体类
3、不要覆盖基类(主要是抽象的基类)中已实现的方法
三、抽象工厂模式
抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类
可以提现这个的案例就是水果派的原料上,
A的代码:
public interface PieIngredientFactory {
public Ingredient createIngredient();
}
public class APieIngredientFactory implements PieIngredientFactory {
@Override
public Ingredient createIngredient() {
return new AIngredient();
}
}
public class AStylePie extends Pie {
private PieIngredientFactory factory;
public AStylePie(PieIngredientFactory factory) {
this.factory = factory;
prepare();
}
@Override
public String getName() {
return "A StyleP Pie with " + getIngredient().getIngredientName();
}
@Override
public void prepare() {
setIngredient(factory.createIngredient());
}
}
关键在于prepare()方法中,无论是什么工厂,都是可以轻易重用的, 而Pie根本不用管是什么工厂