zoukankan      html  css  js  c++  java
  • 2 创建型模式之

    工厂模式适用于大量产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。我不喜欢看一堆的理论,书上把工厂模式分为下面三种。

    1 简单工厂模式

    2 工厂方法模式

    3 抽象工厂模式

    一 简单工厂模式

    先看第1种,简单工厂模式,所谓简单,就是直接能想到的,直接 if 判断,符合条件就创建相应的对象,我们以生产不同的手机为例子。分别生产小米手机,Nokia手机,三星手机,代码如下:

    1 //手机
    2 public interface Phone {
    3     void call();
    4 }
    1 //Nokia手机
    2 public class NokiaPhone implements Phone {
    3     @Override
    4     public void call() {
    5         System.out.println("我用诺基亚手机打电话");
    6     }
    7 }
    1 //三星手机
    2 public class SanuagPhone implements Phone {
    3     @Override
    4     public void call() {
    5         System.out.println("我用三星手机打电话");
    6     }
    7 }
    1 //小米手机
    2 public class XiaoMiPhone implements Phone {
    3     @Override
    4     public void call() {
    5         System.out.println("我用小米手机打电话");
    6     }
    7 }

    各种手机的类有了,简单工厂代码如下

     1 /**
     2  *
     3  * 简单工厂模式
     4  * 工厂里面有一个生产手机的方法,根据不同的值生产不同的手机
     5  *
     6  */
     7 public class PhoneFactory {
     8 
     9     public Phone produce(String type){
    10         Phone phone = null;
    11 
    12         if("xiaomi".equals(type)){
    13             phone = new XiaoMiPhone();
    14         }else if("sanuag".equals(type)){
    15             phone = new SanuagPhone();
    16         }else if("nokia".equals(type)){
    17             phone = new NokiaPhone();
    18         }
    19 
    20         return phone;
    21     }
    22 
    23 }

    特点:生产少量产品,可以用这种方法,生产大量的产品需要修改原来的代码,而且传入的参数有可能会出错,所以适用条件是生产少量的产品,下面看看工厂方法模式

    二 工厂方法模式:为什么叫工厂方法模式,关键在于“方法”,因为工厂方法模式中,工厂类中有许多的方法用来生产不同的手机,不同于简单工作模式(工厂中只有一个生产方法),工厂方法模式中,工厂类中有许多的方法用来生产不同的产品的,代码如下

     1 /**
     2  *
     3  * 工厂类中有许多的方法用来生产不同的产品的
     4  *
     5  * 是对简单工厂方法模式的改进,
     6  * 在简单工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,
     7  * 而多个工厂方法模式是提供多个工厂方法,分别创建对象
     8  *
     9  */
    10 public class PhoneFactory2 {
    11     public Phone produceNokia(){
    12         return new NokiaPhone();
    13     }
    14 
    15     public Phone produceXiaomi(){
    16         return new XiaoMiPhone();
    17     }
    18 
    19     public Phone produceSanug(){
    20         return new SanuagPhone();
    21     }
    22 
    23 }

    工作方法解决了第一种简单工厂模式中,字符串传入出错会出现创建不了对象的情况,而且也能解决创建少量对象的问题,不过也不能创建太多的对象,但相对于简单工厂模式,要好多了,不过PhoneFactory2 类还是可以再优化的,可以把类中的方法都改成静态的,这样就可以不用创建工厂对象就可以创建对象了,代码如下:

     1 /**
     2  * 将上面的多个工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。
     3  *
     4  * 简单工厂模式 之静态工厂方法模式。
     5  *
     6  * 总体来说,工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。
     7  * 在以上的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,
     8  * 所以,大多数情况下,我们会选用第三种——静态工厂方法模式。
     9  */
    10 public class PhoneFactory3 {
    11     private PhoneFactory3(){}
    12 
    13     public static Phone produceNokia(){
    14         return new NokiaPhone();
    15     }
    16 
    17     public static Phone produceSanug(){
    18         return new SanuagPhone();
    19     }
    20 
    21     public static Phone produceXiaomi(){
    22         return new XiaoMiPhone();
    23     }
    24 
    25 }

    三 抽象工厂模式 : 抽象工厂为什么叫抽象工厂?自己的理解就是因为抽象工厂代码中的工厂是抽象的,所以叫做抽象工厂,上面2种工厂模式,不管是简单工厂模式还是工厂方法模式或者是工厂方法模式中的优化的方案,都有一个缺点,在创建大量对象的时候,都需要对原来的代码进行修改才能达到扩展的目的,因为都是一个工厂生产多种产品,是一对多的。那么可不可以多对多呢,就是多个工厂生产各自的产品。对于本例就是三星的工厂只生产三星的手机,小米的工厂只生产小米的手机,这样的话,如果需要再添加需求,比如还要生产华为的手机,那么可以直接添加一个华为的工厂,直接生产华为手机就是了,不用修改原来的代码,这样可以做到对修改关闭,对扩展开放(见设计模式之六大原则之开闭原则),代码如下:

    1 //工厂
    2 public interface Factory {
    3     Phone produce();
    4 }
    1 //生产小米手机的工厂
    2 public class NokiaFactory implements Factory{
    3     @Override
    4     public Phone produce() {
    5         return new NokiaPhone();
    6     }
    7 }
    1 //生产三星手机的工厂
    2 public class SanuagFactory implements Factory{
    3     @Override
    4     public Phone produce() {
    5         return new SanuagPhone();
    6     }
    7 }
    1 //生产小米手机的工厂
    2 public class XiaomiFactory implements Factory{
    3     @Override
    4     public Phone produce() {
    5         return new XiaoMiPhone();
    6     }
    7 }

    客户端测试类如下 :

    1  private static void testFactoryMethod(){
    2         Factory factory = new NokiaFactory();
    3         Phone phone = factory.produce();
    4         phone.call();
    5  }

    这样就可以做到了对扩展开放对修改关闭,工厂和产品都是抽象的,依赖接口,面向接口编程。

    可以达到更好的扩展性,上面的几个例子希望能帮忙读者理解工厂模式。本文的代码放到了github上

    git@github.com:jiulu313/DesignSchema.git

     

     注:设计模式交流学习群 632945466  欢迎所有热爱技术的大牛,小菜,一起学习讨论进步提高,欢迎随时批评指正

  • 相关阅读:
    让程序只有一个进程实例在运行
    HDFS写入和读取流程
    HBase技术详细介绍
    Eclipse下配置使用Hadoop插件
    Hadoop节点热拔插
    剖析为什么在多核多线程程序中要慎用volatile关键字?
    MapReduce 模式、算法和用例(MapReduce Patterns, Algorithms, and Use Cases)
    并行编程中的“锁”难题
    配置 eclipse 编译、开发 Hadoop(MapReduce)源代码
    HBASE松散数据存储设计初识
  • 原文地址:https://www.cnblogs.com/start1225/p/6716394.html
Copyright © 2011-2022 走看看