作者:Flyingis

    工厂模式用于创建实例对象,我们只需告诉工厂需要的对象有什么特点,就能得到所需的结果,而不用去关心怎么创建对象,工厂类似于黑盒,黑盒里面关于对象生产的细节不是关注的重点。

    工厂模式分为:简单工厂模式、工厂模式、抽象工厂模式。

    例子:Thinkpad笔记本生产线。

    简单工厂模式

public class SimpleThinkpadTFactory {
  
public ThinkpadT produceThinkpadT(String type) {
    ThinkpadT thinkpadT 
= null;
    
// 根据不同的类型创建不同的Thinkpad
    if (type.equals("t60")) {
      thinkpadT 
= new ThinkpadT60();
    }
 else if (type.equals("t60p")) {
      thinkpadT 
= new ThinkpadT60p();
    }

  
return thinkpadT;
  }

}


public class ThinkpadTStore {
  SimpleThinkpadTFactory factory;
  
public ThinkpadTStore(SimpleThinkpadFactory factory) {
    
this.factory = factory;
  }


  
public ThinkpadT buyThinkpadT(String type) {
    ThinkpadT thinkpadT;
    
// 不再根据不同条件,使用new去创建对象
    thinkpadT = factory.produceThinkpadT(type);
    
return thinkpadT;
  }

}


    从上例可以看出,SimpleThinkpadTFactory只需知道用户需要什么型号的Thinkpad T系列的电脑,就能返回该型号Thinkpad的对象,避免了在ThinkpadTStore中书写冗长的代码,降低了代码的耦合度。但是在SimpleThinkpadTFactory中,一旦机器的型号分的特别细、特别多,如T42/T43/T60/T42p/T43p/T60p等等,就需要维护大量的"if else",这显然不是我们想看到的,这里我们引入工厂模式。

    工厂模式

public abstract class ThinkpadTStore {
  
public ThinkpadT buyThinkpadT(String type) {
    ThinkpadT thinkpadT;
    thinkpadT 
= produceThinkpadT(type);
    
return thinkpadT;
  }

  
// 单独抽取出工厂方法,abstract类型,需要在子类中实现
  abstract produceThinkpadT(String type);
}


public class ThinkpadT43Store extends ThinkpadTStore {
  ThinkpadT produceThinkpadT(String type) 
{
    
if (type.equals("T43")) {
      
return new ThinpadT43();
    }
 else if (type.equals("T43p")) {
      
return new ThinkpadT43p();
    }
 else return null;
  }

}


public class ThinkpadT60Store extends ThinkpadTStore {
  ThinkpadT produceThinkpadT(String type) 
{
    
if (type.equals("T60")) {
      
return new ThinpadT60();
    }
 else if (type.equals("T60p")) {
      
return new ThinkpadT60p();
    }
 else return null;
  }

}


    具体执行代码:

public class ThinpadTest {
  
public static void main(String[] args) {
    ThinkpadTStore thinkpadT43Store 
= new ThinkpadT43Store();
    ThinkpadTStore thinkpadT60Store 
= new ThinkpadT60Store();

    ThinkpadT thinkpadT 
= null;
    
// 购买Thinkpad T43笔记本
    thinkpadT = thinkpadT43Store.buyThinkpadT("T43");
    
// 购买Thinkpad T60p笔记本
    thinkpadT = thinkpadT60Store.buyThinkpadT("T60p");
  }

}


    这样就将不同型号T系列笔记本的生产进行了更细的划分,降低了简单工厂中工厂类的耦合程度,抽取出来的各种Store只用关心一种型号笔记本的生产,如T43或T60。

    工厂模式的抽象结构图可以表示如下:


    (上图摘自Head First Patterns)

    抽象工厂模式

    什么时候需要使用抽象工厂模式呢?抽象工厂模式用户生产线更复杂的情况下,例如现在除了T系列的Thinkpad笔记本,我们还需要生产R系列和X系列的产品,这时就需要更多的工厂来负责不同系列Thinkpad的生产。


    (上图摘自吕震宇的博客)   

    有两篇文章对于抽象工厂模式阐述的非常好:

    白话设计模式--Abstract Factory

    C#设计模式(6)--Abstract Factory Pattern