总目录
前言
工厂方法模式是为了克服简单工厂模式的缺点而设计出来的,简单工厂模式的工厂类随着产品类的增加需要增加额外的代码,而工厂方法模式每个具体工厂类只完成单个实例的创建,所以它具有很好的可扩展性。但是在现实生活中,一个工厂只创建单个产品这样的例子很少,因为现在的工厂都多元化了,一个工厂创建一系列的产品,如果我们要设计这样的系统时,工厂方法模式显然在这里不适用,然后抽象工厂模式却可以很好地解决一系列产品创建的问题。
1 基本介绍
-
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个种类的产品,而抽象工厂模式可生产多个种类的产品。
-
抽象工厂模式的主要角色:
- 抽象工厂
- 在抽象工厂类中声明了多个工厂方法,用于返回多个产品。提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
- 具体产品工厂
- 它是抽象工厂类的子类,实现了在抽象工厂中声明的多个工厂方法,完成多个具体产品的创建。
- 抽象产品
- 它是定义一个产品的接口,定义了一个产品的规范,描述了一个产品的主要特性和功能。抽象工厂模式有多个抽象产品。
- 具体产品
- 实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。
- 抽象工厂
-
抽象工厂允许客户使用抽象的接口来创建一组相关产品,而不需要知道或关心实际生产出的具体产品是什么。这样客户就可以从具体产品中被解耦。
-
抽象工厂模式是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式
2 使用场景
一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提。
- 适用于需要创建多个产品的场景
- 抽象工厂模式一般用于严格要求以面向对象思想进行开发的超大型项目中。
3 实现方式
“绝味” 连锁店的例子来实现一个抽象工厂模式。例如,绝味鸭脖想在江西南昌和上海开分店,但是由于当地人的口味不一样,在南昌的所有绝味的东西会做的辣一点,而上海不喜欢吃辣的,所以上海的所有绝味的东西都不会做的像南昌的那样辣,然而这点不同导致南昌绝味工厂和上海的绝味工厂生成所有绝味的产品都不同,也就是某个具体工厂需要负责一系列产品(指的是绝味所有食物)的创建工作,下面就具体看看如何使用抽象工厂模式来实现这种情况。
//抽象产品
//此处为抽象鸭脖类,供不同地方的鸭脖来继承
public abstract class AbstractYaBo
{
//展示鸭脖相关信息
public abstract void Show();
}
//抽象产品
//此处为抽象鸭舌类,供不同地方的鸭舌来继承
public abstract class AbstractYaShe
{
public abstract void Show();
}
//抽象工厂
//抽象工厂类,提供创建两个鸭架和鸭脖产品的接口
public abstract class AbstractJueWeiFactory
{
// 抽象工厂提供创建一系列产品的接口
// 这里作为例子,只给出了绝味中鸭脖和鸭架的生产接口
public abstract AbstractYaBo MakeYaBo();
public abstract AbstractYaShe MakeYaShe();
}
上面我们定义了两个抽象产品类鸭架和鸭脖,然后定义了一个生产鸭脖和鸭架的抽象工厂类,现在我们需要去上海和江西南昌开分店。
上海分店:
//上海口味的鸭脖
public class ShangHaiYaBo : AbstractYaBo
{
public override void Show()
{
Console.WriteLine("上海绝味鸭脖,没那么辣");
}
}
//上海口味的鸭舌
public class ShangHaiYaShe : AbstractYaShe
{
public override void Show()
{
Console.WriteLine("上海绝味鸭舌,没那么辣");
}
}
//上海绝味工厂 负责生产适合上海人口味的鸭脖和鸭舌
public class ShangHaiJueWeiFactory : AbstractJueWeiFactory
{
//生产上海鸭脖
public override AbstractYaBo MakeYaBo()
{
return new ShangHaiYaBo();
}
//生产上海鸭舌
public override AbstractYaShe MakeYaShe()
{
return new ShangHaiYaShe();
}
}
南昌分店:
public class NanChangYaBo : AbstractYaBo
{
public override void Show()
{
Console.WriteLine("南昌绝味鸭脖,够辣");
}
}
public class NanChangYaShe : AbstractYaShe
{
public override void Show()
{
Console.WriteLine("南昌绝味鸭舌,够辣");
}
}
public class NanChangJueWeiFactory : AbstractJueWeiFactory
{
public override AbstractYaBo MakeYaBo()
{
return new NanChangYaBo();
}
public override AbstractYaShe MakeYaShe()
{
return new NanChangYaShe();
}
}
客户端调用:
// 客户端调用
class Client
{
static void Main(string[] args)
{
// 南昌工厂制作南昌的鸭脖和鸭舌
AbstractJueWeiFactory nanChangFactory = new NanChangJueWeiFactory();
AbstractYaBo nanChangYabo = nanChangFactory.MakeYaBo();
nanChangYabo.Show();
AbstractYaShe nanChangYajia = nanChangFactory.MakeYaShe();
nanChangYajia.Show();
// 上海工厂制作上海的鸭脖和鸭舌
AbstractJueWeiFactory shangHaiFactory = new ShangHaiJueWeiFactory();
shangHaiFactory.MakeYaBo().Show();
shangHaiFactory.MakeYaShe().Show();
Console.Read();
}
}
当绝味需要再在深圳再开一家分店的上海,直接按照南昌分店和上海分店一样再写一套代码就可以了。
4 优缺点分析
-
优点
- 抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展
- 抽象工厂的最大好处在于交换产品系列非常方便,只需要改变具体工厂即可使用不同的产品配置。
- 当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
-
缺点
- 抽象工厂模式很难支持新种类产品的变化。当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。
5 简单工厂,工厂方法,抽象工厂对比
- 简单工厂,工厂方法两种模式都只是针对一类产品,直接生成实例
但是抽象工厂模式不同,抽象工厂模式并不直接生成实例, 而是用于对产品类簇的创建。 - 通俗点来讲就是:简单工厂和工厂方法模式的工作是生产产品,那么抽象工厂模式的工作就是生产工厂的。
简单工厂把全部的事情,在一个地方(类)全部处理完,
而工厂方法却不同,其是通过创建一个框架,然后让子类决定要如何实现。
而抽象工厂则是定义一个负责创建一组产品(也就是一个产品簇)的接口
结语
希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。