zoukankan      html  css  js  c++  java
  • Builder (建造者) — 【面向对象设计模式学习】

    Builder (建造者) — 【面向对象设计模式学习】

    By CityWalker 2010年3月19日

    Intent

    Separate the construction of a complex object from its representation so that the same construction process can create different representations.

    Applicability

    有些情况下,一个对象会有一些重要的性质,在它们没有恰当的值之前,对象不能作为一个完整的产品使用。比如,一个电子邮件有发件人地址、收件人地址、主题、内容、附录等部分,而在最起码的收件人地址未被赋值之前,这个电子邮件不能发出。

    有些情况下,一个对象的一些性质必须按照某个顺序赋值才有意义。在某个性质没有赋值之前,另一个性质则无法赋值。这些情况使得性质本身的建造涉及到复杂的商业逻辑。

    这时候,此对象相当于一个有待建造的产品,而对象的这些性质相当于产品的零件,建造产品的过程就是组合零件的过程。由于组合零件的过程很复杂,因此,这些"零件"的组合过程往往被"外部化"到一个称作建造者的对象里,建造者返还给客户端的是一个全部零件都建造完毕的产品对象。

    Structure

     

    建造者(Builder)角色:给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者(ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的方法:一个是建造方法,另一个是结果返还方法。

    具体建造者(Concrete Builder)角色:担任这个角色的是于应用程序紧密相关的类,它们在应用程序调用下创建产品实例。这个角色主要完成的任务包括:

    a)         实现Builder角色提供的接口,一步一步完成创建产品实例的过程。

    b)         在建造过程完成后,提供产品的实例。

    指导者(Director)角色:担任这个角色的类调用具体建造者角色以创建产品对象。导演者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。

    产品(Product)角色:产品便是建造中的复杂对象。

    指导者角色是于客户端打交道的角色。导演者角色将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求委派给具体建造者角色。具体建造者角色是做具体建造工作的,但却不为客户端所知。

    Example

     以交通工具的制造为例,类图如下:

    主要代码实现:

    VehicleBuilder

    public abstract class VehicleBuilder
        {
            protected Vehicle vehicle;
    
            public Vehicle VehicleInfo
            {
                get { return vehicle; }            
            }
    
            public abstract void BuildFrame();
    
            public abstract void BuildEngine();
    
            public abstract void BuildWheel();
    
            public abstract void BuildDoor();
    
            public abstract Vehicle GetProduct();
        }
    

    Shop

    public class Shop
        {
            public void Construct(VehicleBuilder vehicle)
            {
                vehicle.BuildFrame();
                vehicle.BuildEngine();
                vehicle.BuildWheel();
                vehicle.BuildDoor();
                vehicle.GetProduct().Show();
            }
        }
    

    Vehicle

    public class Vehicle
        {
            private string type;
            private Hashtable parts = new Hashtable();
    
            public Vehicle(string type)
            {
                this.type = type;
            }
    
            public object this[string key]
            {
                get { return parts[key]; }
                set { parts[key] = value; }
            }
    
            public void Show()
            {
                Console.WriteLine("-------------------");
                Console.WriteLine("Frame: " + parts["frame"]);
                Console.WriteLine("Engine: " + parts["engine"]);
                Console.WriteLine("Wheels: " + parts["wheels"]);
                Console.WriteLine("Doors: " + parts["doors"]);
            }
        }
    

    MotorCycleBuilder

    public class MotorCycleBuilder : VehicleBuilder
        {
            public override void BuildFrame()
            {
                vehicle = new Vehicle("MotorCycle");
                vehicle["frame"] = "MotorCycle Frame";
            }
    
            public override void BuildEngine()
            {
                vehicle["engine"] = "500 cc";
            }
    
            public override void BuildWheel()
            {
                vehicle["wheels"] = "2";
            }
    
            public override void BuildDoor()
            {
                vehicle["doors"] = "0";
            }
    
            public override Vehicle GetProduct()
            {
                return vehicle;
            }
        }
    

    CarBuilder

    public class CarBuilder : VehicleBuilder
        {
            public override void BuildFrame()
            {
                vehicle = new Vehicle("Car");
                vehicle["frame"] = "Car Frame";
            }
    
            public override void BuildEngine()
            {
                vehicle["engine"] = "2500cc";
            }
    
            public override void BuildWheel()
            {
                vehicle["wheels"] = "4";
            }
    
            public override void BuildDoor()
            {
                vehicle["doors"] = "4";
            }
    
            public override Vehicle GetProduct()
            {
                return vehicle;
            }
        }
    

    Client:

    static void Main(string[] args)
            {
                VehicleBuilder builder = new CarBuilder();
                Shop shop = new Shop();
                shop.Construct(builder);
    
                Console.ReadKey();
            }
    
  • 相关阅读:
    MySQL 4.1x 中文乱码效果
    linux内核中的“捏造化”
    Ubuntu开发者峰会在布拉格举行
    Decode 函数的用法
    Solaris 10拆卸jdk1.6及点窜成默许JDK
    教你编写高机能的mysql语法
    DirectShow9.0在vs2005中存在的问题解决
    Unicode,unicoidebig,Asci,UTF8文件read和write
    自已写了个GDI类,实现了相对路径载入任意类型的图片函数,并加一个在CRECT矩形上贴图的函数(5月25日写)
    两种解析EDIT控件上文本的方式
  • 原文地址:https://www.cnblogs.com/Reborn/p/1690327.html
Copyright © 2011-2022 走看看