设计模式(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 ...
随机推荐
- Java中4种类型的内部类 .
在Java中有4种不同类型的内部类可以使用.下面给出它们的名称和例子. 1.静态嵌套类(Static Nested Classes) class Outer { static class Inner ...
- BOM中的各种height
BOM中的高度属性主要涉及三块:screen.window.文档下的元素. screen 其中screen最简单,代表着显示器的对象. screen.height :屏幕高度,像素为单位. scree ...
- Linux SSH安全技巧
SSH服务器配置文件是/etc/ssh/sshd_conf.在你对它进行每一次改动后都需要重新启动SSH服务,以便让改动生效. 1.修改SSH监听端口默认情况下,SSH监听连接端口22,攻击者使用端口 ...
- 不完全翻译:Threading in C#-Getting Started
Introduction(引入,介绍) and Concepts(概念) 原文地址:http://www.albahari.com/threading/ 注:水平有限不能全文翻译,备注了个别字段和短句 ...
- python3实现TCP协议的简单服务器和客户端
利用python3来实现TCP协议,和UDP类似.UDP应用于及时通信,而TCP协议用来传送文件.命令等操作,因为这些数据不允许丢失,否则会造成文件错误或命令混乱.下面代码就是模拟客户端通过命令行操作 ...
- 用户权限模块之spring security
准备工作:数据库采用mysql(5.6及以上) CREATE TABLE `auth_system` ( `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'I ...
- asp net core 跨平台初体验
标: 在 ubuntu 16.04 上部署一个 asp.net core 站点,打开网站后显示一段文字. 安装 net core 运行环境:ubuntu 16.04 LTS 1.添加 apt 源 ...
- Linq用法笔记
一.什么是Linq? LINQ即Language Integrated Query(语言集成查询),LINQ是集成到C#和Visual Basic.NET这些语言中用于提供查询数据能力的一个新特性. ...
- 关于MATLAB处理大数据坐标文件2017620
暑假已至,接下来组内成员将会各回各家,各找各妈,这肯定是对本次大数据比赛是很不利的. 接下来我会把任务分配给组员,当然任务会比起初的时候轻一点,因为我认为本次比赛的目的并不是我要求组员做什么,而是我的 ...
- MySQL数据库web维护客户端管理工具
TreeSoft数据库管理系统使用JAVA开发,采用稳定通用的springMVC +JDBC架构,实现基于WEB方式对 MySQL,Oracle,PostgreSQL 等数据库进行维护管理操作. 功能 ...