设计模式(3)抽象工厂模式(Abstract Factory)
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、易于产品族切换
一个具体抽象工厂的实现其实就是代表一个产品族,客户端通过参数选用不同的工厂实现,就可以在不同的产品创建中进行切换。
抽象工厂模式的缺点也显而易见,那就是扩展新产品的过程会比较麻烦,比如一个产品族中包含的产品发生了变化,比如增加或减少部件,就需要修改抽象工厂,同时需要修改所有的抽象工厂实现类。
设计模式(3)抽象工厂模式(Abstract Factory)的更多相关文章
- 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)
原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...
- 【设计模式】抽象工厂模式 Abstract Factory Pattern
简单工厂模式是一个工厂类根据工厂方法的参数创建不出不同的产品, 工厂方法模式是每一个产品都有一个一一对应的工厂负责创建该产品.那么今天要讲的抽象工厂模式是一个工厂能够产生关联的一系列产品.抽象工厂模式 ...
- 二十四种设计模式:抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式(Abstract Factory Pattern) 介绍提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 示例有Message和MessageModel,Messag ...
- 【UE4 设计模式】抽象工厂模式 Abstract Factory Pattern
概述 描述 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类:具体的工厂负责实现具体的产品实例 抽象工厂中每个工厂可以创建多种产品(如苹果公司生产iPhone.iPad): 工厂方法 ...
- 设计模式之抽象工厂模式(Abstract Factory Pattern)
一.抽象工厂模式的由来 抽象工厂模式,最开始是为了解决操作系统按钮和窗体风格,而产生的一种设计模式.例如:在windows系统中,我们要用windows设定的按钮和窗体,当我们切换Linux系统时,要 ...
- 设计模式 笔记 抽象工厂模式 Abstract Factory
//---------------------------15/04/09---------------------------- //Abstract Factory 抽象工厂----对象创建型模式 ...
- .NET设计模式(2):1.2 抽象工厂模式(Abstract Factory)
概述 抽象工厂模式(Abstract Factory)是所有形态的工厂模式中最为抽象和最具一般性的一种形态.抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式.抽象工厂模式可以向客户端提供一个接口 ...
- 设计模式 - 抽象工厂模式(abstract factory pattern) 具体解释
抽象工厂模式(abstract factory pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/2709 ...
- 抽象工厂模式(Abstract Factory)C#实例
抽象工厂模式(Abstract Factory)C#实例 本文出处http://www.dofactory.com/net/abstract-factory-design-pattern 一.场景描述 ...
- 浅谈C++设计模式之抽象工厂(Abstract Factory)
抽象工厂(Abstract Factory)模式是为了提供一系列相关或相互依赖对象的接口.对象创建型模式的一种. 客户Client 抽象工厂接口AbstractFactory 抽象工厂的实现类Conc ...
随机推荐
- Coursera 机器学习笔记(一)
主要是第一二周内容 机器学习概要 机器学习是什么? 生活在信息时代的我们,其实时时刻刻都离不开机器学习算法.比如日常使用的搜索引擎就涉及到很多学习算法. Arthur Samuel 给出第一个定义.他 ...
- 16.3Sum Closet
思路: 暴力,复杂度为 \(O(n^3)\),超时 class Solution { public: int threeSumClosest(vector<int>& nums, ...
- java基础(八章)
一. 什么是数组及其作用? 定义:具有相同数据类型的一个集合 作用:存储连续的具有相同类型的数据 二. java中如何声明和定义数组 l 声明和定义的语法: 数据类型[ ...
- 每篇半小时1天入门MongoDB——3.MongoDB可视化及shell详解
本篇主要介绍MongoDB可视化操作以及shell使用及命令,备份恢复.数据导入导出. MongoVUE安装和简单使用 使用mongo.exe 管理数据库虽然可行,功能也挺强大,但每次都要敲命令,即繁 ...
- WAF指纹探测及识别技术
Web应用防护系统(也称:网站应用级入侵防御系统.英文:Web Application Firewall,简称: WAF).利用国际上公认的一种说法:Web应用防火墙是通过执行一系列针对HTTP/HT ...
- C语言和go语言之间的交互
一.go代码中使用C代码 go代码中使用C代码,在go语言的函数块中,以注释的方式写入C代码,然后紧跟import "C" 即可在go代码中使用C函数 代码示例: go代码:tes ...
- Replication-删除发布备注
1.删除replication,先删除replication的作业,再删除对应的订阅,再删除发布: 2.相关脚本:删除监视器里不存在的条目sp_removedistpublisherdbreplica ...
- AngularJS高级程序设计读书笔记 -- 大纲篇
零. 初衷 现在 AngularJS 4 已经发布了, 楼主还停留在 1.x 的阶段, 深感自卑. 学习 AngularJS 的初衷是因为, 去年楼主开始尝试使用 Flask 开发自动化程序, 需要用 ...
- Thinkphp中的内置标签用法
Thinkphp中的内置标签有:Volist,Foreach,For,Switch,比较标签,范围判断标签,IF,Present,Empty,Defined,Assign,Define,标签嵌套,im ...
- Blockly编程:用Scratch制作游戏愤怒的小牛(小鸟)
愤怒的小鸟曾经很热门,网上还说他是程序员最喜欢玩的游戏.最先我是WIKIOI的评测页面看到他的,后来在2014年全国信息学奥林匹克联赛第一天第三题飞扬的小鸟也看到了它.因此,突然想做一个类似愤怒的小鸟 ...