《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"; } }
设计原理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()); } }