MaoBisheng

Asp.Net(C#) & SQL & Oracle

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

2. Abstract Factory 抽象工厂(创建型模式)      2008-7-24

工厂模式的缘起

常规的对象创建方法

//创建一个Road 对象
Road road=new Road();

new的问题:

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

解决思路:

——封装变化点:哪里变化,封装哪里

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

最简单的方法:

class RoadFactory
{
    
public static Road CreateRoad()
    
{
        
return new Road();
        
//return new WaterRoad();
    }

}


//客户端程序
Road road = RoadFactory.CreateRoad()

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

假设一个游戏开发场景:我们需要“道路”,“地道”,“丛林”。。。等对象

    //变化点
    class RoadFactory
    
{
        
public static Road CreateRoad()
        
{
            
return new Road();
        }


        
public static Bulding CreateBulding()
        
{
            
return new Bulding();
        }


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


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

    }


    
//相对稳定
     Road road = RoadFactory.CreateRoad();
    Bulding bulding 
= RoadFactory.CreateBulding();    
    Tunnel tunnel 
= RoadFactory.CreateTunnel();
    Jungle jungle 
= RoadFactory.CreateJungle();

简单工厂问题:

不能应对“不同系列对象”的变化,比如有不同风格的游戏场景——对应不同风格的道路,房屋,地道。。。

如何解决——使用面向对象的技术来“封装”变化点 

动机(Motivation)

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

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

意图(Intent

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

 

(A,B);(A2,B2);(A1,B1) 相互依赖;(A1,B2)不相互依赖

客户程序依赖三个类:在客户程序中到处是这三个类,客户程序不依赖于具体实现 

namespace 抽象工厂模式
{
    
class Program
    
{
        
static void Main(string[] args)
        
{
            AbstractFactory factory1 
= new ConcreteFactory1();
            Client c1 
= new Client(factory1);
            c1.Run();

            AbstractFactory factory2 
= new ConcreteFactory2();
            Client c2 
= new Client(factory2);
            c2.Run();

            Console.Read();
        }

    }


    
abstract class AbstractFactory
    
{
        
public abstract AbstractProductA CreateProductA();
        
public abstract AbstractProductB CreateProductB();
    }


    
class ConcreteFactory1 : AbstractFactory
    
{
        
public override AbstractProductA CreateProductA()
        
{
            
return new ProductA1();
        }

        
public override AbstractProductB CreateProductB()
        
{
            
return new ProductB1();
        }

    }


    
class ConcreteFactory2 : AbstractFactory
    
{
        
public override AbstractProductA CreateProductA()
        
{
            
return new ProductA2();
        }

        
public override AbstractProductB CreateProductB()
        
{
            
return new ProductB2();
        }

    }

    
abstract class AbstractProductA
    
{
    }


    
abstract class AbstractProductB
    
{
        
public abstract void Interact(AbstractProductA a);
    }


    
class ProductA1 : AbstractProductA
    
{
    }


    
class ProductB1 : AbstractProductB
    
{
        
public override void Interact(AbstractProductA a)
        
{
            Console.WriteLine(
this.GetType().Name +
              
" interacts with " + a.GetType().Name);
        }

    }


    
class ProductA2 : AbstractProductA
    
{
    }


    
class ProductB2 : AbstractProductB
    
{
        
public override void Interact(AbstractProductA a)
        
{
            Console.WriteLine(
this.GetType().Name +
              
" interacts with " + a.GetType().Name);
        }

    }


    
class Client
    
{
        
private AbstractProductA AbstractProductA;
        
private AbstractProductB AbstractProductB;

        
// Constructor 
        public Client(AbstractFactory factory)
        
{
            AbstractProductB 
= factory.CreateProductB();
            AbstractProductA 
= factory.CreateProductA();
        }


        
public void Run()
        
{
            AbstractProductB.Interact(AbstractProductA);
        }

    }

}

 

Abstract Factory的几个要点:

如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的工厂完全可以。

“系列对象”指的是这些对象之间有相互依赖、或作用的关系,例如游戏开发场景中的“道路”与“房屋”的依赖,“道路”与“地道”的依赖。

Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动——如新增一个沙漠的对象。

 

posted on 2008-07-24 21:51  MaoBisheng  阅读(498)  评论(4编辑  收藏  举报