zoukankan      html  css  js  c++  java
  • 抽象工厂模式

    一、引言

    在软件系统中在动态创建对象基础上,往往由于需求的变化,会存在更多系列对象的创建工作。为此,绕过常规的对象创建(new),提供封装机制来避免客户和这种多系列具体对象的创建工作,紧密合作。这就是抽象工厂模式。
    比如说:工厂模式中每个具体类只完成一个实例的创建,但是现实中一个工厂生产很多产品,而不是单个产品,为了生产一系列产品,便产生了抽象工厂。
    抽象工厂是提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
    模型图:
    物理模型
    情景模拟
    这种模式可以汽车制造厂所使用的金属冲压设备中找到。这种冲压设备可以制造汽车车身部件。同样的机械用于冲压不同的车型的右边车门、左边车门、右前挡泥板、左前挡泥板和引擎罩等等。通过使用转轮来改变冲压盘,这个机械产生的具体类可以在三分钟内改变。
    生活例子
    冲压设备为一个接口,提供系列对象创建的接口,调用接口中函数就完成了对象的创建。

      -

    二、程序设计

    “绝味” 连锁店的例子来实现一个抽象工厂模式。例如,绝味鸭脖想在A和B开分店,但是由于当地人的口味不一样,在A的所有绝味的东西会做的辣一点,而B不喜欢吃辣的,所以B的所有绝味的东西都不会做的像A的那样辣,然而这点不同导致A绝味工厂和B的绝味工厂生成所有绝味的产品都不同,也就是某个具体工厂需要负责一系列产品(指的是绝味所有食物)的创建工作。
    模型图:
    抽象工厂
    代码:

    //产品的抽象接口,以供子类实现
    public abstract class DuckHead
    {
        public abstract void Instruction();
    
    }
    public abstract class DuckBack
    {
        public abstract void Instruction();
    
    }
    
    //下面是四个具体类的实现,分别提供四种产品,满足市场需要
    public class ADuckBack : DuckBack
    {
        public override void Instruction()
        {
            throw new System.NotImplementedException();
        }
    
    }
    
    public class ADuckHead : DuckHead
    {
        public override void Instruction()
        {
            throw new System.NotImplementedException();
        }
    
    }
    //B地方的产品就不写了,关键是工厂中的调用
    //抽象工厂实际上提供一个接口,为面向接口编程,这里关键是将产品和工厂解耦
    public interface IDuckFactory 
    {
        DuckHead CreateDuckHead();
    
       DuckBack CreateDuckBack();
    
    }
    
    public class AStore : IDuckFactory
    {
        public virtual DuckHead CreateDuckHead()
        {
            //实现了接口,返回了A地方的DuckHead
            return new ADuckHead()  ;
        }
    
        public virtual DuckBack CreateDuckBack()
        {
            //实现了接口,返回了A地方的DuckBack
            return new ADuckBack();
        }
    }
    //B店的代码是类似的。
    调用的代码
    
    public class Client
    {
        public static void main(string []args)
        {
            //制作A地方的鸭脖
            IDuckFactory astore = new AStore();
            DuckHead duckhead = astore.CreateDuckHead();
            duckhead.Instruction();
            DuckBack duckback = astore.CreateDuckBack();
            duckback.Instruction();
        }
    }
    View Code

    加入后续需要在C地方再开一家,这样就可以很少改动代码,只需扩展下代码即可。C的产品也是继承DuckHead,DuckBack,然后再加一个CFactory即可。

      -

    三、综述

    • 1、它有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。
    • 2、分离了具体的类。抽象工厂模式帮助你控制一个应用创建的对象的类,因为一个工厂封装创建产品对象的责任和过程。它将客户和类的实现分离,客户通过他们的抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。
    • 3、抽象工厂对于系列产品的变化支持 “开放——封闭”原则(指的是要求系统对扩展开放,对修改封闭),扩展起来非常简便,但是,抽象工厂对于添加新产品这种情况就不支持”开放——封闭 “原则,这也是抽象工厂的缺点所在。
    • 抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。
      适用性:

    • 一个系统不应当依赖于产品类实例如何创建、组合和表达的细节

    • 这个系统有一些列产品,在一个工厂内产生。
    • 系统提供一个产品类,所有的产品以同样接口出现,从而使客户端不依赖与实现。
      其实就是一个接口对一系列工厂提供接口(调用函数,注意返回类型,就是产品)。相似对简单工厂的再次封装。

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    session概述
    Flask实现登录功能【附完整Demo】(转)
    Python __repr__()方法:显示属性(转)
    Python使用SQLAlchemy连接数据库CRUD
    网络基础知识集合
    面向切面编程AOP
    SQL基础 insert table_name_1 (field1,field2,...) select value1,value2,... from table_name_2 ...
    java中char类型的变量为什么可以赋值为整型数字?
    iOS应用生命周期
    视图生命周期与视图控制器生命周期
  • 原文地址:https://www.cnblogs.com/polly333/p/4705676.html
Copyright © 2011-2022 走看看