一、什么是建造者模式
将建造过程与表示分离
建造者模式可以让相同的建造过程有不同的具体表现,把建造的流程隐藏,外界只需要告知建造对象的类型.整个建造者的组成部分有哪些是固定的,具体该如何实现这些不部分,可以不同.
UML图
Build: 负责规定建造对象所需要的组成部分,使用抽象方法,缺一不.
ConcreteBuild:建造者的具体实现类,各个组成部分具体是实现什么在这里确定
Product:产品类,给ConcreteBuild类提供具体产品
Director:导演类,在这里对具体的建造者的组成部分进行组装
二、适用场景
建造者模式适用于那些具有复杂构成的对象,外界又不必关心该对象是如何组成构建的情况.比如一碗拉面,由面、汤头、臊子、佐料组成,这是必要的组成部分,可客人不需要知道你怎么做的,我就只要一碗牛肉拉面,那你就给我做好了呈上来就行。当创建对象的复杂算法独立该对象的组成部分以及装配方式时适用。
三、优缺点
优点
建造者独立易于扩展
便于控制细节风险
缺点
具体建造者必须有共同点,范围有限制
如果内部变化复杂,会有很多建造者
四、大话中的例子
画胖子和画瘦子的例子,画一个胖子需要一个头,两只手,一个身子,两条腿,画瘦子也是这样,只不过画身子的尺寸大小不一样。在抽象建造者类里面确定好 实现 头、手、 身子、腿的抽象方法, 具体的胖子或者瘦子建造者类里面那就去实现这些抽象方法,不会有遗漏,然后导演类将这些部分组合起来,形成完整的对象,供外界调用。
五、我的例子
using System;
using System.Collections.Generic;
namespace BuildMode
{
class Program
{
static void Main(string[] args)
{
PayneSixDirector payneSixDirector = new PayneSixDirector();//实例导演
EarlyPayneSix changmen = new EarlyPayneSix();//长门
LaterPayneSix daitu = new LaterPayneSix();//带土
payneSixDirector.Construt(changmen);//我要找长门的六道,具体那六道,我不管,你自己弄.
payneSixDirector.Construt(daitu);//我要找带土的六道,具体那六道,我不管,你自己弄.
Console.WriteLine("==========第一代佩恩六道===========");
changmen.Result().Show();//展示组成者
Console.WriteLine("==========第二代佩恩六道===========");
daitu.Result().Show();
Console.ReadKey();
}
}
/// <summary>
/// 佩恩六道抽象类
/// </summary>
public abstract class PayneSix
{
protected ConstituteMember constituteMember;//组成成员
public PayneSix()
{
constituteMember = new ConstituteMember();
}
/// <summary>
/// 天道
/// </summary>
public abstract void SetHeaven();
/// <summary>
/// 修罗道
/// </summary>
public abstract void SetShura();
/// <summary>
/// 人间道
/// </summary>
public abstract void SetEarth();
/// <summary>
/// 畜生道
/// </summary>
public abstract void SetAnimal();
/// <summary>
/// 饿鬼道
/// </summary>
public abstract void SetHungryGhost();
/// <summary>
/// 地狱道
/// </summary>
public abstract void SetHell();
public abstract ConstituteMember Result();
}
/// <summary>
/// 早期的佩恩六道
/// </summary>
public class EarlyPayneSix : PayneSix
{
public override ConstituteMember Result()
{
return constituteMember;
}
public override void SetAnimal()
{
constituteMember.Add(new Ninja("畜生道·风褚"));//我可以放不同的忍者,但是必须有畜生道以及其它五道.
}
public override void SetEarth()
{
constituteMember.Add(new Ninja("人间道·泷隐土刃"));//这就是固定组成部分相同,但具体实现不同
}
public override void SetHeaven()
{
constituteMember.Add(new Ninja("天道·弥彦"));
}
public override void SetHell()
{
constituteMember.Add(new Ninja("地狱道·火迪"));
}
public override void SetHungryGhost()
{
constituteMember.Add(new Ninja("饿鬼道·雷偔"));
}
public override void SetShura()
{
constituteMember.Add(new Ninja("修罗道·水宿"));
}
}
/// <summary>
/// 后期的佩恩六道
/// </summary>
public class LaterPayneSix : PayneSix
{
public override ConstituteMember Result()
{
return constituteMember;
}
public override void SetAnimal()
{
constituteMember.Add(new Ninja("畜生道·芙"));
}
public override void SetEarth()
{
constituteMember.Add(new Ninja("人间道·羽高"));
}
public override void SetHeaven()
{
constituteMember.Add(new Ninja("天道·由木人"));
}
public override void SetHell()
{
constituteMember.Add(new Ninja("地狱道·老紫"));
}
public override void SetHungryGhost()
{
constituteMember.Add(new Ninja("饿鬼道·矢仓"));
}
public override void SetShura()
{
constituteMember.Add(new Ninja("修罗道·樊"));
}
}
public class PayneSixDirector
{
/// <summary>
/// 组合建造,根据你传过来的建造者(佩恩六道)
/// </summary>
/// <param name="payneSix"></param>
public void Construt(PayneSix payneSix)
{
payneSix.SetAnimal();
payneSix.SetEarth();
payneSix.SetHeaven();
payneSix.SetHell();
payneSix.SetHungryGhost();
payneSix.SetShura();
}
}
/// <summary>
/// 组成成员
/// </summary>
public class ConstituteMember
{
List<Ninja> ninjasList;
public ConstituteMember()
{
ninjasList = new List<Ninja>();
}
public void Add(Ninja ninja)
{
ninjasList.Add(ninja);
}
public void Show()
{
foreach (Ninja item in ninjasList)
{
Console.WriteLine(item.Name);
}
}
}
/// <summary>
/// 忍者
/// </summary>
public class Ninja
{
string _name;
public string Name { get { return _name; } set { _name = value; } }
public Ninja(string name)
{
_name = name;
}
}
}
运行结果
PS:起初觉得建造者模式和外观模式挺像的, 都是把低层次的接口封装到高层次的接口.都是把需要的一组方法写在一个方法里面,外界只需要调用这一个方法即可,但两者还是用差别,建造者模式是创建型,它的核心是将具有相同组成部分的流程归总起来,在一个方法里创建组成部分这些部分是规整的,一步步构造对象,如果不构造该对象是不完整的;而外观模式是一个结构型,它的核心是将一组方法放在一个方法里面,有点像委托,是不规整的,放什么方法,都可以.
用我的例子简单的说就是,建造者模式要求佩恩六道必须是六道,而外观模式并不强制要求,所以是不适用.外观模式灵活性更高.