设计模式学习之简单工厂、工厂方法、抽象工厂

一直对简单工厂、工厂方法、抽象工厂三种设计模式的认识比较模糊,特别是工厂方法和抽象工厂方法模式,容易混淆。今天特别针对这三种设计模式学习了一下,整理下自己的理解。

       简单工厂模式(Simple Factory),又称静态工厂方法模式,属于工厂方法模式中的特例,所以GOF在《设计模式》一书中把它归为工厂方法模式。下面是从其他博客摘录的例子:      

      

产品类:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. abstract class BMW {  
  2.     public BMW(){  
  3.           
  4.     }  
  5. }  
  6.   
  7. public class BMW320 extends BMW {  
  8.     public BMW320() {  
  9.         System.out.println("制造-->BMW320");  
  10.     }  
  11. }  
  12. public class BMW523 extends BMW{  
  13.     public BMW523(){  
  14.         System.out.println("制造-->BMW523");  
  15.     }  
  16. }  

工厂类:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public class Factory {  
  2.     public BMW createBMW(int type) {  
  3.         switch (type) {  
  4.           
  5.         case 320:  
  6.             return new BMW320();  
  7.   
  8.         case 523:  
  9.             return new BMW523();  
  10.   
  11.         default:  
  12.             break;  
  13.         }  
  14.         return null;  
  15.     }  
  16. }  


客户类:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public class Customer {  
  2.     public static void main(String[] args) {  
  3.         Factory factory = new Factory();  
  4.         BMW bmw320 = factory.createBMW(320);  
  5.         BMW bmw523 = factory.createBMW(523);  
  6.     }  
  7. }  

           该设计模式合适的应用场景:所有的产品一开始就都已知并且永远不会更改,这样可以都在同一个工厂中被创建。

           想象一下这样的场景,如果设计一个jar包给别人使用,别人的需求随时变化,需要随时调整产品策略,设计出符合他们需求的产品类(例如新增产品),如果使用简单工厂模式,每次别人新增产品的时候,都需要修改工厂方法,重新打包给别人引用。这样的设计简直就是灾难!

           工厂方法(Factory Method)模式,分别将产品和工厂抽象出来。针对产品变更频繁的应用场景,工厂方法模式可谓应运而生:

           

产品类:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. abstract class BMW {  
  2.     public BMW(){  
  3.           
  4.     }  
  5. }  
  6. public class BMW320 extends BMW {  
  7.     public BMW320() {  
  8.         System.out.println("制造-->BMW320");  
  9.     }  
  10. }  
  11. public class BMW523 extends BMW{  
  12.     public BMW523(){  
  13.         System.out.println("制造-->BMW523");  
  14.     }  
  15. }  


创建工厂类:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. interface FactoryBMW {  
  2.     BMW createBMW();  
  3. }  
  4.   
  5. public class FactoryBMW320 implements FactoryBMW{  
  6.   
  7.     @Override  
  8.     public BMW320 createBMW() {  
  9.   
  10.         return new BMW320();  
  11.     }  
  12.   
  13. }  
  14. public class FactoryBMW523 implements FactoryBMW {  
  15.     @Override  
  16.     public BMW523 createBMW() {  
  17.   
  18.         return new BMW523();  
  19.     }  
  20. }  


客户类:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public class Customer {  
  2.     public static void main(String[] args) {  
  3.         FactoryBMW320 factoryBMW320 = new FactoryBMW320();  
  4.         BMW320 bmw320 = factoryBMW320.createBMW();  
  5.   
  6.         FactoryBMW523 factoryBMW523 = new FactoryBMW523();  
  7.         BMW523 bmw523 = factoryBMW523.createBMW();  
  8.     }  
  9. }  

           该设计模式适合的应用场景:用户可以根据自己需求,轻松扩展产品类和工厂方法类,而不需要修改原来的jar包的实现。符合OCP原则,即开闭原则。

           针对同一产品族,即实现统一产品接口的所有产品类,工厂方法模式确实很灵活。实际上这是一个粗粒度的灵活,带来的问题也很多。一、工厂方法类增多;二、如果新增的不是产品,而是产品族(即产品接口)呢?三、如果多个产品族之间有联系,如何解耦呢?

          我们以上面例子中的车为例,如果新的产品是空调车。很明显,车和空调不属于一个产品族,我们很自然的会定义两种接口。如果这两种产品族没有任何联系,可以分别创建两套工厂方法,问题来了,空调和车是有联系的,当然,我们可以根据排列组合,在空调的工厂方法中new车,或者在车的工厂方法中new空调,但是这样耦合性太强。抽象工厂(Abstract Factory)模式应运而生了。在相同的工厂接口中定义了两种产品族的创建接口,这样,将两种产品族轻松的联系在一起。

    

 产品类: 

 

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. //车子以及型号  
  2. abstract class BMW {  
  3.     public BMW(){  
  4.           
  5.     }  
  6. }  
  7. public class BMW320 extends BMW {  
  8.     public BMW320() {  
  9.         System.out.println("制造-->BMW320");  
  10.     }  
  11. }  
  12. public class BMW523 extends BMW{  
  13.     public BMW523(){  
  14.         System.out.println("制造-->BMW523");  
  15.     }  
  16. }  
  17.   
  18. //空调以及型号  
  19. public class Aircondition {  
  20.     public Aircondition(){  
  21.           
  22.     }  
  23. }  
  24. public class AirconditionA extends Aircondition{  
  25.     public AirconditionA(){  
  26.         System.out.println("制造-->AirconditionA");  
  27.     }  
  28. }  
  29. public class AirconditionB extends Aircondition{  
  30.     public AirconditionB(){  
  31.         System.out.println("制造-->AirconditionB");  
  32.     }  
  33. }  


创建工厂类:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. //创建工厂的接口  
  2. public interface FactoryBMW {  
  3.     BMW createBMW_A();  
  4.     BMW createBMW_B();  
  5.     Aircondition createaAirconditionA();  
  6.     Aircondition createaAirconditionB();  
  7. }  
  8. //宝马320系列,生产配置A,B两种空调型号的320汽车  
  9. public class FactoryBWM320 implements FactoryBMW{  
  10.       
  11.     @Override  
  12.     public BMW320 createBMW_A() {  
  13.         // TODO Auto-generated method stub  
  14.         createaAirconditionA();  
  15.         return new BMW320();  
  16.     }  
  17.     @Override  
  18.     public BMW320 createBMW_B() {  
  19.         // TODO Auto-generated method stub  
  20.         createaAirconditionB();  
  21.         return new BMW320();  
  22.     }  
  23.     @Override  
  24.     public Aircondition createaAirconditionA() {  
  25.         // TODO Auto-generated method stub  
  26.         return new AirconditionA();  
  27.     }  
  28.   
  29.     @Override  
  30.     public Aircondition createaAirconditionB() {  
  31.         // TODO Auto-generated method stub  
  32.         return new AirconditionB();  
  33.     }  
  34. }  
  35. //宝马523系列,生产配置A,B两种空调型号的523汽车  
  36. public class FactoryBWM523 implements FactoryBMW {  
  37.   
  38.     @Override  
  39.     public BMW523 createBMW_A() {  
  40.         // TODO Auto-generated method stub  
  41.         createaAirconditionA();  
  42.         return new BMW523();  
  43.     }  
  44.     @Override  
  45.     public BMW523 createBMW_B() {  
  46.         // TODO Auto-generated method stub  
  47.         createaAirconditionB();  
  48.         return new BMW523();  
  49.     }  
  50.     @Override  
  51.     public Aircondition createaAirconditionA() {  
  52.         // TODO Auto-generated method stub  
  53.         return new AirconditionA();  
  54.     }  
  55.   
  56.     @Override  
  57.     public Aircondition createaAirconditionB() {  
  58.         // TODO Auto-generated method stub  
  59.         return new AirconditionB();  
  60.     }  
  61.   
  62. }  


客户:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. public class Customer {  
  2.     public static void main(String[] args){  
  3.           
  4.         //想要A型空调宝马320  
  5.         FactoryBWM320 factoryBWM320_A = new FactoryBWM320();  
  6.         BMW320 bmw320_A = factoryBWM320_A.createBMW_A();  
  7.           
  8.         //想要B型空调宝马320  
  9.         FactoryBWM320 factoryBWM320_B = new FactoryBWM320();  
  10.         BMW320 bmw320_B = factoryBWM320_B.createBMW_B();  
  11.           
  12.         //想要A型空调宝马523  
  13.         FactoryBWM523 factoryBWM523_A = new FactoryBWM523();  
  14.         BMW523 bmw523_A = factoryBWM523_A.createBMW_A();  
  15.           
  16.         //想要B型空调宝马523  
  17.         FactoryBWM523 factoryBWM523_B = new FactoryBWM523();  
  18.         BMW523 bmw523_B = factoryBWM523_B.createBMW_B();  
  19.     }  
  20. }  

            总结:三种设计模式均属于创建型模式。简单工厂模式到工厂方法模式解决的是灵活性、可扩展问题,工厂方法模式到抽象工厂方法模式解决的是不同产品族的耦合问题。当然,三种设计模式都降低了对产品类的耦合。

            以上是我对着三种设计模式的一点理解,求指正~

            参考:http://blog.youkuaiyun.com/jason0539/article/details/23020989

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值