工厂模式(Factory Pattern)

工厂模式(Factory Pattern)
工厂模式主要为创建对象提供了接口,工厂模式按照《java与模式》中的提法分为3类:
1、简单工厂模式(Simple Factory)
2、工厂方法模式(Factory Method)
3、抽象工厂模式(Abstract Factory)
这三种模式从上到下逐步抽象,并且更具一般性
还有一种分类方法就是将简单工厂模式看为工厂方法模式的一种特例,两个归为一类。
需要使用工厂模式的情况:
1、在编码时不能预见需要创建哪种类的实例;
2、系统不应该依赖于产品类实例如何被创建、组合和表达的细节。
下面开始对三种类型的工厂模式进行详细说明。
 
一、简单工厂模式
角色组成:
工厂类角色:模式核心,含有一定的商业业务逻辑和判断逻辑,往往由一个具体类实现;
抽象产品角色:一般是具体产品继承的父类或者实现的接口,往往是接口或者抽象类;
具体产品角色:工厂类所创建的对象就是这类角色的实例。
例子如下(FactoryPattern.java JDK1.5编译测试通过):
/**
 *工厂模式测试
 *@author tsimgsong
 *@version 1.0,09/04/2007
 */
public class FactoryPattern{
   public static void main(String[] args){
          Fruit f;
          try{
        f = FruitShop.buy("apples");
          f.eatMethod();
          }catch(UnAvailableProduct e){
             System.out.println("出错原因:"+e.getMessage());
          }
   }
 
}
/**
 *抽象产品角色
 */
interface Fruit{
    void eatMethod();
    void growFrom();
    }
    /**
     *具体产品角色之一
     */
    class Apple implements Fruit{
           public Apple(){
                System.out.println("You create an Apple");
          }
          public void eatMethod(){
               System.out.println("You are eating an Apple");
          }
 
        public void growFrom(){
              System.out.println("Apple tree");
        }
 
    }
       /**
        *具体产品角色之二
        */
       class Orange implements Fruit
       {  
              public Orange(){
                     System.out.println("You create an Orange");
              }
              public void eatMethod(){
                     System.out.println("You are eating an Orange");
              }
              public void growFrom(){
                     System.out.println("Orange Tree");
              }
       }
       /**
        *工厂模式核心:工厂类
        */
 
       class FruitShop
       {  
              /**
               *根据参数生成相应的产品
               *@param type 产品类型
               */
              public static Fruit buy(String type) throws UnAvailableProduct{
                     if(type.equalsIgnoreCase("apple")){
                            return new Apple();
                     }else if(type.equalsIgnoreCase("orange")){
                            return new Orange();
                     }else{
                            throw new UnAvailableProduct("尚未上市");
                     }
 
              }
       }
 
       class UnAvailableProduct extends Exception
       {
              public UnAvailableProduct(String msg){
                     super(msg);
              }
       }
 
分析:当增加一个具体产品类的时候,只要复核抽象产品定制的规则,也即实现或者继承了抽象产品类,只要在工厂类注册就可以生成使用。从具体产品的角度来看,是满足开闭原则的,对扩展开放同时对修改关闭,但从工厂的角度而言又不满足开闭开闭原则,每增加一类具体产品,都必须要修改工厂类,增加相应的商业业务逻辑和判断逻辑。同时在实际应用中,很可能产品是一个多层次的树状结构,而简单工厂模式只有一个工厂类对应这些产品,这种模式对于业务简单的时候可以满足应用,而对于复杂的业务环境可能能力不够。
 
二、工厂方法模式
角色组成:
抽象工厂角色:工厂方法模式的核心,具体工厂角色必须实现的或者继承的父类,通过抽象类或者接口来表现,在前面的简单工厂模式的工厂的基础上抽象出工厂的工厂
具体工厂角色:含有与具体业务逻辑有关的代码,由应用调用以创建具体的产品。由具体类实现
抽象产品角色:同上
具体产品角色:同上
在前面一个例子的基础上,如果商店越来越多,有的专卖水果,有的专卖蔬菜,有的专卖肉类,需要一个管理机构公司来管理,通过这个机构来生成具体的商店,由公司来指定具体的商店,在商店可以买到相应商品。
在上例的基础上修改如下:(FactoryPattern.java JDK1.5测试通过)
/**
 *工厂模式测试
 *@author tsimgsong
 *@version 1.0,09/04/2007
 */
public class FactoryPattern{
   public static void main(String[] args){
          Food f;
          Corp corp;
          try{
                 corp = new FreshShop();
        f = corp.buy("pig");
          f.eatMethod();
          }catch(UnAvailableProduct e){
             System.out.println("出错原因:"+e.getMessage());
          }
   }
 
}
    /**
     *工厂模式核心:抽象工厂角色
     */
    interface Corp {
              Food buy(String type) throws UnAvailableProduct;
       }
    /**
     *具体工厂角色:水果商店工厂类
     *
     */
       class FruitShop implements Corp
       {  
              /**
               *根据参数生成相应的产品
               *@param type 产品类型
               */
              public Food buy(String type) throws UnAvailableProduct{
                     if(type.equalsIgnoreCase("apple")){
                            return new Apple();
                     }else if(type.equalsIgnoreCase("orange")){
                            return new Orange();
                     }else{
                            throw new UnAvailableProduct("尚未上市");
                     }
              }
       }
 
       /**
        *具体工厂角色:肉类商店工厂类
        */
       class FreshShop implements Corp{
              public Food buy(String type) throws UnAvailableProduct{
                     if(type.equalsIgnoreCase("pig")){
                            return new Pig();
                     }else if(type.equalsIgnoreCase("goat")){
                            return new Goat();
                     }else{
                            throw new UnAvailableProduct("尚未上市");
                     }
              }
 
       }
 
    /**
     *抽象产品角色
     */
    interface Food{
        void eatMethod();
        void growFrom();
    }
       /**
        *具体产品角色 水果
        */
 
    class Apple implements Food{
           public Apple(){
                System.out.println("You create an Apple");
          }
          public void eatMethod(){
               System.out.println("You are eating an Apple");
          }
 
        public void growFrom(){
              System.out.println("Apple tree");
        }
 
    }
       /**
        *具体产品角色之一 水果
        */
       class Orange implements Food
       {  
              public Orange(){
                     System.out.println("You create an Orange");
              }
              public void eatMethod(){
                     System.out.println("You are eating an Orange");
              }
              public void growFrom(){
                     System.out.println("Orange Tree");
              }
       }
       /**
        *具体产品角色
        */
 
       class Pig implements Food
       {
              public Pig(){
                     System.out.println("You create an Pig");
              }
              public void eatMethod(){
                     System.out.println("You are eating an Pig Fresh");
              }
              public void growFrom(){
                     System.out.println("Pig grow From");
              }
       }
       /**
        *具体产品角色
        */
 
       class Goat implements Food
       {
              public Goat(){
                     System.out.println("You create an Goat");
              }
              public void eatMethod(){
                     System.out.println("You are eating an Goat Fresh");
              }
              public void growFrom(){
                     System.out.println("Goat grow From");
              }
       }
 
 
       class UnAvailableProduct extends Exception
       {
              public UnAvailableProduct(String msg){
                     super(msg);
              }
       }
工厂方法使用一个抽象工厂角色作为核心来代替在简单工厂模式中使用具体工厂类作为核心,当有新的产品加入时,只要按照抽象产品角色、抽象工厂角色提供的合同来完成,就可以被客户使用,而不必去修改任何已有的代码,完全符合开闭原则。
 
三、抽象工厂模式
抽象工厂模式是一种比工厂模式抽象成都更高的模式。这种模式是由一个工厂类层次和N个产品类层次组成,从每一个产品类层次中提取出一个产品类形成产品家族,这个类族的实例为产品族,产品族中的产品之间有一种依赖关系,一个具体的工厂类负责创建产品族中的各个产品。
抽象工厂模式的本意要求我们创建具体产品对象时,客户端不能暗示任何具体产品对象类型的信息,但是通过分析模式的通信接口可知,客户端可以告诉工厂类这些具体产品的父类。
关键点在于产品体系,如笔记本,有IBM的笔记本,DELL的笔记本,HP的笔记本,现在有一个抽象笔记本生产商,具体的生产商有IBMProducer,DELLProducer,HPProducer,对于笔记本都有一系列的组件,CPU,RAM,KeyBoard,每个工厂都需要生产CPU,RAM,KeyBoard。在生成具体的工厂类的时候就确定了后面要生产的CPU,RAM或者KeyBoard的具体对象。
例子如下(AbstractFactory.java JDK1.5测试通过):
/**
 *抽象工厂类示例
 *@author tsimgsong
 *@version 1.0,09/04/2007
 */
 class TestAbstractFactory{
        public static void main(String[] args){
               AbstractFactory factory = new IBMFactory();
               factory.createCPU();
        }
}
 
/**
 *抽象工厂
 */
public interface AbstractFactory{
    CPU createCPU();
       RAM createRAM();
       KeyBoard createKeyBoard();
}
 
/**
 *具体工厂 IBM ,生产IBM笔记本所需要的所有产品体系
 */
class IBMFactory implements AbstractFactory
{
        public CPU createCPU(){
               return new IBMCPU();
        }
        public RAM createRAM(){
               return new IBMRAM();
        }
        public KeyBoard createKeyBoard(){
               return new IBMKeyBoard();
        }
}
/**
 *具体工厂 DELL ,生产DELL笔记本所需要的所有产品体系
 */
class DELLFactory implements AbstractFactory
{
        public CPU createCPU(){
               return new DELLCPU();
        }
        public RAM createRAM(){
               return new DELLRAM();
        }
        public KeyBoard createKeyBoard(){
               return new DELLKeyBoard();
        }
}
/**
 *具体工厂 HP,生产HP笔记本所需要的所有产品体系
 */
class HPFactory implements AbstractFactory
{
        public CPU createCPU(){
               return new HPCPU();
        }
        public RAM createRAM(){
               return new HPRAM();
        }
        public KeyBoard createKeyBoard(){
               return new HPKeyBoard();
        }
}
 
/**
 *抽象产品类 CPU
 */
abstract class CPU
{
}
/**
 *抽象产品类 RAM
 */
abstract class RAM
{
}
/**
 *抽象产品类 KeyBoard
 */
abstract class KeyBoard
{
}
/**
 *具体产品类
 */
class IBMCPU extends CPU
{
       public IBMCPU(){
              System.out.println("new IBMCPU");
       }
}
class DELLCPU extends CPU
{
       public DELLCPU(){
              System.out.println("new DELLCPU");
       }
}
class HPCPU extends CPU
{
       public HPCPU(){
              System.out.println("new HPCPU");
       }
}
class IBMRAM extends RAM
{
       public IBMRAM(){
              System.out.println("new IBM Ram");
       }
}
class DELLRAM extends RAM
{
       public DELLRAM(){
              System.out.println("new DELL Ram");
       }
}
class HPRAM extends RAM
{
       public HPRAM(){
              System.out.println("new HP Ram");
       }
}
 
class IBMKeyBoard extends KeyBoard
{
       public IBMKeyBoard(){
              System.out.println("new IBM KeyBoard");
       }
}
class DELLKeyBoard extends KeyBoard
{
       public DELLKeyBoard(){
              System.out.println("new DELL KeyBoard");
       }
}
class HPKeyBoard extends KeyBoard
{
       public HPKeyBoard(){
              System.out.println("new HP KeyBoard");
       }
}
在生产笔记本时,只要制定正确的笔记本产生,对具体的组件就无需再传递任何信息就可以生产出正确的组件。一个具体的工厂生产的是一个能构成产品体系的产品。如果说现在需要增加一种新的产品,如笔记本同时需要生产mouse,需要修改的包括,增加一个mouse抽象类或接口,针对各个厂商实现具体的mouse实现类,修改各个抽象工厂接口,增加生产mouse的方法,修改各个具体工厂类。
在一篇网文中提出了一个改进的方案,改进方案引用如下
http://www.ojava.net/read.php?tid=7243,部分内容做了修改)

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tsimgsong/archive/2007/09/05/1772534.aspx

 

 

 

 

 

 

简单工厂

简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。

不修改代码的话,是无法扩展的。

工厂方法

工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。

在同一等级结构中,支持增加任意产品。

抽象工厂

抽象工厂是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。

应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。

 

区别

简单工厂 用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)

工厂模式 :用来生产同一等级结构中的固定产品。(支持增加任意产品)  
抽象工厂:用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)  

以上三种工厂 方法在等级结构和产品族这两个方向上的支持程度不同。所以要根据情况考虑应该使用哪种方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值