一、抽象工厂的应用场景以及优缺点
1 应用场景:
如果系统需要多套的代码解决方案,并且每套的代码解决方案中又有很多相互关联的产品类型,并且在系统中我们可以相互替换的使用一套产品的时候可以使用该模式,客户端不需要依赖具体的实现。
2 优点:
抽象工厂模式将产品的创建工作迟到了具体工厂的子类中,我们声明工厂类变量的时候是使用的抽象类型,同理,我们使用产品类型也是抽象类型。
这样做就尽可能的减少了客户端代码与产品类之间的依赖,从而降低了系统的耦合度。耦合度降低了,对于后期的维护和扩展就更加的有利。
3 缺点:
抽象工厂模式很难支持增加新产品的变化,这是因为抽象工厂接口中已经明确了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,
这样就涉及到抽象工厂类的以及所有子类的变化。也就违背了“开放--封闭”原则。
4.实现要点:
1)、如果没有应对“多系列对象创建”的需求变化,则没有必要使用AbstractFactory模式,这时候使用简单的静态工厂完全可以。
2)、"系列对象"指的是这些对象之间有相互依赖、或作用的关系,例如游戏开发场景中“道路”与“房屋”的依赖,“道路”与“地道”的依赖。
3)、AbstractFactory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。
4)、AbstractFactory模式经常和FactoryMethod模式共同组合来应对“对象创建”的需求变化。
二、模式的组成
1 抽象产品类角色(AbstractProduct):
为抽象工厂中相互依赖的每种产品定义抽象接口对象,
也可以这样说,有几种产品,就要声明几个抽象角色, 每一个抽象角色和一种具体的产品相匹配。
2 具体产品类(ConcreteProduct):
具体产品类实现了抽象产品类,是针对某个具体产品的实现的类型。
3 抽象工厂类角色(AbstractFactory):
定义了创建一组相互依赖的产品对象的接口操作,每种操作和每种产品一一对应。
4 具体工厂类角色(ConcreteFactory):
实现抽象类里面的所有抽象接口操作,可以创建某系列具体的产品,这些具体的产品是“抽象产品类角色”的子类。
三、代码
1.基本代码:
#region 创建抽象类
/// <summary>
/// 房顶抽象类,子类的房顶必须继承该类
/// </summary>
public abstract class Roof
{
/// <summary>
/// 创建房顶
/// </summary>
public abstract void Create();
}
/// <summary>
/// 地板抽象类,子类的地板必须继承该类
/// </summary>
public abstract class Floor
{
/// <summary>
/// 创建地板
/// </summary>
public abstract void Create();
}
/// <summary>
/// 窗户抽象类,子类的窗户必须继承该类
/// </summary>
public abstract class Window
{
/// <summary>
/// 创建窗户
/// </summary>
public abstract void Create();
}
/// <summary>
/// 房门抽象类,子类的房门必须继承该类
/// </summary>
public abstract class Door
{
/// <summary>
/// 创建房门
/// </summary>
public abstract void Create();
}
/// <summary>
/// 桌子抽象类,子类的房门必须继承该类
/// </summary>
public abstract class Dask
{
/// <summary>
/// 创建桌子
/// </summary>
public abstract void Create();
}
#endregion 创建抽象类
#region 实现具体类
/// <summary>
/// 欧式地板类
/// </summary>
public class EuropeanFloor : Floor
{
public override void Create()
{
Console.WriteLine("创建欧式的地板");
}
}
/// <summary>
/// 欧式的房顶
/// </summary>
public class EuropeanRoof : Roof
{
public override void Create()
{
Console.WriteLine("创建欧式的房顶");
}
}
/// <summary>
///欧式的窗户
/// </summary>
public class EuropeanWindow : Window
{
public override void Create()
{
Console.WriteLine("创建欧式的窗户");
}
}
/// <summary>
/// 欧式的房门
/// </summary>
public class EuropeanDoor : Door
{
public override void Create()
{
Console.WriteLine("创建欧式的房门");
}
}
/// <summary>
/// 欧式桌子类
/// </summary>
public class EuropeanDask : Dask
{
public override void Create()
{
Console.WriteLine("创建欧式的桌子");
}
}
/// <summary>
/// 现代的房顶
/// </summary>
public class ModernizationRoof : Roof
{
public override void Create()
{
Console.WriteLine("创建现代的房顶");
}
}
/// <summary>
/// 现代的地板
/// </summary>
public class ModernizationFloor : Floor
{
public override void Create()
{
Console.WriteLine("创建现代的地板");
}
}
/// <summary>
/// 现代的窗户
/// </summary>
public class ModernizationWindow : Window
{
public override void Create()
{
Console.WriteLine("创建现代的窗户");
}
}
/// <summary>
/// 现代的房门
/// </summary>
public class ModernizationDoor : Door
{
public override void Create()
{
Console.WriteLine("创建现代的房门");
}
}
/// <summary>
/// 现代的桌子(扩展)
/// </summary>
public class ModernizationDask : Dask
{
public override void Create()
{
Console.WriteLine("创建现代的桌子");
}
}
#endregion 实现具体类
#region 创建抽象工厂类
/// <summary>
/// 抽象工厂类,提供创建不同类型房子的接口
/// </summary>
public abstract class AbstractFactory
{
// 抽象工厂提供创建一系列产品的接口,这里作为例子,只给出了房顶、地板、窗户和房门创建接口
public abstract Roof CreateRoof(); //(可多可单)
public abstract Floor CreateFloor();
public abstract Window CreateWindow();
public abstract Door CreateDoor();
public abstract Dask CreateDask();//(扩展)
}
#endregion
#region 实现抽象工厂类
/// <summary>
/// 欧式风格房子的工厂,负责创建欧式风格的房子
/// </summary>
public class EuropeanFactory : AbstractFactory
{
// 制作欧式房顶
public override Roof CreateRoof()
{
return new EuropeanRoof();
}
// 制作欧式地板
public override Floor CreateFloor()
{
return new EuropeanFloor();
}
// 制作欧式窗户
public override Window CreateWindow()
{
return new EuropeanWindow();
}
// 制作欧式房门
public override Door CreateDoor()
{
return new EuropeanDoor();
}
// 制作欧式桌子(扩展)
public override Dask CreateDask()
{
return new EuropeanDask();
}
}
/// <summary>
/// 现在风格房子的工厂,负责创建现代风格的房子
/// </summary>
public class ModernizationFactory : AbstractFactory
{
// 制作现代房顶
public override Roof CreateRoof()
{
return new ModernizationRoof();
}
// 制作现代地板
public override Floor CreateFloor()
{
return new ModernizationFloor();
}
// 制作现代窗户
public override Window CreateWindow()
{
return new ModernizationWindow();
}
// 制作现代房门
public override Door CreateDoor()
{
return new ModernizationDoor();
}
// 制作现代桌子只有现代有)
public override Dask CreateDask()
{
return new ModernizationDask();
}
}
#endregion
2.扩展代码:
新建一套古典风格的房子:
/// <summary>
///先为表弟的房子来建立一个工厂类吧
/// </summary>
public class ClassicalFactory : AbstractFactory
{
//创建房顶
public override Roof CreateRoof()
{
return new ClassicalRoof();
}
// 创建地板
public override Floor CreateFloor()
{
return new ClassicalFloor();
}
// 创建窗户
public override Window CreateWindow()
{
return new ClassicalWindow();
}
// 创建房门
public override Door CreateDoor()
{
return new ClassicalDoor();
}
}
/// <summary>
///古典的房顶
/// </summary>
public class ClassicalRoof : Roof
{
public override void Create()
{
Console.WriteLine("创建古典的房顶");
}
}
/// <summary>
/// 古典的地板
/// </summary>
public class ClassicalFloor : Floor
{
public override void Create()
{
Console.WriteLine("创建古典的地板");
}
}
/// <summary>
/// 古典的窗户
/// </summary>
public class ClassicalWindow : Window
{
public override void Create()
{
Console.WriteLine("创建古典的窗户");
}
}
/// <summary>
/// 古典的房门
/// </summary>
public class ClassicalDoor: Door
{
public override void Create()
{
Console.WriteLine("创建古典的房门");
}
}
此时,只需要添加五个类:一个是古典风格工厂类,负责创建古典风格的房子,另外几个类是具有古典风格的房顶、地板、窗户和房门的具体产品。
从上面代码看出,抽象工厂对于系列产品的变化支持 “开放——封闭”原则(指的是要求系统对扩展开放,对修改封 闭),扩展起来非常简便,
但是,抽象工厂对于增加新产品这种情况就不支持”开放——封闭 “原则,因为要修改创建系列产品的抽象基类 AbstractFactory,增加相应产品的创建方法,这也是抽象工厂的缺点所在。
说明:此文章纯属个人笔记,加深记忆,希望以后能写出自己的作品。