java设计模式--工厂模式

所谓工厂,就是要造产品,比如一个小型砖瓦厂,只有一个窑,既能造砖又能造瓦,这种叫简单工厂模式。规模稍大一点呢,我多个窑,有的窑专门造砖,有的窑专门造瓦,想造别的,比如瓷砖,我再用个专门的窑,这种成了工厂方法模式。但若是我开个汽车装配厂,我既要轮胎,又要发动机,又要车架等等组合型的,那就要抽象工程模式。所以,我们的工厂模式分为三种:简单工厂模式,工厂方法模式,抽象工厂模式。

   首先,简单工厂:

   所谓简单工厂,就是你告诉我,你想要什么产品,我能产这种产品,就给你生产。简单工厂模式又叫静态工厂模式,因为这个工厂产出的产品是开始就定死的,就能造那几种,多了没办法。而设计原则是新增产品不要修改原有的代码,就好比你一个砖瓦窑想要生产瓷器,即便不砸了重来,也得内部整改很多东西。
   以下的代码示例是一个简单工厂类,该工厂类可以生产手机, 且只能生产IPhone和Samsung两款手机。倘若你想生产小米手机,不好意思,目前生产不了,RuntimeException,你非要生产呢,继续加判断,就等于改掉了目前的工厂类。
   代码:
    
1
2
3
4
5
6
7
8
9
10
11
12
public  class  SimplePhoneFactory {
     
     public  static  Cellphone getCellphone(String type){
         if ( "iPhone" .equals(type)){
             return  new  IPhone();
         } else  if ( "Samsung" .equals(type)) {
             return  new  Samsung();
         } else  {
             throw  new  RuntimeException( "没有正确的手机类型创建" );
         }
     }
}

  

    工厂方法:

    工厂方法是在简单工厂的基础上,可以扩展的工厂,从设计的思路上,更加清晰的去管理工厂的生产。将每个产品的工厂实现细分出来。这种模式实现上面的手机工厂的话,就是一个广义的工厂(接口),然后具体的实现每个产品的工厂实现。如果要新增产品的话,直接加一个该新产品的实现工厂即可,不用改动原有代码。
    代码:
 
1
2
3
4
5
6
/*
   工厂方法接口
  */
public  interface  PhoneFactory {
    public  Cellphone getPhone();
}

 

1
2
3
4
5
6
7
8
9
10
11
12
/*
  * @Description: iPhone 工厂
  */
public  class  IPhoneFactory  implements  PhoneFactory{
 
     @Override
     public  Cellphone getPhone() {
         // TODO Auto-generated method stub
         return  new  IPhone();
     }
 
}
1
2
3
4
5
6
7
8
9
10
11
12
/*
  * @Description:samsung工厂
  */
public  class  SamsungPhoneFactory   implements  PhoneFactory{
 
     @Override
     public  Cellphone getPhone() {
         // TODO Auto-generated method stub
         return  new  Samsung();
     }
 
}

 以上代码可以看出,每个产品都需要自己的实现工厂,这时如果我们需要新增加新产品,比如小米手机,只需要新增一个MIPhoneFactory来实现PhoneFactory即可。

   抽象工厂:

    开头也说了,针对于组合型产品,我们使用抽象工厂。也就是说,这种工厂相对其他两种,复杂的多。而实际上,我们没办法拿抽象工厂和简单工厂已经工厂方法比较,因为他们不是用来解决同一类问题的,基本上没有什么可比性。抽象工厂用来针对的是产品族,而简单工厂和工厂方法都是针对单一产品的,如果真让抽象工厂去对单个产品进行管理,反倒无能为力。
   这里我们还以手机为例,我们要生产手机,需要很多配件,比如CPU,比如相机,比如内存等等,我们暂且只认为决定一款手机好坏只有这三个组件。使用抽象工厂来实现。
   首先,我们定义CPU的接口,已经能生产的一些列CPU,这里以GoodCPU和BadCPU为例:
   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public  interface  CPU {
    void  run();
    void  start();
}
//高端CPU
class  GoodCUP  implements  CPU{
 
     @Override
     public  void  run() {
         System.out.println( "高端CPU运转方法。。。" );
         
     }
 
     @Override
     public  void  start() {
         System.out.println( "高端CPU开始方法。。。" );
         
     }
     
}
 
//低端CPU
class   BadCPU  implements  CPU{
 
     @Override
     public  void  run() {
         System.out.println( "低端CPU运转方法。。。" );
         
     }
 
     @Override
     public  void  start() {
         System.out.println( "低端CPU开始方法。。。" );
         
     }
     
}

  然后是相机接口,以及相关的相机生产类型,其中的方法是随便写的。

    

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public  interface  Camera {
    public  void  take();
  
}
 
class  GoodCamera  implements  Camera{
 
     @Override
     public  void  take() {
         System.out.println( "高端相机拍照。。。" );
         
     }
     
}
 
class  BadCamera  implements  Camera{
 
     @Override
     public  void  take() {
         System.out.println( "低端相机拍照。。。" );
         
     }
     
}

  最后一个内存的接口已经一系列类型:

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public  interface  Memory {
     
     void  work();
}
 
class  GoodMemory  implements  Memory{
 
     @Override
     public  void  work() {
         System.out.println( "高性能内存工作" );
         
     }
     
}
class  BadMemory  implements  Memory{
 
     @Override
     public  void  work() {
         System.out.println( "低性能内存工作" );
         
     }
     
}

  

   我们前面说了,抽象工厂就是利用一些列组件组合产品的工厂,上面我们写的CPU,相机,内存都是我们要组件手机的组件。现在,我们开始写我们的抽象工厂。当然为了方便,肯定要有工厂接口:

  

1
2
3
4
5
public  interface  AbPhoneFactory {
    CPU getCPU();
    Camera getCamera();
    Memory getMemory();
}

  然后,我们根据自己的需要,随机组合几种组件,即可得到我们的产品,当然这是一组(产品)组合出来的最终产品。

     比如我们用好的CPU,好的内存,好的相机组合成一个好的手机:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public  class  GoodsPhoneFactory   implements  AbPhoneFactory{
 
     @Override
     public  CPU getCPU() {
         // TODO Auto-generated method stub
         return  new  GoodCUP();
     }
 
     @Override
     public  Camera getCamera() {
         // TODO Auto-generated method stub
         return  new  GoodCamera();
     }
 
     @Override
     public  Memory getMemory() {
         // TODO Auto-generated method stub
         return  new  GoodMemory();
     }
 
     
 
}

  也可以用差的CPU,差的内存,差的相机组合成比较差劲的手机:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public  class  BadPhoneFactory  implements  AbPhoneFactory{
 
     @Override
     public  CPU getCPU() {
         // TODO Auto-generated method stub
         return  new  BadCPU();
     }
 
     @Override
     public  Camera getCamera() {
         // TODO Auto-generated method stub
         return  new  BadCamera();
     }
 
     @Override
     public  Memory getMemory() {
         // TODO Auto-generated method stub
         return  new  BadMemory();
     }
 
}

 当然你也可以乱组合成中等的,这都是随你便了,只要加一个工厂实现即可。

 

最后,我们来总结一下吧:

    对于单一产品,简单工厂更简单,但是新增产品时却很乏力,或者说不符合设计原则,而工厂方法是不修改原有类的前提下,新增工厂类实现,更符合设计原则。是不是我们在单一产品的时候就该选择工厂方法了呢?下面给出这么一个对比:

    -- 结构复杂度 简单工厂更加简单 简单工厂优于工厂方法

   -- 代码复杂度 工厂方法复杂度较高 简单工厂优于工厂方法
    -- 客户端编程难度 工厂方法客户端需要了解更多的实现工厂 简单工厂优于工厂方法
   -- 管理难度 工厂方法由于实现工厂类较多,管理更难 简单工厂优于工厂方法

   结合以上四点,我们说简单工厂比工厂方法更加易用。这也就是开发时候简单工厂比工厂方法使用的更多的原因。

   对于产品族,如果使用工厂模式,唯一的选择--抽象工厂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值