• 简单工厂模式&工厂方法模式&抽象工厂模式的区别


     之前写过一篇关于工厂模式(Factory Pattern)的随笔,里面分析了简单工厂模式,但对于工厂方法和抽象工厂的分析较为简略。这里重新分析分析三者的区别,工厂模式是java设计模式中比较简单的一个设计模式,但很多地方都用到了工厂模式,(如解析xml中,jdbc连接数据库等)利用好工厂模式对程序的设计很有用处。工厂模式在一些设计模式的书中分为简单工厂模式,工厂方法模式和抽象工厂模式三类。也有把工厂方法模式划分到抽象工厂模式的,认为工厂方法是抽象工厂模式的特例的一种,就是只有一个要实现的产品接口。下面结合例子分析三者的区别。

      首先是简单工厂模式,这里以工厂生产产品为例。

    产品类的共同接口

    1 1 package factory;
    2 2 /**
    3 3  * 
    4 4  * @author CIACs
    5 5  *
    6 6  */
    7 7 public interface Product {
    8 8     //声明类所需继承的共同接口,也可以是抽象类
    9 9 }

    产品A

     1 package factory;
     2 /**
     3  * 
     4  * @author CIACs
     5  *
     6  */
     7 public class ProductA implements Product {
     8     public ProductA() {
     9         System.out.println("ProductA");
    10     }
    11 }

    产品B

     1 package factory;
     2 /**
     3  * 
     4  * @author CIACs
     5  *
     6  */
     7 public class ProductB implements Product {
     8     public ProductB() {
     9         System.out.println("ProductB");
    10     }
    11 }

    工厂类

     1 package factory;
     2 /**
     3  * 
     4  * @author CIACs
     5  *
     6  */
     7 public class Factory {
     8     //可以在工厂类中添加任何你所需要的逻辑
     9     public static Product create(String str)
    10     {
    11         //生成ProductA
    12         if(str.equalsIgnoreCase("ProductA"))
    13         {
    14             return new ProductA();
    15         }
    16         else
    17             //生成ProductB
    18             if(str.equalsIgnoreCase("ProductB"))
    19             {
    20                 return new ProductB();
    21             }
    22         return null;
    23     }
    24 
    25 }

    客户端

     1 package factory;
     2 /**
     3  * 
     4  * @author CIACs
     5  *
     6  */
     7 public class Client {
     8     public static void main(String[] args) {
     9         //调用Factory的静态方法生成所要的类
    10         Factory.create("productA");
    11         Factory.create("ProductB");
    12     }
    13 }

    控制台输出结果:

    简单工厂模式实现了生成产品类的代码跟客户端代码分离,在工厂类中你可以添加所需的生成产品的逻辑代码,但是问题来了,优秀的java代码是符合“开放-封闭”原则的,也就是说对扩展开发,对修改关闭,如果你要加一个产品类C,你就要修改工厂类里面的生成产品的代码,在这里你就要增加if-else判断。对于这个问题,我们的工厂方法模式就可以解决这个问题。

      接下来是工厂方法模式

     产品类中增加了ProductC(其他产品类的代码是可以重用上面的,只要把包名更改了就行)。

     1 package factoryMehtod;
     2 /**
     3  * 
     4  * @author CIACs
     5  *
     6  */
     7 
     8 public class ProductC implements Product {
     9     public ProductC() {
    10         System.out.println("productC");
    11     }
    12 }

    声明工厂接口

     1 package factoryMehtod;
     2 /**
     3  * 
     4  * @author CIACs
     5  *
     6  */
     7 public interface Factory {
     8     //声明产生产品类的方法
     9     public Product createProduct();
    10 }

    产生ProductA的FactoryA

     1 package factoryMehtod;
     2 /**
     3  * 
     4  * @author CIACs
     5  *
     6  */
     7 public class FactoryA implements Factory {
     8     //实现工厂类的方法生成产品类A
     9     public Product createProduct()
    10     {
    11         return new ProductA();
    12     }
    13 
    14 }

    产生ProductB的FactoryB

     1 package factoryMehtod;
     2 /**
     3  * 
     4  * @author CIACs
     5  *
     6  */
     7 public class FactoryB implements Factory {
     8     //实现工厂类的方法生成产品类B
     9     public Product createProduct()
    10     {
    11         return new ProductB();
    12     }
    13 }

    产生ProductC的FactoryC

     1 package factoryMehtod;
     2 /**
     3  * 
     4  * @author CIACs
     5  *
     6  */
     7 public class FactoryC implements Factory {
     8     //实现工厂类的方法生成产品类C
     9     public Product createProduct()
    10     {
    11         return new ProductC();
    12     }
    13 }

    客户端

     1 package factoryMehtod;
     2 /**
     3  * 
     4  * @author CIACs
     5  *
     6  */
     7 public class Client {
     8     public static void main(String[] args) {
     9         Factory factory;
    10         factory = new FactoryA();
    11         factory.createProduct();
    12         factory = new FactoryB();
    13         factory.createProduct();
    14         factory = new FactoryC();
    15         factory.createProduct();
    16     }
    17 }

    控制台输出结果:

       工厂方法模式中我们把生成产品类的时间延迟,就是通过对应的工厂类来生成对应的产品类,在这里我们就可以实现“开发-封闭”原则,无论加多少产品类,我们都不用修改原来类中的代码,而是通过增加工厂类来实现。但是这还是有缺点的,如果产品类过多,我们就要生成很多的工厂类。假如我们要实现的产品接口不止一个,也就是有多个产品接口,不同产品接口有对应的产品族。什么是产品族呢?简单的理解就是,不同牌子产的车里面会有跑车类型,家庭类型,商用类型等的车,不同牌子的车的跑车类型的车可以组成一个产品族。对于这种情况我们可以采用抽象工厂模式。

       最后是抽象工厂模式,在这里我们为不同产品附加上对应的礼物,就是说ProductA中会有GiftA。

    增加的Gift接口

    1 package abstractFactory;
    2 /**
    3  * 
    4  * @author CIACs
    5  *
    6  */
    7 public interface Gift {
    8     //声明产品赠品的接口,当然也可以是抽象类,同样为了简单就不声明方法了
    9 }

    GiftA类

     1 package abstractFactory;
     2 /**
     3  * 
     4  * @author CIACs
     5  *
     6  */
     7 public class GiftA implements Gift {
     8     public GiftA()
     9     {
    10         System.out.println("GiftA");
    11     }
    12 }

    GiftB类

     1 package abstractFactory;
     2 /**
     3  * 
     4  * @author CIACs
     5  *
     6  */
     7 public class GiftB implements Gift {
     8     public GiftB()
     9     {
    10         System.out.println("GiftB");
    11     }
    12 }

    Factory接口

     1 package abstractFactory;
     2 /**
     3  * 
     4  * @author CIACs
     5  *声明Product类工厂和Gift类工厂的工同工厂接口
     6  */
     7 public interface Factory {
     8     public Product createProduct();
     9     public Gift createGift();
    10 
    11 }

    生成ProductA和GiftA的FactoryA

     1 package abstractFactory;
     2 /**
     3  * 
     4  * @author CIACs
     5  *FactoryA可以生成ProductA和GiftA
     6  */
     7 public class FactoryA implements Factory {
     8     @Override
     9     public Product createProduct()
    10     {
    11         return new ProductA();
    12     }
    13     @Override
    14     public Gift createGift()
    15     {
    16         return new GiftA();
    17     }
    18 }

    生成ProductB和GiftB的FactoryB

     1 package abstractFactory;
     2 /**
     3  * 
     4  * @author CIACs
     5  *FactoryB可以生成ProductB和GiftB
     6  */
     7 public class FactoryB implements Factory {
     8     @Override
     9     public Product createProduct() {
    10         return new ProductB();
    11     }
    12     @Override
    13     public Gift createGift() {
    14         return new GiftB();
    15     }
    16 
    17 }

    客户端

     1 package abstractFactory;
     2 /**
     3  * 
     4  * @author CIACs
     5  *
     6  */
     7 public class Client {
     8     public static void main(String[] args) {
     9         Factory factory;
    10         factory = new FactoryA();
    11         factory.createProduct();
    12         factory.createGift();
    13         factory = new FactoryB();
    14         factory.createProduct();
    15         factory.createGift();
    16     }
    17 }

    控制台输出结果:

      抽象工厂模式中我们可以定义实现不止一个接口,一个工厂也可以生成不止一个产品类,抽象工厂模式较好的实现了“开放-封闭”原则,是三个模式中较为抽象,并具一般性的模式。我们在使用中要注意使用抽象工厂模式的条件。

    由于水平有限,文章中难免有错误的地方,欢迎指出错误或不足之处,共同进步。欢迎转载,谢谢
  • 相关阅读:
    POJ 3904 Sky Code [数学]
    UVA 11542 Square [XOR方程组]
    CSS+DIV 设置圆角边框加阴影效果
    取消谷歌CHROME文本框(域)外边框高亮和缩放功能的办法
    IE和火狐CSS透明层兼容写法
    Ubuntu 12.04 amd64 搭建Apache+PHP+Mysql环境
    CSS样式表的优先级别
    css设置透明层
    卸载gnome的命令为
    ubuntu12.04 启动n卡独显方法
  • 原文地址:https://www.cnblogs.com/sunweiye/p/10815928.html
Copyright © 2020-2023  润新知