Abstract Factory 抽象工厂(创建型模式)

new 的问题
常规的对象创建方法: Road road = new Road();

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

解决思路:
    -- 封装变化点--哪里变化,封装哪里
    -- 潜台词:如果没有变化,当然不需要额外的封装

工厂模式的缘起

·变化点在"对象创建",因此就封装"对象创建"
·面向接口编程--依赖接口,而非依赖实现
·最简单的解决方法:

 

 

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

假设一个游戏开发场景:

我们需要构造"道路","房屋","地道","丛林"....

从一个对象工厂到一组有关系的对象工厂:

 

代码
        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();
            }
            ...
        }

 

 


静态简单工厂的问题:不能应对"不同系列对象"的变化。比如有不同风格的游戏场景---对应不同风格的道路、房屋、地道...,场景不一样时要一个个去改new 的对象

解决:使用面向对象的技术来"封装"变化点

动机(Motivation)

在软件系统中,经常面临着"一系列相互依赖的对象"的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。

如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种"封装机制"来避免客户程序和这种"多系列具体对象创建工作"的紧耦合?


意图(Intent)

提供一个接口,让接口负责创建一系列"相关或者相互依赖的对象",无需指定它们具体的类。     ---《设计模式》GoF

结构: 


 

 客户程序不需要更改,只需要换一个Dll,整个风格即可变化


代码

        
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模式共同组合来"应对"对象创建"的需求变化 


 

 

posted @ 2009-12-25 23:59  疯狂的咸鱼  阅读(373)  评论(0编辑  收藏  举报