设计模式(3)抽象工厂模式(Abstract Factory)

设计模式(0)简单工厂模式

设计模式(1)单例模式(Singleton)

设计模式(2)工厂方法模式(Factory Method)

源码地址

0 抽象工厂模式简介

0.0 抽象工厂模式定义

抽象工厂模式一般的书面定义为:提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类

提供创建接口,无需指定具体实现类,这个原则在简单工厂模式和工厂方法模式篇已经反复讲到了,这是面向接口编程的一个基本准则,很显然,从抽象工厂模式的一般定义中可以看出这也是抽象工厂模式的一个核心,而抽象工厂模式的另一个核心是要解决一系列相关或相依赖对象(产品族)创建的问题。这也是这几种工厂模式的细节区别所在的关键点所在,初学设计模式时往往因为没有认识到这一点区别而对几种工厂模式难以理解

我们可以简单的这么理解,抽象工厂模式不单单要解决对象的创建问题,还要涉及到创建的对象之间的相互依赖或者约束关系。工厂方法模式和简单工厂模式解决了单个产品对象创建的问题,它们只关心单个产品对象的创建,而抽象工厂模式是关注的产品族(多个相互关联对象)的创建,最终创建的产品族形成一个新的产品对象。

抽象工厂模式的结构图如下:

AbstractFactory:抽象工厂类,定义创建某个产品所需相关对象的操作接口

ProductFactory1/ProductFactory2:具体的工厂类,实现抽象工厂定义的方法,负责某个产品所需所有对象创建操作接口的具体实现。

AbstractProductA/AbstractProductB:定义某一类产品对象的接口

ProductA1/ProductA2/ProductB1/ProductB2:具体产品对象的实现

0.1 抽象工厂模式应用场景

如果对上面的文字描述还不能有一个直观的认识,我们仍然从一个简单的应用场景来说明抽象工厂模式的引入时机。

野外商店老板为了更好的服务众英雄,特将店内隐身药水进行了一次升级,分为红瓶装(瓶口直径2cm)、蓝瓶装(瓶口直径5cm)2款,并且2种瓶子分别搭配圆形(2cm)和方形(5cm)两种款式的瓶盖。英雄们来到商店后,只需要将自己的的需要告诉商店老板,老板根据英雄的要求,去取瓶子和盖子进行组装即可。

在应用抽象工厂模式之前,我们很简单的使用简单工厂模式实现这个需求。

定义瓶子接口及实现类

/// <summary>
/// 定义瓶子接口
/// </summary>
public interface IBottle
{
    /// <summary>
    /// 展示自己的信息
    /// </summary>
    void ShowInfo();
}
/// <summary>
/// 红色瓶子
/// </summary>
public class RedBottle : IBottle
{
    /// <summary>
    /// 展示自己的信息
    /// </summary>
    public void ShowInfo()
    {
        Console.WriteLine("我是一个热情火辣的红色瓶子,我的瓶口直径是2cm。");
    }
}

定义瓶盖接口及实现类

/// <summary>
/// 定义瓶盖接口
/// </summary>
public interface ICap
{
    /// <summary>
    /// 展示自己的信息
    /// </summary>
    void ShowInfo();
}
/// <summary>
/// 圆形瓶盖
/// </summary>
public class RoundCap : ICap
{
    /// <summary>
    /// 展示自己的信息
    /// </summary>
    public void ShowInfo()
    {
        Console.WriteLine("我是一个圆形瓶盖,我的直径是2cm。");
    }
}
/// <summary>
/// 方形瓶子
/// </summary>
public class SquareCap : ICap
{
    /// <summary>
    /// 展示自己的信息
    /// </summary>
    public void ShowInfo()
    {
        Console.WriteLine("我是一个方形瓶盖,我的直径是5cm。");
    }
}

定义创建瓶子和瓶盖的简单工厂

/// <summary>
/// 瓶子创建工厂方法
/// </summary>
public class BottleFactory
{
    /// <summary>
    /// 创建瓶子对象
    /// </summary>
    /// <param name="color">瓶子颜色</param>
    /// <returns></returns>
    public static IBottle CreateBottle(string color)
    {
        if (color == "red")
            return new RedBottle();
        if (color == "blue")
            return new BlueBottle();
        return null;
    }
}
/// <summary>
/// 瓶盖创建工厂方法
/// </summary>
public class CapFactory
{
    /// <summary>
    /// 创建瓶子对象
    /// </summary>
    /// <param name="shape">瓶盖形状</param>
    /// <returns></returns>
    public static ICap CreateCap(string shape)
    {
        if (shape == "round")
            return new RoundCap();
        if (shape == "square")
            return new SquareCap();
        return null;
    }
}

最终成品组装类定义

/// <summary>
/// 隐形药水组装者
/// </summary>
public class ProductMaker
{
    private IBottle _bottle; // 瓶子对象
    private ICap _cap; // 瓶盖对象

    /// <summary>
    /// 创建最终药水对象
    /// </summary>
    /// <param name="bottleColor"></param>
    /// <param name="capShape"></param>
    public void MakeProduct(string bottleColor, string capShape)
    {
        _bottle = BottleFactory.CreateBottle(bottleColor);
        _cap = CapFactory.CreateCap(capShape);
        Console.WriteLine("准备英雄需要的瓶子和瓶盖。");
        _bottle.ShowInfo();
        _cap.ShowInfo();
        Console.WriteLine("开始往瓶子了灌入隐形药水,然后封上瓶盖。");
    }
}

客户端调用

static void Main(string[] args)
{
    ProductMaker pm = new ProductMaker();
    pm.MakeProduct("red", "round"); // 提供给英雄红瓶子圆盖子的隐形药水
    Console.WriteLine();
    pm.MakeProduct("blue", "square"); // 提供给英雄蓝瓶子方盖子的隐形药水
    Console.ReadLine();
}

这样,我们通过接口进行隔离,解决了不同瓶子,不同盖子创建时,客户端无需关心具体创建过程,只需要告诉工厂需要何种类型的对象即可。但同时会暴露一个很明显的问题就是,我们创建的瓶子和瓶盖2个对象并不是孤立存在的,2个对象之间是有明显的相互关系的,那就是平口尺寸必须和瓶盖尺寸保持一直,否则就会让店老板出现灌装好药水却拧不上盖子的尴尬。此时应该会对上面提到的抽象工厂的定义有进一步的理解,也在这种场景下,是我们必须要引入抽象工厂模式的时候了。

1 抽象工厂模式详解

0、提炼抽象工厂类

根据抽象工厂方法的结构图,我们首先定义个一个抽象工厂类,该抽象工厂定义瓶子和瓶盖2个对象的创建接口。

/// <summary>
/// 抽象工厂类
/// </summary>
public abstract class AbstractFactory
{
    /// <summary>
    /// 创建瓶子
    /// </summary>
    /// <returns></returns>
    public abstract IBottle CreateBottle();

    /// <summary>
    /// 创建瓶盖
    /// </summary>
    /// <returns></returns>
    public abstract ICap CreateCap();
}

1、抽象工厂的具体实现

分析产品的组合情况,实际上只存在2种类型的最终产品,红瓶子圆盖子和蓝瓶子方盖子,我们分别定义2个抽象工厂的具体实现类

/// <summary>
/// 红瓶子圆盖子工厂类
/// </summary>
public class RedBottleAndRoundCapFactory : AbstractFactory
{
    /// <summary>
    /// 创建瓶子
    /// </summary>
    /// <returns></returns>
    public override IBottle CreateBottle()
    {
        return BottleFactory.CreateBottle("red");
    }

    /// <summary>
    /// 创建瓶盖
    /// </summary>
    /// <returns></returns>
    public override ICap CreateCap()
    {
        return CapFactory.CreateCap("round");
    }
}
/// <summary>
/// 蓝瓶子方盖子工厂类
/// </summary>
public class BlueBottleAndSquareCapFactory : AbstractFactory
{
    /// <summary>
    /// 创建瓶子
    /// </summary>
    /// <returns></returns>
    public override IBottle CreateBottle()
    {
        return BottleFactory.CreateBottle("blue");
    }

    /// <summary>
    /// 创建瓶盖
    /// </summary>
    /// <returns></returns>
    public override ICap CreateCap()
    {
        return CapFactory.CreateCap("square");
    }
}

2、最终产品组装类的修改实现

跟原来的实现相比较,最终产品组装类不在从客户端传入瓶子、瓶盖的参数通过对应的工厂方法创建,而是直接传入已经定义好的瓶子瓶盖组装工厂类对象,能够做到瓶子瓶盖必须配套创建。

/// <summary>
/// 创建最终药水对象
/// </summary>
/// <param name="factory">抽象工厂具体对象</param>
public void MakeProduct(AbstractFactory factory)
{
    _bottle = factory.CreateBottle();
    _cap = factory.CreateCap();
    Console.WriteLine("准备英雄需要的瓶子和瓶盖。");
    _bottle.ShowInfo();
    _cap.ShowInfo();
    Console.WriteLine("开始往瓶子了灌入隐形药水,然后封上瓶盖。");
}

3、客户端调用

ProductMaker pm = new ProductMaker();
AbstractFactory factory = new RedBottleAndRoundCapFactory(); // 提供给英雄红瓶子圆盖子的隐形药水
pm.MakeProduct(factory);
Console.WriteLine();
factory = new BlueBottleAndSquareCapFactory(); // 提供给英雄蓝瓶子方盖子的隐形药水
pm.MakeProduct(factory);
Console.ReadLine();

2 总结

通过创建的多个对象之间的关联关系阐述了抽象工厂模式与其他工厂模式的区别以及使用时机。基于上面的示例,我们可以总结出抽象工厂模式的具有以下优点:

0、分离接口和实现

客户端使用抽象工厂方法来创建需要的对象,只需要传入抽象方法的,无需关注内部具体实现逻辑,实现接口与具体实现的分离解耦。

1、易于产品族切换

一个具体抽象工厂的实现其实就是代表一个产品族,客户端通过参数选用不同的工厂实现,就可以在不同的产品创建中进行切换。

抽象工厂模式的缺点也显而易见,那就是扩展新产品的过程会比较麻烦,比如一个产品族中包含的产品发生了变化,比如增加或减少部件,就需要修改抽象工厂,同时需要修改所有的抽象工厂实现类。

时间: 2024-08-02 11:04:18

设计模式(3)抽象工厂模式(Abstract Factory)的相关文章

【设计模式】 抽象工厂模式 Abstract Factory Pattern

简单工厂模式是一个工厂类根据工厂方法的参数创建不出不同的产品, 工厂方法模式是每一个产品都有一个一一对应的工厂负责创建该产品.那么今天要讲的抽象工厂模式是一个工厂能够产生关联的一系列产品.抽象工厂模式相对于简单工厂和工厂方法模式来着更具抽象性. 一.抽象工厂模式演绎 我们先来看一个简单的需求: 甲方要开发一套办公自动化软件,其中有一个非常重要的功能就是要能够导入Word 文档和Excel 文档. 开发人员拿到需求后就开始编码了,  很快代码写完了: public class ImportTool

二十四种设计模式:抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式(Abstract Factory Pattern) 介绍提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 示例有Message和MessageModel,Message有一个Insert()方法,该方法的参数是MessageModel. AbstractMessageModel using System; using System.Collections.Generic; using System.Text; namespace Pattern.Abstract

设计模式-04抽象工厂模式(Abstract Factory Pattern)

1.模式动机 在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法.但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象. 为了更清晰地理解工厂方法模式,需要先引入两个概念: 产品等级结构:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机.海信电视机.TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌

设计模式 笔记 抽象工厂模式 Abstract Factory

//---------------------------15/04/09---------------------------- //Abstract Factory 抽象工厂----对象创建型模式 /* 1:意图:提供一个创建一系列相关或相互依赖对象的接口,而无需制定他们具体的类. 2:别名:Kit 3:动机 4:适应性: 1>一个系统要独立于它的产品的创建.组合和表示时. 2>一个系统要由多个产品系列中的一个来配置时. 3>当你要强调一系列相关的产品对象的设计以便进行联合使用时.

设计模式 - 抽象工厂模式(abstract factory pattern) 详解

抽象工厂模式(abstract factory pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27091671 参考工厂模式: http://blog.csdn.net/caroline_wendy/article/details/27081511 抽象工厂模式: 提供一个接口, 用于创建相关或依赖对象的家族, 而不需要明确指定具体类. 全部代码: http://download.csdn.net/de

设计模式 - 抽象工厂模式(abstract factory pattern) 具体解释

抽象工厂模式(abstract factory pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27091671 參考工厂模式: http://blog.csdn.net/caroline_wendy/article/details/27081511 抽象工厂模式: 提供一个接口, 用于创建相关或依赖对象的家族, 而不须要明白指定详细类. 所有代码: http://download.csdn.net/

Android设计模式——抽象工厂模式(Abstract Factory)

二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 1 package com.example.main; 2 3 import android.app.Activity; 4 import

php设计模式——抽象工厂模式(Abstract Factory)

二十三种设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 1 <?php 2 /* 3 * php设计模式——抽象工厂模式(Abstract Factory) 4 */ 5 6 7 /* 8 * I

抽象工厂模式(Abstract Factory)C#实例

抽象工厂模式(Abstract Factory)C#实例 本文出处http://www.dofactory.com/net/abstract-factory-design-pattern 一.场景描述 本实例描述了抽象工厂模式的一个使用场景.在动物世界弱肉强食,食肉动物会吃掉食草动物.这是动物世界的规律,因此在动物世界类中有Runfoodchain(运行食物链)方法.在动物世界里总是有食肉动物和食草动物这两个抽象成员.它们之所以是抽象成员是因为他们不是具体的一种动物.而食草动物与食肉动物的区别在

抽象工厂模式&lt;Abstract Factory&gt;

概述 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类.让子类决定实例化哪一个类 角色 抽象工厂(Creator):这个抽象类(或接口)声明一个创建对象的工厂方法,用来返回一个Product类型的对象. 具体工厂(ConcreteCreator):重定义工厂方法,返回一个具体的Concrete Product实例. 抽象产品(Product):定义工厂方法所创建的对象 具体产品(ConcreteProduct): 具体产品,继承自Product抽象类. 解读 UML图 c#代码