首页 > 设计模式 > 初尝Builder 设计模式

初尝Builder 设计模式

每一次去下馆子都会遇到这样的模式,告诉服务员你的需求,然后由他们的人配餐,出菜。这样的消费过程在西式快餐中体现的尤为标准。不论你的需求多么复杂,到餐馆吃饭,无非2样:要吃的,要喝的。在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法确相对稳定。如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?这就是要说的Builder 模式。

意图

将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

结构图

builder 结构图

时序图

builder 时序图

一段代码

using System;
using System.Collections;
using System.Configuration;
using System.Reflection;

namespace Builder
{

    public abstract class CanBeTaken
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private decimal money;

        public decimal Money
        {
            get { return money; }
            set { money = value; }
        }
        public CanBeTaken(string name, decimal money)
        {
            this.name = name;
            this.money = money;
        }

    }

    public interface Builder
    {
        void BuildFood();
        void BuildDrink();
        BillList GetBill();
    }

    public class BillList
    {
        Hashtable bill = new Hashtable();

        public void Add(CanBeTaken FoodOrDrink) {
            if (bill != null)
                bill.Add(FoodOrDrink.Name,FoodOrDrink.Money);
        }

        public void Remove(CanBeTaken FoodOrDrink) {
            if (bill != null && bill.Contains(FoodOrDrink.Name)) {
                bill.Remove(FoodOrDrink.Name);
            }
        }

        public void ShowBill() {
            decimal total=0;
            Console.WriteLine("--------------------------------------\n");
            //foreach (CanBeTaken cbt in bill) {
            //    Console.WriteLine("{0} : $ {1}",cbt.Name,cbt.Money);
            //    total += cbt.Money;
            //}
            IDictionaryEnumerator enumer = bill.GetEnumerator();
            while (enumer.MoveNext()) {
                Console.WriteLine("{0} : $ {1}", enumer.Key.ToString(), enumer.Value.ToString());
                total += (decimal)enumer.Value;
            }
            Console.WriteLine("Needs : ${0}",total);
            Console.WriteLine("\n--------------------------------------\n");
        }

    }

    public class NormalBuilder : Builder {
        class NormalFood : CanBeTaken {
            public NormalFood(string name, decimal money) : base(name, money) { }
        }
        BillList list = new BillList();
        public void BuildFood() {
            list.Add(new NormalFood("东北大米",(decimal)0.1));
            list.Add(new NormalFood("四菜一汤",(decimal)3.5));
        }

        public void BuildDrink() {
            list.Add(new NormalFood("营养快线",(decimal)0.5));
        }

        public BillList GetBill() {
            if (list != null)
                return list;
            else
                return null;
        }
    }

    public class WesternBuilder : Builder {
        class WesternFood : CanBeTaken {
            public WesternFood(string name, decimal money) : base(name, money) { }
        }
        BillList list = new BillList();
        public void BuildFood() {
            list.Add(new WesternFood("KFC 外带全家桶",(decimal)7.5));
        }

        public void BuildDrink() {
            list.Add(new WesternFood("可口可乐",(decimal)0.5));
        }

        public BillList GetBill()
        {
            if (list != null)
                return list;
            else
                return null;
        }

    }

    public class Director
    {
        public Director(Builder builder) {
            builder.BuildFood();
            builder.BuildDrink();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Builder builder;
            string builderName = ConfigurationManager.AppSettings["builderName"].ToString();
            builder = (Builder)Assembly.Load("Builder").CreateInstance("Builder." + builderName);
            Director d = new Director(builder);
            BillList list = builder.GetBill();
            list.ShowBill();
        }
    }
}

运行结果

builder 运行结果

  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.