目录
建造者模式
引言
定义
模式结构图
实例
实例描述
代码实现
建造者模式扩展
建造者模式的简化
抽象指挥者
总结
模式优点
模式缺点
无论是现实生活中还是软件系统中,都存在一些复杂的对象,它们拥有多个组成部分。如汽车,它包含车轮、方向盘、发动机等部件。对于大多数用户而言,无需知道这些部件的创造过程和汽车的装配细节,只需要通过汽车型号买到一辆完整的车。在软件系统中,对于一个复杂对象,用户只需要使用这个对象,而不关系这个复杂对象的具体创建过程。建造者模式可以将这种复杂对象的创建和使用解耦,用户只需要使用复杂对象,复杂对象的具体创建细节由创建者去关注。
英文定义:"Separate the construction of a complex object from its representation so that the same construction process can create different representations."。
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式包含如下角色:
(1)Builder(抽象建造者)
(2)ConcreteBuilder(具体建造者)
(3)Product(产品角色)
(4)Director(指挥者)
某游戏软件中人物角色包含多种类型,不同类型的人物角色,其性别、脸型、发型等外部特征有所差异,使用建造者模式创建人物角色对象。
通过分析,该实例类图如下:
指挥者类 Director
class Director
{
private CharactorBuilder builder;
public CharactorBuilder Builder { get => builder; set => builder = value; }
public Character Construct()
{
Builder.BuildFace();
Builder.BuildGender();
Builder.BuildHair();
return Builder.Character;
}
}
产品类Character(人物角色)
class Character
{
private string gender;
private string hair;
private string face;
public string Hair { get => hair; set => hair = value; }
public string Gender { get => gender; set => gender = value; }
public string Face { get => face; set => face = value; }
}
抽象建造者类CharacterBuilder(角色建造者类)
abstract class CharactorBuilder
{
private Character character = new Character();
public Character Character { get => character; set => character = value; }
public abstract void BuildGender();
public abstract void BuildFace();
public abstract void BuildHair();
}
具体建造者类ConcreteBuilderA(A角色建造者类)
class CharactorBuilderA : CharactorBuilder
{
public override void BuildFace()
{
Character.Face = "圆脸";
}
public override void BuildGender()
{
Character.Gender = "男性";
}
public override void BuildHair()
{
Character.Hair = "光头";
}
}
具体建造者类ConcreteBuilderB(B角色建造者类)
class CharactorBuilderB : CharactorBuilder
{
public override void BuildFace()
{
Character.Face = "方脸";
}
public override void BuildGender()
{
Character.Gender = "男性";
}
public override void BuildHair()
{
Character.Hair = "寸头";
}
}
具体建造者类ConcreteBuilderC(C角色建造者类)
class CharactorBuilderC : CharactorBuilder
{
public override void BuildFace()
{
Character.Face = "圆脸";
}
public override void BuildGender()
{
Character.Gender = "女性";
}
public override void BuildHair()
{
Character.Hair = "长发";
}
}
测试代码
class Program
{
static void Main(string[] args)
{
Director director = new Director();
director.Builder = new CharactorBuilderA();
Character c = director.Construct();
c.Desc();
Console.ReadKey();
}
}
运行结果
建造者模式再实际使用过程中通常可以进行简化,以下是几种常用的简化方式:
(1)省略抽象建造者角色:如果系统中只需要一个具体建造者的话,可以省略掉抽象建造者。如下图所示:
(2)省略指挥者角色:在具体建造者只有一个的情况下,如果已经省略抽象建造者,那么还可以省略指挥者角色,让Builder角色扮演指挥者与建造者双重角色。如下图所示:
指挥者Director类还可以抽象化,由具体的子类决定复杂对象的建造。这样做的好处是,如果某个复杂对象的建造过程有一定的次序,例如实例中人物要求先创建性别,再创建发型。又或者要求先创建脸型,再创建发型,那么开发人员修改的时候,就可以添加具体的指挥者子类,而不需要去修改指挥者,满足开闭原则。如下图所示:
(1)在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品。
(2)每一个具体建造者都相对独立。因此系统的可扩展性很好。
(3)可以更加精细地控制产品地创建过程。因为建造者模式将复杂产品地创建步骤定义在指挥者类的模板方法中,而具体的创建过程定义在不同的方法中,使得创建过程更加清晰。
(1)建造者模式所创建的产品需要有较多的共同点,因此建造者模式的使用有一定的限制性。
(2)如果产品内部变化复杂,可能会导致需要定义较多的具体建造者类来实现这种变化,导致系统变得很庞大。