new的问题:不能应对“具体实例化类型的变化”
解决思路:哪里变化,封装哪里
设计模式解决的问题就是在设计时要考虑到以后可能发生的变化,并为这种变化预留扩展
变化点在“对象创建”,因此就封装“对象创建”
面向接口编程-依赖接口,而非依赖实现
最简单的解决方案:
class RoadFactory{
public static Road CreateRoad()
{
Retrun new Road();
}
}
Road road=roadFactory.CreateRoad();
假设一个游戏开发场景,需要构造道路,房屋,街道,丛林等
class RoadFactory{
public static Road CreateRoad()
{
Retrun new Road();
}
public static Building CreateBuilding()
{
Retrun new Building();
}
public static Tunnel CreateTunnel()
{
Retrun new Tunnel();
}
public static Jungle CreateJungle()
{
Retrun new Jungle();
}
}
Road road=roadFactory.CreateRoad();
Building building=roadFactory.CreateBuilding();
简单工厂问题:不能应对“不同系列对象”的变化,比如有不同风格的游戏场景
如何解决:使用“面向对象”的技术来封装变化点
动机:
在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作,同时,由于需求的变化,往往存在更多系列对象的变化
如何应对这种变化:绕过常规的对象创建方法,提供一种“封装机制”来避免客户程序和这种“多系列具体对象的创建工作”的紧耦合
提供一个接口,让该接口负责创建一系列“相关或相互依赖的对象”,无需指定它们具体的类
Abstract Factory模式的几个要点:
1.如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的静态工厂完全可以
2.“系列对象”指的是这些对象之间有相互依赖、或作用的关系,如游戏场景中“道路”与“房屋”的关系
3.Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动
4.Abstract Factory模式经常和Factory Method模式共同组合来应对“对象创建”的需求变化
public abstract class Road
{
}
public abstract class Building
{
}
public abstract class Tunnel
{
}
public abstract class Jungle
{
}
abstract class FacilitiesFactory
{
public abstract Road CreateRoad()
public abstract Building CreateBuilding()
public abstract Tunnel CreateTunnel()
public abstract Jungel CreateJungle()
}
public class ModernRoad : Road
{
}
public class ModernBuilding : Building
{
}
public class ModernTunnel : Tunnel
{
}
public class ModernJungle : Jungle
{
}
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 Jungel CreateJungle()
{
return new ModernJungle();
}
}
//客户程序
class GameManager
{
FacilitiesFactory facilitiesFactory;
Road road;
Building building;
Tunnel tunnel;
Junnel jungle;
public GameManager(FacilitiesFactory facilitiesFactory)
{
this.facilitiesFactory=facilitiesFactory;
}
public void BuildGameFacilities
{
road=facilitiesFactory.CreateRoad();
building=facilitiesFactory.CreateBuilding();
tunnel=facilitiesFactory.CreateTunnel();
jungle=facilitiesFactory.CreateJungle();
}
public void Run()
{
road.AAA();
building.BBB(road);
tunnel.CCC();
jungle.DDD(tunnel);
}
}
//调用
class App
{
pulic static void Main()
{
GameManager g=new GameManager(new ModernFacilitiesFactory());
g.BuildGameFacilities();
g.Run();
}
}