1.常规的对象创建方法:
// 创建一个Road 对象
Road road=new Road();
new的问题:
– 实现依赖,不能应对“具体实例化类型”的变化。
2.工厂模式的缘起
• 变化点在“对象创建”,因此就封装“对象创建”
• 面向接口编程——依赖接口,而非依赖实现
最简单的解决方法:
class RoadFactory {
public static Road CreateRoad()
{
return new Road();
}
}
// 在其他类里面创建一个Road 对象
Road road=
roadFactory.CreateRoad();
3.创建一系列相互依赖的对象
假设一个游戏开发场景:
我们需要构造“道路”、
“房屋”、“地道”、“丛
林”……等等对象
普通的静态工厂:
class FacilityFactory {
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
}
简单工厂的问题:
– 不能应对“不同系列对象”的变化。比如有不同风格的游
戏场景——对应不同风格的道路、房屋、地道……
4.Abstract Factory
动机:在软件系统中,经常面临着“一系列相互依赖的对象”的创建
工作;同时,由于需求的变化,往往存在更多系列对象的
创建工作。
意图:提供一个接口,让该接口负责创建一系列“相关或者
相互依赖的对象”,无需指定它们具体的类。
//抽象类
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 Jungle CreateJungle();
}
//客户程序
客户程序依赖于上面的抽象类和抽象工厂,不依赖于具体的实现
class GameManager
{
Road road;
Building building;
Tunnel tunnel;
Jungle jungle;
FacilitiesFactory facilitiesFacotry;
public GameManager(FacilitiesFactory facilitiesFactory)
{this.facilitiesFactory=facilitiesFactory;}
public void BuildGameFacilities()
{
road = facilitiesFactory.CreateRoad();
building = facilitiesFactory.CreateBuilding();
tunnel = facilitiesFactory.CreateTunnel();
jungle = facilitiesFactory.CreateJungle();
}
public void Play()
{
road.AAA();
building.BBB(road);
tunnel.CCC();
jungle.DDD(tunnel);
}
}
抽象类的具体实现:
public class ModernRoad():Road
{}
public class ModernBuilding():Building
{}
public class ModernTunnel():Tunnel
{}
public class ModernJungle():Jungle
{}
抽象工厂的具体实现类
class ModernFacilitiesFactory:FacilitiesFactory
{
public overried Road CreateRoad( return ModernRoad(););
public overried Building CreateBuilding(return ModernBuilding(););
public overried Tunnel CreateTunnel(return ModernTunnel(););
public overried Jungle CreateJungle(return ModernJungle(););
}
这样就创建了一个现代风格的设施,传入客户程序的构造函数。如果要创建古典风格的设施,只需要提供古典设施的实现(抽象类和抽象工厂的实现),只需要将下面这个类的GameManager参数改为古典风格抽象工厂实现类的实例new ClassicFacilitiesFactory()或者将这个参数写在配置文件里面,我们只需要修改配置文件就可以在游戏中实现古典风格的游戏场景,而客户程序不需要一点的修改。
//调用客户程序的类
class App
{
public static void Main()
{
GameManger g= new GameManger( new ModernFacilitiesFactory());
g.BuildGameFacilities();
g.Run();
}
}
Abstract Factory模式的几个要点:
如果没有应对“多系列对象构建”的需求变化,则没有必要
使用Abstract Factory模式,这时候使用简单的静态工厂
完全可以。
• “系列对象”指的是这些对象之间有相互依赖、或作用的关
系,例如游戏开发场景中的“道路”与“房屋”的依赖,“道路”
与“地道”的依赖。
• Abstract Factory模式主要在于应对“新系列”的需求变动。
其缺点在于难以应对“新对象”的需求变动。
• Abstract Factory模式经常和Factory Method模式共同组合
来应对“对象创建”的需求变化。