zoukankan      html  css  js  c++  java
  • 简单工厂,Factory Method(工厂方法)和Abstract Factory(抽象工厂)模式

    对于简单工厂来说,它的工厂只能是这个样子的
    public class SimplyFactory {
    /**
    * 静态工厂方法
    */
    public static Prouct factory(String which) throw NoSuchProductExcption
    {

       if(which.equalIgnoreCase("product1"))
       {
       return new Product1();
        }
       else if(which.equalsIgnoreCase("product2"))
          {   
            return new Product2(); 
           }
      else if(which.equalsIgnoreCase("product3"))
          {   
            return new Product3(); 
           }
      else throw  NoSuchProductExcption("NoSuchProduct");
       }
      }
    }

    而对产品Product1,Product2,Product3,可以执行接口Product,也可以不执行接口Product(当然这样不好),这个Product接口只是用来抽象具体product用的

    public interface Product
    {
      void productMethod1();     //这些只是
      void productMethod2();
      void productMethod3();
    }
    对工厂来说,只要有这么一种产品,一般来说就要在工厂里有它的生产的方法, 否则抛出异常,而要工厂生产的话,也必须下达生产什么产品的命令,至少要向工厂发出信号,让工厂足以区分是要生产什么产品,否则工厂是不知道生产哪一种产品,
    对于简单工厂来说,就是需要在工厂中枚举所有的产品,所以说简单工厂还是非常笨的。 


    if(which.equalIgnoreCase("product1"))     只是用来区分生产什么产品的标记值,(也可以根据产品其它属性来 判断,比如产品类型,产品大小,总之能够区分是什么产品的属性,或者是与产品属性相关的变量)    或者说标记值是A,生产A产品,或者工厂里定义不是 这样的,我偏偏要生产B产品,或者再特殊一些,我偏偏要生产A产品+B产品,那么就要 return new ProductA()+new ProductB()了。

    这样,我们就可以看出一个问题来,如果要能够被简单工厂生产出来,就必须在简单工厂中有能够生产出的它的方法定义,当然还需要有这个具体产品类的定义,就 是有class对应,这样确保在简单工厂中new 它的时候不会抛出 NoSuchProduct的Exception.


    对于工厂方法来说
    实质上它是让工厂实现了抽象的工厂接口,它把具体怎么生产一种东西,放在具体的工厂去实现了,所谓”延迟到子类中实现“
    public interface Creator
    {
      public Prouct factory();
    }

    public SubCreator1 implent Creator
    {
       public Prouct factory()
      {
       return new ConcreteProduct1();
       }
    }

    public SubCreator2 implent Creator
    {
       public Prouct factory()
      {
        return new ConcreteProduct2();
       }
    }
    请注意:返回类型是Product型的!!
    这样客户端调用是直接new 一个具体工厂的实例,然后命令它去生产,而对于具体工厂的父类(既工厂接口,接口完全可以改成子类继承父类来实现,只是这样不好,不符合OO的原则),它完全不知道什么产品被生产了,甚至它连那个具体工厂被实例化它都不知道

    抽象工厂模式 
    抽象工厂模式意图是“提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类”或为特定的客户(或情况)提供特定系列的对象。

    public interface Creator
    {
       public ProuctA factoryA();
       public ProuctB factoryB();
    }

    public interface ProductA     //ProductA 接口
    {
    }

    public interface ProductB     //ProductB 接口
    {
    }


    public class ConCreator1 implent Creator
    {
       public ProuctA factoryA()
      {
       return new ConcreteProductA1();
       }

       public ProuctB factoryB()
      {
       return new ConcreteProductB1();
       }
    }

    public class ConCreator2 implent Creator
    {
       public ProuctA factoryA()
       {
        return new ProductA2();
        }

       public ProuctB factoryB()
       {
       return new ProductB2();
        }
    }


    public class ProductA1 implements  ProductA
    {
     public  ProductA1()
       {
        }
    }
    public class ProductA2 implements  ProductA
    {
     public  ProductA2()
       {
        }
    }
    public class ProductB1 implements  ProductB
    {
     public  ProductB1()
       {
        }
    }
    public class ProductB2 implements  ProductB
    {
     public  ProductB2()
       {
        }
    }
    实际上是这样的
    1,两个工厂类ConCreator1,ConCreator2都实现了Creator接口
    2,ProuctA1,ProductA2都实现了ProductA接口
    3,ProuctB1,ProductB2都实现了ProductB接口
    4,ConCreator1负责生产ProductA类型的产品(包括ProductA1,ProductB1)
    5,ConCreator2负责生产ProductB类型的产品(包括ProductA2,ProductB2)
    6,工厂方法也有这样的特征,也就是说Creator不知道什么被生产出来,甚至不知道ConCreator1还是ConCreator2被实例化了,因 为client高兴调那一个工厂,就调那一个工厂,就是说工厂能生产什么,对客户端是可见的。甚至还有一种情况,客户端高兴起来就生产了 ProductA1,我就不生产ProductA2,因为上面的例子中它们还都是松散的,没有绑定在一起
    ----------------------------总结----------------------------

    工厂方法模式:
    一个抽象产品类,可以派生出多个具体产品类。  
    一个抽象工厂类,可以派生出多个具体工厂类。  
    每个具体工厂类只能创建一个具体产品类的实例。

    抽象工厂模式:
    多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。  
    一个抽象工厂类,可以派生出多个具体工厂类。  
    每个具体工厂类可以创建多个具体产品类的实例。  
       
    区别:
    工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。  
    工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
  • 相关阅读:
    luoguP1160 队列安排 x
    luoguP3366 【模板】最小生成树 x
    cogs服务点设置(不凶,超乖) x
    codevs3269 混合背包 x
    [kuangbin带你飞]专题一 简单搜索 x
    [SWUST1744] 方格取数问题(最大流,最大独立集)
    [SWUST1738] 最小路径覆盖问题(最大流,最小路径覆盖)
    [SWUST1742] 试题库问题(最大流)
    [HDOJ5676]ztr loves lucky numbers(状压枚举,打表,二分)
    [swustoj1739] 魔术球问题 (最大流,最小路径覆盖)
  • 原文地址:https://www.cnblogs.com/yeagen/p/2173859.html
Copyright © 2011-2022 走看看