zoukankan      html  css  js  c++  java
  • 【设计模式】抽象工厂模式

    抽象工厂模式

    抽象工厂模式的用意

    抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,创建多个产品族中的产品对象。这就是抽象工厂模式的用意。

    系统的设计

    采用抽象工厂模式设计出的系统类图如下图所示:

    从上图所示,抽象工厂涉及到以下角色:

    • 抽象工厂(AbstractFactory)角色:担任这个角色的是工厂方法模式的核心,它是与应用系统的商业逻辑无关的。通常使用 Java 接口或者抽象 Java 类实现,而所有的具体工厂类必须实现这个 Java 接口或继承这个抽象 Java 类。
    • 具体工厂类(Concrete Factory)角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。通常使用 Java 类实现这个角色。
    • 抽象产品类(Abstract Product)角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。通常使用 Java 接口或者抽象 Java 类实现这一角色。
    • 具体产品类(Concrete Product)角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。通常使用具体 Java 类实现这个角色。

    下面利用相图描述,会看到在相图上出现两个等级结构 A 和 B,以及两个产品族 1 和 2,如下图所示:

    源代码

    抽象产品角色的源代码

    public interface Creator {
        /**
        * 产品等级结构A的工厂方法
        */
        public ProductA factoryA();
        
        /**
        * 产品等级结构B的工厂方法
        */
        public ProductB factoryB();
    }
    

    具体工厂类 ConcreteCreator1 和 ConcreteCreator2 的源代码

    public class ConcreteCreator1 implements Creator {
        
        public ProductA factoryA() {
            return new ProductA1();
        }
        
        public ProductB factoryB() {
            return new ProductB1();
        }
        
    }
    
    public class ConcreteCreator2 implements Creator {
        
        public ProductA factoryA() {
            return new ProductA2();
        }
        
        public ProductB factoryB() {
            return new ProductB2();
        }
        
    }
    

    一般而言,有多少个产品等级结构,就会在工厂角色中发现多少个工厂方法。每一个产品等级结构中有具体产品,就有多少个产品族,也就会在工厂等级结构中发现多少个具体工厂。

    具体产品类 ProductA 的源代码

    客户端需要的是产品,而不是工厂。在真实的系统中,产品类应当与应用系统的商业逻辑有密切关系。下面是产品等级结构 A 的抽象产品角色,在这个示意系统中,这个抽象产品角色是由一个 Java 接口实现的,如下代码所示:

    public interface ProductA {
        
    }
    

    可以看出这个接口也只是一个标识接口,下面展示其具体的实现类

    具体产品类 ProductA1 和 ProductA2 的源代码

    public class ProductA1 implements Product {
        public ProductA1() {
            
        }
    }
    
    public class ProductA2 implements Product {
        public ProductA2() {
            
        }
    }
    

    而在这个演示系统中,产品等级结构B的源代码和A大致相同,略。

    谈一谈优劣:

    优点:

    • 分离接口和实现:
      客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。

    • 使得切换产品族变得容易:因为一个具体的工厂实现代表的是一个产品族,客户端选用不同的工厂实现,就相当是在切换不同的产品族。

    缺点:

    • 不太容易扩展新的产品:
      如果需要给整个产品族添加一个新的产品,那么就需要修改抽象工厂,这一就会导致所有的工厂实现类都需要修改

    • 容易造成类层次复杂

    来源《Java与模式》

  • 相关阅读:
    vs2013常用快捷键收集
    关于cocos2d-x 与 cocos2d-html5 资源预加载的思考
    【转】使用cocos2d-console工具转换脚本为字节码
    多层CCLayer的touch冲突解决
    jsb里出现的 Invalid Native Object的一次bug修复的思考
    win7 通过命令行压缩文件
    消格子时一个很深的bug的修复纪录
    mac自带apache服务器开启
    shell命令:给当前目录里一个文件压缩一份不包含.svn文件的zip包
    shell命令:删除当前.sh文件所在目录下的zip包,并且重新打包
  • 原文地址:https://www.cnblogs.com/jojop/p/11274982.html
Copyright © 2011-2022 走看看