在软件开发的过程中,当遇到一个“复杂的对象”,该对象由好多的部分组成,各个部分的组合比较稳定或有一定的依赖次序,但各部分自身却会经常面临着变化。如何隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”,这就是所谓的建造模式。
例子:
买肯德基
:(Terrylee的例子)典型的儿童餐包括一个主食,一个辅食,一杯饮料和一个玩具(例如汉堡、炸鸡、可乐和玩具车)。这些在不同的儿童餐中可以是不同的,但是组合成儿童餐的过程是相同的。
客户端:顾客。想去买一套套餐(这里面包括汉堡,可乐,薯条),可以有1号和2号两种套餐供顾客选择。
指导者角色:
收银员。知道顾客想要买什么样的套餐,并告诉餐馆员工去准备套餐。
建造者角色:
餐馆员工。按照收银员的要求去准备具体的套餐,分别放入汉堡,可乐,薯条等。
产品角色:
最后的套餐,所有的东西放在同一个盘子里面。
计算工资:
工资的计算一般是:底薪+奖金-税。但底薪分为一级8000、二级6000、三级4000三个等
级。根据岗位不同奖金的发放也不一样,管理及日常事务处理岗位(A类)每月根据领导及同事间的评议得分计算奖金,销售岗位(B类)则根据销售额发放提成。
税金则根据奖金和底薪的数额进行计算。由此看出该工资的计算方式是比较稳定的构建算法,但对工资的每一部分都会根据不同的情况产生不同的算法,如何将客户
端与变化巨烈的底薪、奖金和税金计算方式分离呢,这也比较适合用建造者模式。
Builder模式的架构
抽象建造者(Builder):
给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。
具体建造者(Concrete Builder):
实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例。
指导者(Director):
调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。
产品(Product):
要创建的复杂对象。
程序实现:
//指导者
class Director
{
public void build(Builder b
)
{
b.BuildPartA();
b.BuildPartB();
}
}
//抽象建造者
abstract class Builder
{
//创建产品的第一部分
public abstract void BuildPartA();
//创建产品的第二部分
public abstract void BuildPartB();
}
//具体建造者类
class ConcreteBuilder1 : Builder
{
Product p = new Product();
public override void BuildPartA()
{
p.Add("Part1","Part1");
}
public override void BuildPartB()
{
p.Add("Part2","Part2");
}
//返回产品对象
public Product GetProduct()
{
return p;
}
}
//具体建造者类
class ConcreteBuilder2 : Builder
{
Product p = new Product();
public override void BuildPartA()
{
p.Add("PartA","PartA");
}
public override void BuildPartB()
{
p.Add("PartB", "PartB");
}
//返回产品对象
public Product GetProduct()
{
return p;
}
}
//产品类
class Product
{
StringDictionary sd = new StringDictionary();
public void Add(string name, string value)
{
sd.Add(name, value);
}
public void Show()
{
foreach (DictionaryEntry de in sd)
{
Console.WriteLine(de.Key+"\t"+de.Value+"\n");
}
}
}
//客户程序
class Client
{
public static void Main(string[] args)
{
Director d = new Director();
Builder b1 = new ConcreteBuilder1();
Builder b2 = new ConcreteBuilder2();
d.build(b1);
d.build(b2);
((ConcreteBuilder1)b1).GetProduct().Show();
((ConcreteBuilder2)b2).GetProduct().Show();
}
}
(车延禄)
程序举例:创建一个证件生成的程序。
任何证件生成都需要两个部分组成--姓名和号码。姓名由“姓”和“名”组成,而号码则根据不同证件由不同的生成方式。如:学生证("前缀"+号码),身份证("省份"+"城市"+"出生日期"+"随机数")。
产品类如下实现:
class Certificate
{
//证件名称
private string name;
//证件号码
private string cardid;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public string CardID
{
get
{
return cardid;
}
set
{
cardid = value;
}
}
//显示证件信息
public void show()
{
Console.WriteLine(name + "\n" + cardid);
}
}
抽象建造者:
interface IBuilder
{
//生成姓名
void BuildName();
//生成证件号码
void BuildCardID();
}
具体建造者(生成学生证):
class StudentBuilder : IBuilder
{
//证件对象
Certificate p = new Certificate();
private string firstname
; //名字
private string lastname
; //姓氏
private string cardprefix
; //学生证前缀
private string cardno
; //学生证号码
public StudentBuilder(string fname, string lname, string cprefix, string cno)
{
this.firstname = fname;
this.lastname = lname;
this.cardprefix = cprefix;
this.cardno = cno;
}
//建造学生证姓名
public void BuildName()
{
p.Name = lastname + firstname;
}
//建造学生证号码
public void BuildCardID()
{
p.CardID = cardprefix + cardno;
}
//返回证书对象
public Certificate GetCertificate()
{
return p;
}
}
具体建造者(生成身份证)
class PersonBuilder : IBuilder
{
//证书对象
Certificate p = new Certificate();
private string lastname
; //名字
private string firstname
; //姓氏
private string provno
; //省份代号
private string cityno
; //城市代号
private DateTime birthday
; //出生日期
private string randomcode
; //生成身份证号的后三位随机数
public PersonBuilder(string lname, string fname, string pno, string cno, DateTime birth, string randomcode)
{
this.lastname = lname;
this.firstname = fname;
this.provno = pno;
this.cityno = cno;
this.birthday = birth;
this.randomcode = randomcode;
}
//建造姓名对象
public void BuildName()
{
p.Name = lastname + firstname;
}
//建造身份证号码
public void BuildCardID()
{
string strbirth = birthday.Year.ToString() + birthday.Month.ToString() + birthday.Day.ToString();
p.CardID = provno + cityno + strbirth + randomcode;
}
//返回证件对象
public Certificate GetCertificate()
{
return p;
}
}
指导者对象:
class Director
{
public void Build(IBuilder b
)
{
b.BuildName();
b.BuildCardID();
}
}
客户端对象:
class Client
{
public static void Main()
{
//创建指导者
Director d = new Director();
Console.WriteLine("请输入要创建的证书类型:(0-驾照,1-身份证)");
string type = Console.ReadLine();
switch (type)
{
case "0":
//实例化学生证具体生成器
IBuilder b1 = new StudentBuilder("伯通", "周", "鲁教字:", "99999999");
d.Build(b1);
b1.GetCertificate().show();
break;
case "1":
//实例化身份证具体生成器
IBuilder b2 = new PersonBuilder("峰", "欧阳", "3701", "01", new DateTime(1976, 11, 23), "89x");
d.Build(b2);
b2.GetCertificate().show();
break;
default:
break;
}
}
}
每一个具体的建造者是相互独立的,完成某一类产品的组装生成,可以完成产品在组装过程中实现更精细的控制。
在客户端程序中无需了解产品的构造,只需要实例化指导者对象和具体建造者对象,然后使用指导者对象来控制具体建造者的的建造过程和建造次序。
在指导者对象中用来控制具体建造对象的建造过程。
在具体建造者对象中用来实现产品每一部分的具体建造过程。
在产品对象用来描述产品的各部件的组成。
建造者模式用来控制产品的建造过程,实现产品对象的组成变化与客户程序的分离,而工厂模式实现产品类型的变化与客户端程序的分离。
建造模式的演化:
省略抽象建造者:
如果只有一个具体建造者的话,那可以省略抽象建造者。
class Director
{
ConcreteBuilder b = new ConcreteBuilder();
public void build()
{
b.BuildPartA();
b.BuildPartB();
}
}
如果只有一个具体建造者,除了可以省略抽象建造者,还可以把指导者也省略,让具体建造者也承担指导者的角色。
class ConcreteBuilder : Builder
{
Product p = new Product();
public override void BuildPartA()
{
p.Add("Part1","Part1");
}
public override void BuildPartB()
{
p.Add("Part2","Part2");
}
//返回产品对象
public Product GetProduct()
{
return p;
}
//具体建造者承担的指导者的角色功能
public void Construct()
{
BuildPartA();
BuildPartB();
}
}
一般来说在以下两种情况下应当考虑使用建造者模式:
1、被建造的对象有复杂的组成部分,每一部分的生成算法又不一样。(采用具体建造者不同的方法,实现对象不同部分的构造)
2、被建造的对象各部分有一定的组成顺序。(用Director对ConcreteBuild方法的调用次序来控制)
分享到:
相关推荐
java设计模式------------------------------------建造者模式
设计模式之---建造模式 1,建造模式属于对象的创建模式,是将一个产品的内部表象和产品的生产分割出来 2.使用原因:为了将构建复杂对象的过程和它的不见解耦; 3 使用情况:建造模式利用一个导演着对象和一个具体...
JAVA-设计模式-创建型模式-建造者模式
Java设计模式-建造者模式详解 Java设计模式-建造者模式详解将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。生成器模式(Builder)是使用多个“小型”工厂来最终创建出一个完整对象。...
-java常用设计模式-建造者模式是java中的一种创建型设计模式,它允许开发者通过一步一步地构建复杂对象来创建不同类型的对象。 建造者模式的定义 建造者模式是一种创建型设计模式,它允许开发者通过一步一步地构建...
建造者模式(Builder Pattern)是一种创建型设计模式,它提供了一种方法来分步骤构建复杂的对象,使得构建过程和表示分离,使得同样的构建过程可以创建不同的表示。这种模式经常在对象的构造过程中需要进行多种选择...
建造者模式是一种结构型设计模式,它将复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。这种模式在软件工程中被广泛应用,尤其是在需要构建对象的过程复杂且需要保持构建过程与对象表现分离的...
**建造者模式(Builder Pattern)**是软件设计模式中的一种创建型模式,它允许我们分步骤构建复杂的对象,而无需暴露构建过程。在C++中,这种模式常用于将对象的创建过程与使用过程分离,使得对象的构建更加灵活,...
"设计模式-建造者模式" 设计模式是软件开发中常用的解决问题的方法和模式,旨在提高软件的可维护性、灵活性和可重用性。设计模式可以分为三大类:创建型模式、结构型模式和行为型模式。今天,我们将讨论创建型模式...
建造者模式是一种结构型设计模式,它允许我们分步骤创建复杂对象,而无需暴露构建过程的内部细节。这种模式在Java编程中非常常见,尤其是在处理需要多种构建方式或需要隔离对象构造过程的场景。 建造者模式的核心...
建造者模式(Builder Pattern)是软件工程中一种用于创建对象的抽象工厂方法,它将复杂的对象构造过程分离开来,使得相同的构造过程可以创建不同的表示。这种模式在C#编程中广泛应用于创建对象的复杂性较高,或者...
建造者模式是一种软件设计模式,属于创建型模式之一,主要用于解决创建复杂对象的问题。在实际应用中,当对象的构造过程过于复杂,涉及到多个属性或者子对象的组合时,直接通过构造函数创建可能会导致代码混乱、难以...
建造者模式,是一种创建型设计模式,它提供了一种创建对象的最佳方式,特别是在对象的构建过程比较复杂,需要多个步骤时。在建造者模式中,我们创建一个指导对象(Director),该对象负责组织构建过程,而具体的构建...
建造者模式(Builder Pattern)是软件工程中一种用于创建对象的抽象工厂方法,它将复杂的构建过程分解为一系列步骤,使得构建过程可以独立于其表示进行。这种模式允许客户端使用相同的构建过程创建不同表现形式的...
设计模式通常分为三类:创建型模式(如工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式),结构型模式(如适配器模式、装饰器模式、代理模式、桥接模式、组合模式、外观模式、享元模式)以及行为型模式(如...
代理模式(Proxy Pattern)、单例模式(Singleton Pattern)、工厂方法...建造者模式(Builder Pattern)、桥梁模式(Bridge Pattern)、命令模式(Command Pattern)、装饰模式(Decorator Pattern)、迭代器模式...
建造者模式(Builder)是Java设计模式中的一种创建型模式,它允许我们分步骤构建复杂的对象,而无需暴露其构造过程。在Android开发中,这种模式尤其有用,因为Android组件如Activity、Fragment等的初始化过程通常...
建造者模式,是Java设计模式中的重要组成部分,它在软件工程中扮演着构造复杂对象的角色。这个模式的主要目的是将对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示。通过使用建造者模式,我们可以...
- 建造者模式(Builder):将复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 - 对象池模式(Pool):通过重用已创建的对象来减少对象的创建和销毁次数。 2. **结构型模式**:这类模式...