在传统的继承链中,修改一个子类,或增加、减少一个子类;对于依赖继承链中的成员的外部类就要进行很多修改工作。这是因为这个外部类的依赖中的逻辑实现并不知道将来会添加什么类(比方说在判断中不知道增加什么条件),这样就给扩展和调试增加了许多困难,也直接违反了“开闭原则”。

简单工厂模式

简单工厂模式给出的方案是:将基类部分的对象创建后封装到一个具体的类中,这样在更改继承链时,只要修改这个具体的类即可,而外部类的依赖的实现中涉及到的该类的创建就不需要修改了。

基本

简单工厂模式属于创建模式,是工厂模式的一种,也是最简单、常用的一种。
行为:

  • 定义一个创建对象的类,有这个类来封装实例化对象的行为。

使用场景:

  • 当需要大量创建某种、某类或某批对象时。

内涵:

  • Factory体现了生产、创建、赋予功能,而且侧重于批量生产。本质上是修改了常规的依赖关系使之与继承链解耦。
  1. public class SimpleFactory{
  2. public Foo createFoo(String []args){
  3. Foo foo = null;
  4. // Of course you can do other implementations
  5. if(args.length > 0) foo = new Foo();
  6. else {foo = new Foo(123);}
  7. return foo;
  8. }
  9. }
  10. // This class is what a client really needs
  11. public class Bar{
  12. SimpleFactory sf;
  13. Foo foo = null;
  14. // Make the factory more flexible
  15. public Bar(SimpleFactory sf){
  16. this.setFactory(sf);
  17. }
  18. public void setFactory(SimpleFactory sf){
  19. // Do some manoeuvres
  20. // ...
  21. // Then set factory
  22. this.sf = sf;
  23. // Let our factory make its work done
  24. foo = sf.createFoo();
  25. // ...
  26. }
  27. }
  28. // In another package maybe...
  29. public class SomeClient{
  30. public static void main(String[] args){
  31. Bar bar = new Bar(new SimpleFactory);
  32. }
  33. }

注意到Line13将SimpleFactory硬编码到了Bar之中,实际上SimpleFactory中的createFoo方法可以是静态的,这样sf这个变量就不用聚合在Bar中了。

工厂方法模式

在先前的简单工厂模式中,一个工厂虽然可以生产多种Foo的实例,但对于Foox则无能为例。虽然我们仍然可以通过增加相应的简单工厂来完成任务,但这无疑是增加冗余的。

工厂方法模式则以更简练的方式解决问题。
工厂方法模式定义了一个创建对象的抽象方法,由子类决定决定要实例化的类,从而将实例化推迟到子类中进行。

注意是实现抽象(abstract)方法的子类充当的才是创建对象的角色,至于原本的抽象方法,可以是任何可能用到创建对象的某个类。

抽象工厂模式

类似于工厂方法模式,不同之处在于抽象工厂是通过定义interface来创建相关的依赖关系。
“抽象”的内涵在于implicit,也就是保留了扩展性。抽象工厂实际是把简单工厂那种指名道姓的工厂抽象为某种蓝图,而让其实现类去做原来简单工厂的工作,而又因为方法是在interface中的,这些简单工厂更利于维护和扩展。