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



近期评论