设计模式Abstract FactoryCreational标签03标签04标签05
C#03:(创建型模式)Abstract Factory 抽象工厂模式.pdf
说明:
- 工厂模式
- 创建型模式
视频
New的问题
-
解决思路
封装变化点——-哪里变化,封装哪里
-
缘起
变化点在“对象创建”,因此就封装“对象创建”;
- 面向接口编程—依赖接口,而非依赖实现;
最简单的解决办法:
示例场景:假如需要创建一条公路! ```csharp class RoadFactory //类库 { public static Road CreateRoad() {
} }return new Road(); //返回return new WaterRoad();
//创建一个Road对象 Road road=roadFactory.CreateRoad(); //客户程序
<a name="e3FTX"></a>
# 创建一系列相互依赖对象的创建工作:
1. 示例场景:
不能应对“不同系列对象”的变化。比如有不同风格的游戏场景---对应不同风格的道路,房屋,地道等
2. 如何解决?
使用面向对象的技术来“封装”变化点
<a name="o3oB4"></a>
# 工厂方法如下:
1. 示例场景:假设一个游戏开发场景:我们需要构造“道路”,“房屋”,“地道”,“丛林”......等等对象
```csharp
class RoadFactory
{
public static Road CreateRoad()
{
return new Road();
}
public static Building CreateBuilding()
{
return new Building();
}
public static Tunnel CreateTunnel()
{
return new Tunnel();
}
public static Jungle CreateJungle()
{
return new Jungle();
}
}
调用方法如下:
Road road = RoadFactory.CreateRoad();
Building building = RoadFactory.CreateBuilding();
Tunnel tunnel = RoadFactory.CreateTunnel();
Jungle jungle = RoadFactory.CreateJungle();
如上可见简单工厂的问题:
不能应对”不同系列对象”的变化。比如有不同风格的场景—-对应不同风格的道路,房屋、地道….
如何解决?
动机 —Motivation
在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作,同时,由于需求的变化,存在更多系列对象的创建工作。
如何应对这种变化呢?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合呢?
意图 —Intent
提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。 ——《设计模式》GOF
结构 —Structure
适用性
- 一个系统要独立于它的产品的创建、组合和表示时。
- 一个系统要由多个产品系统中的一个来配置时。
- 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
- 当你提供一个产品类库,而只想显示它们的接口不是实现时。
生活中的例子
要点
- 如果没有应对“多系列对象构建”的需求变化,则没有必要使用AbstractFactory模式,这时候使用简单的静态工厂完全可以。
- “系列对象”指的是这些对象之间有相互依赖或作用的关系,例如游戏开发场景中的“道路”与“房屋”的依赖,“道路”与“地道”的依赖。
- Abstract Factory模式主要在于对“新系类”的需求变动。其缺点在于难以应对“新对象”的需求变动。
- Abstract Factory 模式经常和Factory Method模式共同组合来应对“对象创建”的需求变化。
源代码
```csharp using System; using System.Collections.Generic; using System.Text;
namespace No02_AbstractFactory.AbstractFactoyGame { ///
/// <summary>
/// 建筑屋
/// </summary>
public abstract class Building
{
}
/// <summary>
/// 隧道
/// </summary>
public abstract class Tunnel
{
}
/// <summary>
/// 丛林
/// </summary>
public abstract class Jungle
{
}
/// <summary>
/// 设施
/// </summary>
public abstract class FacilitiesFactory
{
public abstract Road CreateRoad();
public abstract Building CreateBuilding();
public abstract Tunnel CreateTunnel();
public abstract Jungle CreateJungle();
}
}
```csharp
using No02_AbstractFactory.AbstractFactoyGame;
namespace No02_AbstractFactory.ModernStyleGame
{
class ModernObjects
{
/// <summary>
/// 道路
/// </summary>
public class ModernRoad : Road
{
}
/// <summary>
/// 建筑屋
/// </summary>
public class ModernBuilding : Building
{
}
/// <summary>
/// 隧道
/// </summary>
public class ModernTunnel : Tunnel
{
}
/// <summary>
/// 丛林
/// </summary>
public class ModernJungle : Jungle
{
}
/// <summary>
/// 设施
/// </summary>
public class ModernFacilitiesFactory : FacilitiesFactory
{
public override Road CreateRoad()
{
return new ModernRoad();
}
public override Building CreateBuilding()
{
return new ModernBuilding();
}
public override Tunnel CreateTunnel()
{
return new ModernTunnel();
}
public override Jungle CreateJungle()
{
return new ModernJungle();
}
}
}
}
using No02_AbstractFactory.AbstractFactoyGame;
namespace No02_AbstractFactory.NoChangePart
{
public class GameManager
{
private FacilitiesFactory facilitiesFactory;
private Road road;
private Building building;
private Tunnel tunnel;
private Jungle jungle;
public GameManager(FacilitiesFactory facilitiesFactory)
{
this.facilitiesFactory = facilitiesFactory;
}
/// <summary>
/// 创建设施
/// </summary>
public void BuildGameFacilities()
{
//这些方法的调用都是依赖抽象方法
road = facilitiesFactory.CreateRoad();
building = facilitiesFactory.CreateBuilding();
tunnel = facilitiesFactory.CreateTunnel();
jungle = facilitiesFactory.CreateJungle();
}
/// <summary>
/// 运行游戏
/// </summary>
public void Run()
{
//road.AAA();
//building.BBB(road);
//tunnel.CCC();
//jungle.DDD();
}
}
}
using No02_AbstractFactory.AbstractFactoyGame;
using No02_AbstractFactory.NoChangePart;
using static No02_AbstractFactory.ModernStyleGame.ModernObjects;
namespace No02_AbstractFactory
{
public class GameApp
{
public static void Main()
{
//GameManager gameManager0 = new GameManager(new FacilitiesFactory()); //抽象的方法是不可以调用的,可以改用接口的方式
GameManager gameManager = new GameManager(new ModernFacilitiesFactory());
gameManager.BuildGameFacilities();
gameManager.Run();
}
}
}
- 本文作者:GeekPower - Felix Sun
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!