您的位置:首页 > 编程语言 > C#

C#面向对象设计模式纵横谈3 AbstractFactory抽象工厂模式创建型模式

2015-06-08 17:19 483 查看
Abstract Factory抽象工厂(创建型模式)

创建型模式主要解决的就是一个new的问题

常见的对象创建方法:

//创建一个Road对象

Road road=new Road();

new 的问题

–实现依赖,不能对应“具体实例化类型”的变化。

如上面的road路方法,变成水泥路,则原来使用road的

地方都需要修改

解决思路:

–封住变化点–哪里变化,封住哪里(设计模式核心原则)

–潜台词:如果没有变化,当然不需要额外的封装;

工厂模式的缘起

变化点在“对象创建”,因此就封装“对象创建”

面向接口编程–依赖接口,而非依赖实现

最简单的解决方法:

class RoadFoctory
{
//静态方法
public static Road CreateRoad()
{
//这里如果需要创建不同的路,只需要在这修改
返回即可,其他调用的地方不需要改变;从此,
对路需求的改变就可以隔离在这个地方
//return new Road();
return new WaterRoad();//水路
}
}


====================客户程序=====================

= =

= //创建一个Road对象 =

= Road road=roadFactory.CreateRoad(); =

= =

====================客户程序=====================

创建一系列相互依赖的对象

假设一个游戏开发场景:

我们需要构造“道路”、“房屋”、“地道”、“丛林”。。等等对象

Road road=roadFactory.CreateRoad();
...
BUilding building=roadFactory.CreateBuilding();

class RoadFactory
{
//都是静态代码
public static Road CreateRoad(0
{
return new Road();
}

public static Building CreateBuilding()
{
return new Building();
}

public statice Tunnel CreateTunnel()
{
return new Tunnel();
}

public static Jungle CreateJungle()
{
return new Jungle();
}
}


上面简单工厂(静态工厂)的问题:

–不能对应“不同系列对象”的变化。比如有不同风格的

游戏场景–对应不同风格的道路、房屋、地道。。。

如何解决:

–使用面向对象的技术“封装”变化点

动机(Motivation)

在软件系统中,经常面临着“一系列相互依赖的对象”的创建

工作;同时,由于需求的变化,往往存在更多系统对象的创建工作。

如何应对这种变化?如何饶过常规的对象创建方法(new),提供

一种“封装机制”来避免客户程序和这种“多系列具体对象创建

工作”的紧耦合?

意图(Intent)

提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,

无需指定他们具体的类。

结构:图-1



A2和B2是相互依赖的,A1和B1是相互依赖的

A1、B1是一系列

A2、B2是二系列

ConcreteFactory2()创建的是A2和B2

客户程序依赖的是AbstractFactory、AbstractFactoryA、AbstractFactoryB

ConcreteFactory1(道路系列1)和ConcreteFactory2(道路系列2)是不在客

户程序出现的,客户程序

不依赖具体实现,客户程序只依赖于三个抽象的类

代码示例:

//路
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
{
FacilitiesFactory facilitiesFactory;
punlic GameManager(FacilitiesFactory facilitiesFactory)
{
this.facilitiesFactory=facilitiesFactory;
}

Road road;
Building building;
Tunnel tunnel;
public void BuildGameFacilities()
{
road=facilitiesFactory.CreateRoad();

building=facilitiesFactory.CreateBuilding();

tunnel=facilitiesFactory.CreateTunnel();
}

public void Run()
{
road.AAA();
building.BBB();
}
}

//现代路
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 Jungle CreateJungle()
{
return new ModernJungle();
}
}

class App
{
public static void Main()
{
//现代风格
//GameManager g=new GameManager(new ModernFacilitiesFacitory());
//想要古典风格的只需要换这里
GameManager g=new GameManager(new ClassicFacilitiesFactory());

g.BuildGanmeFacilities();
g.Run();
}
}


这种模式应对的是系列不稳定,风格不稳定,而不是应对的是对象的不稳定(对象指的是道路,房屋,管道等,这些是稳定的)

如果添加了一种沙漠的对象,这种工厂设计模式就是一种失败的设计模式。

因为添加了一个沙漠抽象对象,整个客户程序所有的都要重来,

所有依赖、继承于你这个抽象工厂这个类都要重新实现重新部署。

寻找变化点,隔离变化点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: