Abstract Factory 抽象工厂(创建型模式)
new 的问题
常规的对象创建方法: Road road = new Road();
-- 实现依赖,不能应对“具体实例化类型”的变化。
解决思路:
-- 封装变化点--哪里变化,封装哪里
-- 潜台词:如果没有变化,当然不需要额外的封装
工厂模式的缘起
·变化点在"对象创建",因此就封装"对象创建"
·面向接口编程--依赖接口,而非依赖实现
·最简单的解决方法:
创建一系列相互依赖的对象
假设一个游戏开发场景:
我们需要构造"道路","房屋","地道","丛林"....
从一个对象工厂到一组有关系的对象工厂:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
static void Main(string[] args)
{
Road road = RoadFactory.CreateRoad();
...
Building building = RoadFactory.CreateBuilding();
}
//==============上面的客户程序相对稳定,下面为变化点================
class RoadFactory
{
public static Road CreateRoad() //把Road创建成抽象类
{
return new Road(); //这里返回具体的实例,如WaterRoad,DryRoad
}
public static Road CreateBuilding()
{
return new Building();
}
public static Road CreateTunnel()
{
return new Tunnel();
}
...
}
{
Road road = RoadFactory.CreateRoad();
...
Building building = RoadFactory.CreateBuilding();
}
//==============上面的客户程序相对稳定,下面为变化点================
class RoadFactory
{
public static Road CreateRoad() //把Road创建成抽象类
{
return new Road(); //这里返回具体的实例,如WaterRoad,DryRoad
}
public static Road CreateBuilding()
{
return new Building();
}
public static Road CreateTunnel()
{
return new Tunnel();
}
...
}
静态简单工厂的问题:不能应对"不同系列对象"的变化。比如有不同风格的游戏场景---对应不同风格的道路、房屋、地道...,场景不一样时要一个个去改new 的对象
解决:使用面向对象的技术来"封装"变化点
动机(Motivation)
在软件系统中,经常面临着"一系列相互依赖的对象"的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种"封装机制"来避免客户程序和这种"多系列具体对象创建工作"的紧耦合?
意图(Intent)
提供一个接口,让接口负责创建一系列"相关或者相互依赖的对象",无需指定它们具体的类。 ---《设计模式》GoF
结构:
![](https://images.cnblogs.com/cnblogs_com/jonniexie/%E8%B4%B4%E5%9B%BE%E7%9B%B8%E5%86%8C/%E6%A8%A1%E5%BC%8F_3.1.jpg)
客户程序不需要更改,只需要换一个Dll,整个风格即可变化
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
abstract class Road{} //道路
abstract class Building{} //房屋
abstract class Tunnel{} //隧道
abstract class FacilitiesFactory //类工厂
{
public abstract Road CreateRoad();
public abstract Building CreateBuilding();
public abstract Tunnel CreateTunnel();
}
class GameManager
{
//FacilitiesFactory, 实例化的一个场景
FacilitiesFactory facilitiesFactory;
public GameManager(FacilitiesFactory facilitiesFactory)
{
this.facilitiesFactory = facilitiesFactory; //场景传入
}
Road road;
Building build;
Tunnel tunnel;
public void BuildGameFacilities()
{
road = facilitiesFactory.CreateRoad();
build = facilitiesFactory.CreateBuilding();
tunnel = facilitiesFactory.CreateTunnel();
}
public void Run()
{
//Playing Game
}
}
//需要改变的就是传入的facilitiesFactory;
static void Main(string[] args)
{
GameManager gm = new GameManager(new ModernFacilitiesFactory()); //实现一个现代场景,如果要实现其他常见改这就可以了
gm.BuildGameFacilities();
gm.Run();
}
class ModernRoad : Road { } //现代道路
class ModernBuilding : Building { } //现代房屋
class ModernTunnel : Tunnel{ } //现代隧道
class ModernFacilitiesFactory : FacilitiesFactory //现代类工厂
{
public override Road CreateRoad()
{
return new ModernRoad();
}
public override Building CreateBuilding()
{
return new ModernBuilding();
}
public override Tunnel CreateTunnel()
{
return new ModernTunnel();
}
}
Abstract Factory模式的几个要点
·如果没有应对"多系列对象构建"的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的静态工厂完全可以
·"系列对象"指的是这些对象之间有相互依赖、或作用的关系,例如游戏开发场景中的"道路"与"房屋"的依赖,"道路"与"地道"的依赖。
·Abstract Factory模式组要在于应对"新系列"的需求变动。其缺点在于难以应付"新对象"的需求变动。
·Abstract Factory 模式经常和Factory Method模式共同组合来"应对"对象创建"的需求变化