建造者模式

一、概念

建造者模式是一种创建型设计模式,它将客户端与包含多个部件的复杂对象的创建过程分离,客户端无须知道复杂对象的内部组成部分装配方式,只需知道建造者的类型即可。建造者模式关注如何一步一步地创建一个复杂的对象,不同的具体建造者者定义了不同的建造过程,而且具体的建造者相互独立。

定义:又称生成器将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表现。

二、模式结构

产品(Product):表示正在构建的复杂对象,它通常由多个部分组成。具体建造者创建该产品的内部表示并定义它的装配过程

抽象建造者(Abstract Builder):定义了构建产品的抽象接口,包括构建各个部分的方法以及装配过程方法。

具体建造者(Concrete Builder):实现了抽象建造者接口,实现了各个部件的具体构造装配方法,定义并明确所创建的复杂对象。

指导者(Director):负责使用具体建造者来构建产品,它负责安排负责对象的构建次序。

image-20240616170754882

三、具体实现

使用建造者模式来实现游戏角色的创建,对游戏角色进行设计,其基本结构如下图所示。

image-20240616171001577

3.1 角色类(产品类)

public class Actor
{
    private string type;            // 角色类型
    private string sex;             // 性别
    private string face;            // 脸型
    private string costume;         // 服装
    private string hairStyle;       // 发型

    public void SetType(string type)
    {
        this.type = type;
    }

    public void SetSex(string sex)
    {
        this.sex = sex;
    }

    public void SetFace(string face)
    {
        this.face = face;
    }

    public void SetCostume(string costume)
    {
        this.costume = costume;
    }

    public void SetHairStyle(string hairStyle)
    {
        this.hairStyle = hairStyle;
    }

    public string getType() { return type; }
    public string getSex() {  return sex; }
    public string getFace() { return face; } 
    public string getCostume() {  return costume; }
    public string getHairStyle() {  return hairStyle; }

}

3.2 角色建造者(抽象建造者)

public abstract class ActorBuilder
{
    protected Actor actor = new Actor();

    public abstract void BuildType();
    public abstract void BuildSex();
    public abstract void BuildFace();
    public abstract void BuildCostume();
    public abstract void BuildHairStyle();

    public Actor CreateActor()
    {
        return actor;
    }

}

3.3 角色具体建造类(具体建造者)

public class HeroBuilder : ActorBuilder
{
    public override void BuildCostume()
    {
        actor.SetCostume("盔甲");
    }

    public override void BuildFace()
    {
        actor.SetFace("飘逸");
    }

    public override void BuildHairStyle()
    {
        actor.SetHairStyle("飘逸");
    }

    public override void BuildSex()
    {
        actor.SetSex("男");
    }

    public override void BuildType()
    {
        actor.SetType("英雄");
    }
}

public class AngleBuilder : ActorBuilder
{
    public override void BuildCostume()
    {
        actor.SetCostume("白裙");
    }

    public override void BuildFace()
    {
        actor.SetFace("漂亮");
    }

    public override void BuildHairStyle()
    {
        actor.SetHairStyle("披肩长发");
    }

    public override void BuildSex()
    {
        actor.SetSex("女");
    }

    public override void BuildType()
    {
        actor.SetType("天使");
    }
}

public class DevilBuilder : ActorBuilder
{
    public override void BuildCostume()
    {
        actor.SetCostume("黑衣");
    }

    public override void BuildFace()
    {
        actor.SetFace("丑陋");
    }

    public override void BuildHairStyle()
    {
        actor.SetHairStyle("光头");
    }

    public override void BuildSex()
    {
        actor.SetSex("妖");
    }

    public override void BuildType()
    {
        actor.SetType("恶魔");
    }
}

3.4 角色控制器(指挥者)

    public class ActorController
    {
        public Actor construct(ActorBuilder actorBuilder)
        {
            Actor actor;
            actorBuilder.BuildType();
            actorBuilder.BuildSex();
            actorBuilder.BuildFace();
            actorBuilder.BuildCostume();
            actorBuilder.BuildHairStyle();
            actor = actorBuilder.CreateActor();
            return actor;
        }
    }

3.5 客户测试类

public class Client
{
    static void Main(string[] args)
    {
        ActorBuilder builder = new DevilBuilder();
        ActorController actorController = new ActorController();
        Actor actor = actorController.construct(builder);
        Console.WriteLine(actor.GetType() + "的外观: ");
        Console.WriteLine("性别: " + actor.getSex());
        Console.WriteLine("面容: " + actor.getFace());
        Console.WriteLine("服装: " + actor.getCostume());
        Console.WriteLine("发型: " + actor.getHairStyle());

    }
}

四、优缺点

  • 优点:
    1. 分离构建过程和表示,使构建过程更加灵活,可以创建不同的表示。
    2. 可以更好地控制构建过程,隐藏具体地构建细节。
    3. 每个具体构建者都相对独立,可以在不同地构建过程中重复使用相同地建造者。
  • 缺点:
    1. 如果产品地内部复杂,可能会导致需要定义很多具体构造者来实现这种变化,会导致系统变得很庞大。
    2. 当产品属性比较少,建造者模式可能会导致代码冗余。

五、 使用环境

  • 结构复杂:当对象具有非常复杂的内部结构,包含许多属性时,建造者模式适用。
  • 分离创建和使用:如果想将复杂对象的创建和使用分离,建造者模式是一个不错的选择。
  • 多步骤构建:当创建对象需要多个步骤时,建造者模式非常适合。