设计模式之创建型(4)-建造者模式(Builder)

设计模式之创建型(4)-建造者模式(Builder)

(一)定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们。用户不知道内部的具体构建细节。

UML类图:抽象不应该依赖细节,细节应该依赖于抽象

image

(二)类与对象之间的关系:

Builder:抽象建造者。为创建一个Product对象的各个部件指定抽象接口。

ConcreteBuilder:具体建造者。实现Builder接口。
  ❶  构造和装配产品的各个部件。
  ❷  定义并明确它所创建的表示。
  ❸  提供一个返回这个产品的接口。

Director:指挥者。构建一个使用Builder接口的对象。

Product:产品角色
  ❶  被构建的复杂对象,具体建造者创建该产品的内部表示并定义它的装配过程。
  ❷ 包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

(三)时序图:

image

(四)4.1 案例分析:车间造车

车间装配车辆是分步骤完成的复杂装配过程,车行采用不同的车间装配出不同的车辆。但是每个车辆装配的过程是稳定的,不同是会根据不同的需求装配出不同的车辆。因此可以将该问的处理采用生成器模式来解决。

类关系图如下:

image

代码如下:

源码using System;
using System.Collections;
using System.Text;

namespace 设计模式.生成器模式
{
    public class Shop
    {
        public 
        {
            vehicleBuilder.BuildFrame();
            vehicleBuilder.BuildEngine();
            vehicleBuilder.BuildWheels();
            vehicleBuilder.BuildDoors();
        }
    }

    public abstract class VehicleBuilder
    {
        protected Vehicle vehicle;
        public Vehicle Vehicle
        {
            get
            {
                return vehicle;
            }
        }
        public abstract void BuildFrame();
        public abstract void BuildEngine();
        public abstract void BuildWheels();
        public abstract void BuildDoors();
    }

    public class MotorCycleBuilder : VehicleBuilder
    {
        public override void BuildFrame()
        {
            vehicle = new Vehicle("摩托车");
            vehicle["frame"] = "MotorCycle Frame";
        }

        public override void BuildEngine()
        {
            vehicle["engine"] = "500 CC";
        }

        public override void BuildWheels()
        {
            vehicle["wheels"] = "2";
        }

        public override void BuildDoors()
        {
            vehicle["doors"] = "0";
        }
    }

    public class CarBuilder : VehicleBuilder
    {

        public override void BuildFrame()
        {
            vehicle = new Vehicle("轿车");
            vehicle["frame"] = "Car Frame";
        }

        public override void BuildEngine()
        {
            vehicle["engine"] = "2500 CC";
        }

        public override void BuildWheels()
        {
            vehicle["wheels"] = "4";
        }

        public override void BuildDoors()
        {
            vehicle["doors"] = "4";
        }
    }

    public class ScooterBuilder : VehicleBuilder
    {

        public override void BuildFrame()
        {
            vehicle = new Vehicle("单脚滑行车");
            vehicle["frame"] = "Scooter Frame";
        }

        public override void BuildEngine()
        {
            vehicle["engine"] = "none";
        }

        public override void BuildWheels()
        {
            vehicle["wheels"] = "2";
        }

        public override void BuildDoors()
        {
            vehicle["doors"] = "0";
        }
    }

    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 string Show()
        {
            Console.WriteLine("\n----------------------------------");
            Console.WriteLine("车辆类型:" + type);
            Console.WriteLine(" 框架:" + parts["frame"]);
            Console.WriteLine(" 发动机:" + parts["engine"]);
            Console.WriteLine(" #轮子数:" + parts["wheels"]);
            Console.WriteLine(" #车门数:" + parts["doors"]);

            StringBuilder sb=new StringBuilder();
            sb.AppendFormat("车辆类型:{0}",type).AppendLine();
            sb.AppendFormat(" 框架:{0}",parts["frame"]).AppendLine();
            sb.AppendFormat(" 发动机:{0}",parts["engine"]).AppendLine();
            sb.AppendFormat(" #轮子数:{0}", parts["wheels"]).AppendLine();
            sb.AppendFormat(" #车门数:{0}" , parts["doors"]);
            return sb.ToString();
        }
    }
}

4.2  案例分析:房屋构建

image

代码实现class Program
{
    static void Main(string[] args)
    {
        IHouse house = BuildHouse(false);
        Console.WriteLine(house.Description());
        Console.ReadKey();
    }

    public static IHouse BuildHouse(bool isBackyard)
    {
        if (isBackyard)
        {
            return new SingleFamilyHouse();
        }
        else
        {
            return new Aparement();
        }
    }
}

public interface IHouse
{
    Boolean GetBackyard();
    long NoOfRooms();
    string Description();
}

public class Room
{
    public string RoomName { get; set; }
}

public class Aparement : IHouse
{
    private Boolean isBackyard; //是否带院子
    private List<Room> rooms;

    public Aparement()
    {
        rooms = new List<Room>();

        
        room.RoomName = "Master Room";
        rooms.Add(room);

        room = new Room();
        room.RoomName = "Second BedRoom";
        rooms.Add(room);

        room = new Room();
        room.RoomName = "Living Room";
        rooms.Add(room);
        isBackyard = false;
    }

    public bool GetBackyard()
    {
        return isBackyard;
    }

    public long NoOfRooms()
    {
        return rooms.Count;
    }

    public string Description()
    {
        StringBuilder strDescript = new StringBuilder();
        strDescript.AppendFormat("这是一间公寓,有{0}间房间,这间公寓没有后院", rooms.Count).AppendLine();
        foreach (Room item in rooms)
        {
            strDescript.AppendFormat("{0}房间{1}", rooms.FindIndex(t => t.RoomName == item.RoomName), item.RoomName).AppendLine();
        }
        return strDescript.ToString();
    }
}

public class SingleFamilyHouse : IHouse
{
    private bool isBackyard;
    private List<Room> rooms;

    public SingleFamilyHouse()
    {
        rooms = new List<Room>();

        
        room.RoomName = "Master Room";
        rooms.Add(room);

        room = new Room();
        room.RoomName = "Second BedRoom";
        rooms.Add(room);

        room = new Room();
        room.RoomName = "Third BedRoom";
        rooms.Add(room);

        room = new Room();
        room.RoomName = "Guest BedRoom";
        rooms.Add(room);

        room = new Room();
        room.RoomName = "Living Room";
        rooms.Add(room);
        isBackyard = true;
    }

    public bool GetBackyard()
    {
        return isBackyard;
    }

    public long NoOfRooms()
    {
        return rooms.Count;
    }

    public string Description()
    {
        StringBuilder strDescript = new StringBuilder();
        strDescript.AppendFormat("这是一间公寓,有{0}间房间,这间公寓有后院", rooms.Count).AppendLine();
        foreach (Room item in rooms)
        {
            strDescript.AppendFormat("{0}房间{1}", rooms.FindIndex(t => t.RoomName == item.RoomName), item.RoomName).AppendLine();
        }
        return strDescript.ToString();
    }
}

(五)建造者模式的适用性及优缺点分析

优点:建造者模式使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体建造者就可以了。建造者模式将一个复杂对象的生成责任进行了很好的分配。它把构造过程放到指挥者的方法中,把装配过程放到具体建造者类中。建造者模式的产品之间都有共通点。

缺点:如果产品之间的差异性很大,这就需要借助工厂方法模式或抽象工厂模式。另外,如果产品的内部变化复杂,Builder的每一个子类都需要对应到不同的产品去做构建的动作,这就需要定义很多个具体建造者类来实现这种变化。

适用性:

①  创建复杂对象的算法是独立于它的组成部件及装配过程。

创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。

②  构造的过程允许构造对象有不同的表现。

posted @ 2014-05-27 00:00 李华丽 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值