zoukankan      html  css  js  c++  java
  • 结合实例分析简单工厂模式&工厂方法模式&抽象工厂模式的区别

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

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

    产品类的共同接口

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

    控制台输出结果:

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

  • 相关阅读:
    Notes about "Exploring Expect"
    Reuse Sonar Checkstyle Violation Report for Custom Data Analysis
    Eclipse带参数调试的方法
    MIT Scheme Development on Ubuntu
    Manage Historical Snapshots in Sonarqube
    U盘自动弹出脚本
    hg的常用配置
    Java程序员的推荐阅读书籍
    使用shared memory 计算矩阵乘法 (其实并没有加速多少)
    CUDA 笔记
  • 原文地址:https://www.cnblogs.com/zhi-hao/p/4028169.html
Copyright © 2011-2022 走看看