• Java设计模式—工厂方法模式&抽象工厂模式



    工厂方法模式与抽象工厂模式都是设计模式中重要而且常见的模式。


          工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。


    通用类图如下:



            在工厂方法模式中,抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义;Creator为抽象创建

    类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂ConcreteCreator完成的。


    工厂方法模式的扩展方式有很多种,下边是工厂方法模式一个比较实用的源代码:


    抽象产品类:

    public abstract class Product {    
         //产品类的公共方法
         public void method1(){
                 //业务逻辑处理
         }  
         //抽象方法
         public abstract void method2();    
    }


    具体的产品类可以有多个,都继承于抽象产品类。

    public class ConcreteProduct1 extends Product {
         public void method2() {
                 //业务逻辑处理
         }
    }
    public class ConcreteProduct2 extends Product {
         public void method2() {
                 //业务逻辑处理
         }
    }


    抽象工厂类负责定义产品对象的产生:

    public abstract class Creator {    
         /*
          * 创建一个产品对象,其输入参数类型可以自行设置
          * 通常为String、Enum、Class等,当然也可以为空
          */        
         public abstract <T extends Product> T createProduct(Class<T> c);
    }


    具体如何产生一个产品的对象,是由具体的工厂类实现的:

    public class ConcreteCreator extends Creator {     
         public <T extends Product> T createProduct(Class<T> c){
                 Product product=null;
                 try {
                        product = (Product)Class.forName(c.getName()).newInstance();
                 } catch (Exception e) {
                        //异常处理
                 }
                 return (T)product;         
         }
    }

    场景类如下所示:

    public class Client {
         public static void main(String[] args) {
                 Creator creator = new ConcreteCreator();
                 Product product = creator.createProduct(ConcreteProduct1.class);
                 /*
                  * 继续业务处理
                  */
         }
    }

    该通用代码是一个比较实用、易扩展的框架。



    工厂方法模式的优点:

    (1)良好的封装性,代码结构清晰。一个对象创建是有条件约束的,如一个调用者需要一个具体的产品对象,只要

    知道这个产品的类名(或约束字符串)就可以了,不用知道创建对象的艰辛过程,降低模块间的耦合。

    (2)工厂方法模式的扩展性非常优秀。在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个工厂类,

    就可以完成“拥抱变化”。

    (3)屏蔽产品类。这一特点非常重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,

    只要接口保持不变,系统中的上层模块就不要发生变化。因为产品类的实例化工作是由工厂类负责的,一个产品对象

    具体由哪一个产品生成是由工厂类决定的。



    使用场景:


           首先,工厂方法模式是new一个对象的替代品,所以在所有需要生成对象的地方都可以使用,但是需要慎重地考

    虑是否要增加一个工厂类进行管理,增加代码的复杂度。




    工厂方法模式的扩展:


    (1)简单工厂模式

    当一个模块只需要一个工工厂类时,我们可以将抽象工厂类kill掉,然后将具体工厂类中制造产品的方法前面加static

    关键字,则,工厂方法模式就变为了简单工厂模式。

             该模式是工厂方法模式的弱化,因为简单,所以称为简单工厂模式(Simple Factory Pattern),也叫做静态工

    厂模式。在实际项目中,采用该方法的案例还是比较多的,其缺点是工厂类的扩展比较困难,不符合开闭原则,但它

    仍然是一个非常实用的设计模式。


    (2)多工厂模式


    当遇到一个复杂的项目,初始化一个对象很费事的时候,我们可以使用多工厂模式,即一个工厂只生产特定的某种产

    品,实现了单一职责。

            每一个产品类都对应了一个创建类,好处就是创建类的职责清晰,而且结构简单,但是给可扩展性和可维护性带

    来了一定的影响。为什么这么说呢?如果要扩展一个产品类,就需要建立一个相应的工厂类,这样就增加了扩展的难

    度。因为工厂类和产品类的数量相同,维护时需要考虑两个对象之间的关系。
     
          当然,在复杂的应用中一般采用多工厂的方法,然后再增加一个协调类,避免调用者与各个子工厂交流,协调类

    的作用是封装子工厂类,对高层模块提供统一的访问接口。




    抽象工厂模式


    抽象工厂模式是一种比较常用的模式。


    其定义如下:

    为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。


    通用类图如下:



              抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的

    对象是一种非常好的解决方式。我们来看看抽象工厂的通用源代码,首先有两个互相影响的产品线(也叫做产族),

    例如制造汽车的左侧门和右侧门,这两个应该是数量相等的——两个对象之间的约束,每个型号的车门都是不

    一样的,这是产品等级结构约束的,我们先看看两个产品族的类图,如下所示:



    注意类图上的圈圈、框框相对应,两个抽象的产品类可以有关系,例如共同继承或实现一个抽象类或接口。


    通用源代码如下:

    //抽象产品类
    public abstract class AbstractProduct A {   
         //每个产品共有的方法
         public void shareMethod(){
         }
         //每个产品相同方法,不同实现
         public abstract void doSomething();
    }
    


    产品A1的实现类
    public class ProductA1 extends AbstractProductA {
         public void doSomething() {
                 System.out.println("产品A1的实现方法");
         }
    }


    产品A2的实现类
    public class ProductA2 extends AbstractProductA {
         public void doSomething() {
                 System.out.println("产品A2的实现方法");
         }
    }
    
    产品B与此类似,不再赘述。


    抽象工厂类
    public abstract class AbstractCreator {
         //创建A产品家族
         public abstract AbstractProductA createProductA(); 
         //创建B产品家族
         public abstract AbstractProductB createProductB();
    }
    

    注意:有N个产品族,在抽象工厂类中就应该有N个创建方法。


    产品等级1的实现类
    public class Creator1 extends AbstractCreator {    
         //只生产产品等级为1的A产品
         public Abstract ProductA createProductA() { 
                 return new ProductA1();
         }
         //只生产产品等级为1的B产品
         public AbstractProductB createProductB() {
                 return new ProductB1();
         }
    }

    产品等级2的实现类
    public class Creator2 extends AbstractCreator {    
         //只生产产品等级为2的A产品
         public AbstractProductA createProductA() { 
                 return new ProductA2();
         }
         //只生产产品等级为2的B产品
         public AbstractProductB createProductB() {
                 return new ProductB2();
         }
    }
    
    注意:M个实现工厂类,在每个实现工厂中,实现不同产品族的生产任务。

    场景类如下:

    public class Client {
         public static void main(String[] args) {
                 //定义出两个工厂
                 Abstract Creator creator1 = new Creator1();
                 Abstract Creator creator2 = new Creator2();
                 //产生A1对象
                 AbstractProductA a1 =  creator1.createProductA();
                 //产生A2对象
                 AbstractProductA a2 = creator2.createProductA();
                 //产生B1对象
                 AbstractProductB b1 = creator1.createProductB();
                 //产生B2对象
                 AbstractProductB b2 = creator2.createProductB();
                 /*
                  * 然后在这里就可以为所欲为了...
                  */
         }
    }
    


    抽象工厂模式的优点:

    ● 封装性。

             每个产品的实现类不是高层模块要关心的,它要关心的是什么?是接口,是抽象,它不关心对象是如何创建出

    来,这由谁负责呢?工厂类,只要知道工厂类是谁,我就能创建出一个需要的对象,省时省力,优秀设计就应该如

    此。


    ● 产品族内的约束为非公开状态。


    缺点:
           抽象工厂模式的最大缺点就是产品族扩展非常困难,为什么这么说呢?我们以通用代码为例,如果要增加一个产

    品C,也就是说产品家族由原来的2个增加到3个,看看我们的程序有多大改动吧!抽象类AbstractCreator要增加一个

    方法createProductC(),然后两个实现类都要修改,想想看,这严重违反了开闭原则,而且我们一直说明抽象类和接

    口是一个契约。改变契约,所有与契约有关系的代码都要修改,那么这段代码叫什么?叫“有毒代码”,——只要与这

    段代码有关系,就可能产生侵害的危险!



    两种设计模式的区别:

            区别在于产品,如果产品单一,最合适用工厂模式,但是如果有多个业务品种、业务分类时,通过抽象工

    厂模式产生需要的对象是一种非常好的解决方式。再通俗深化理解下:工厂模式针对的是一个产品等级结构 ,

    抽象工厂模式针对的是面向多个产品等级结构的。


    工厂方法模式与抽象工厂模式对比:

    工厂方法模式

    抽象工厂模式

    针对的是一个产品等级结构针对的是面向多个产品等级结构
    一个抽象产品类多个抽象产品类
    可以派生出多个具体产品类每个抽象产品类可以派生出多个具体产品类
    一个抽象工厂类,可以派生出多个具体工厂类一个抽象工厂类,可以派生出多个具体工厂类
    每个具体工厂类只能创建一个具体产品类的实例每个具体工厂类可以创建多个具体产品类的实例


    如果对你有帮助,记得点赞哦~大笑



  • 相关阅读:
    问题:plugin with id 'android' not found
    问题:plugin with id 'android' not found
    【NYOJ】[122]Triangular Sums
    【NYOJ】[122]Triangular Sums
    【NYOJ】[113]字符串替换
    【NYOJ】[113]字符串替换
    【NYOJ】[111]分数加减法
    【NYOJ】[111]分数加减法
    【NYOJ】[101]两点距离
    【NYOJ】[101]两点距离
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6467273.html
Copyright © 2020-2023  润新知