建造者模式

简介

建造者模式(Builder Pattern)是一种创建型设计模式,用于构建复杂对象。它的主要目的是将对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示形式。这种模式通常适用于创建对象的参数较多,且某些参数之间存在复杂的依赖关系的情况。

在建造者模式中,通常会有一个建造者(Builder)接口或抽象类,定义了构建对象所需的各种方法。然后有一个具体的建造者类实现了这个接口,负责实际构建对象的过程。最后,还有一个指挥者(Director)类,它负责根据一定的构建流程,使用建造者来构建对象。

案例

假设你是一位房屋装修公司的项目经理,你负责根据客户的需求和喜好来设计他们的家居装修方案。这个场景也可以很好地使用建造者模式来完成。

在这个场景中:

  1. 产品(Product):家居装修方案,包含客厅装修、卧室装修、厨房装修等。
  2. 抽象建造者(Builder):装修方案建造者接口,定义了构建装修方案所需的各种方法,如设计客厅、设计卧室、设计厨房等。
  3. 具体建造者(ConcreteBuilder):实现了装修方案建造者接口,负责根据客户的需求和喜好构建装修方案。
  4. 指挥者(Director):负责指导具体的构建过程,根据客户的需求来决定如何调用具体建造者来构建装修方案。
  5. 客户端(Client):客户通过与项目经理沟通,提供自己的需求和喜好,最终得到定制的家居装修方案。

例如,客户可能希望他们的客厅采用现代风格,卧室采用简约风格,厨房采用欧式风格。具体的构建过程可能是:

  1. 客户提供客厅现代风格的需求,指挥者调用具体建造者来设计现代风格的客厅。
  2. 客户提供卧室简约风格的需求,指挥者调用具体建造者来设计简约风格的卧室。
  3. 客户提供厨房欧式风格的需求,指挥者调用具体建造者来设计欧式风格的厨房。

最终,客户得到了一个定制的家居装修方案,满足了他们的需求和喜好。

通过建造者模式,你可以很好地实现家居装修方案的定制功能,使客户可以根据自己的喜好和需求来设计自己的家居装修,而不需要知道装修方案是如何构建的具体细节。

using System;

// 产品类 - 家居装修方案
class HouseDecorationPlan
{
    public string LivingRoom { get; set; }
    public string Bedroom { get; set; }
    public string Kitchen { get; set; }

    public override string ToString()
    {
        return $"Living Room: {LivingRoom}, Bedroom: {Bedroom}, Kitchen: {Kitchen}";
    }
}

// 抽象建造者接口
interface IHouseDecorator
{
    void DecorateLivingRoom(string style);
    void DecorateBedroom(string style);
    void DecorateKitchen(string style);
    HouseDecorationPlan GetHouseDecorationPlan();
}

// 具体建造者类
class SimpleHouseDecorator : IHouseDecorator
{
    private HouseDecorationPlan _plan = new HouseDecorationPlan();

    public void DecorateLivingRoom(string style)
    {
        _plan.LivingRoom = style;
    }

    public void DecorateBedroom(string style)
    {
        _plan.Bedroom = style;
    }

    public void DecorateKitchen(string style)
    {
        _plan.Kitchen = style;
    }

    public HouseDecorationPlan GetHouseDecorationPlan()
    {
        return _plan;
    }
}

// 指挥者类
class ProjectManager
{
    private IHouseDecorator _decorator;

    public ProjectManager(IHouseDecorator decorator)
    {
        _decorator = decorator;
    }

    public void BuildHouse(string livingRoomStyle, string bedroomStyle, string kitchenStyle)
    {
        _decorator.DecorateLivingRoom(livingRoomStyle);
        _decorator.DecorateBedroom(bedroomStyle);
        _decorator.DecorateKitchen(kitchenStyle);
    }
}

// 客户端
class Client
{
    static void Main(string[] args)
    {
        // 创建具体建造者
        IHouseDecorator decorator = new SimpleHouseDecorator();

        // 创建指挥者
        ProjectManager manager = new ProjectManager(decorator);

        // 指挥者根据客户需求来构建房屋装修方案
        manager.BuildHouse("Modern", "Simple", "European");

        // 客户获取装修方案
        HouseDecorationPlan plan = decorator.GetHouseDecorationPlan();

        // 输出装修方案
        Console.WriteLine("House Decoration Plan:");
        Console.WriteLine(plan);
    }
}

类图

@startuml

class HouseDecorationPlan {
    +LivingRoom: string
    +Bedroom: string
    +Kitchen: string
    +ToString(): string
}

interface IHouseDecorator {
    {abstract} +DecorateLivingRoom(style: string)
    {abstract} +DecorateBedroom(style: string)
    {abstract} +DecorateKitchen(style: string)
    {abstract} +GetHouseDecorationPlan(): HouseDecorationPlan
}

class SimpleHouseDecorator {
    -_plan: HouseDecorationPlan
    +DecorateLivingRoom(style: string)
    +DecorateBedroom(style: string)
    +DecorateKitchen(style: string)
    +GetHouseDecorationPlan(): HouseDecorationPlan
}

class ProjectManager {
    -_decorator: IHouseDecorator
    +ProjectManager(decorator: IHouseDecorator)
    +BuildHouse(livingRoomStyle: string, bedroomStyle: string, kitchenStyle: string)
}

IHouseDecorator <|.. SimpleHouseDecorator
IHouseDecorator <-- ProjectManager
HouseDecorationPlan <-- SimpleHouseDecorator

@enduml
类图代码

 

优点:

  1. 分离构建过程和表示:建造者模式可以将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示形式。这样,客户端不需要知道对象的具体构建细节,只需关心建造者接口及如何使用即可。

  2. 更好的封装性:客户端只需知道建造者接口,而不需要知道具体的建造过程,使得对象的构建过程与表示细节被封装在具体的建造者内部,对外部是透明的。

  3. 灵活性:可以根据需要定义不同的具体建造者,以构建不同的对象表示。同时,客户端可以根据需要指定具体的建造者,以获取所需的对象表示。

  4. 可读性:将构建过程分解为一系列步骤,使得代码更易读、更易维护。每个具体建造者负责自己的部分,使得代码结构更清晰。

  5. 可复用性:由于建造过程和表示被分离,可以通过复用相同的建造者或构建步骤来构建不同的对象,提高了代码的可复用性。

缺点:

  1. 增加了系统复杂性:引入建造者模式会增加系统中的类和对象数量,特别是在有多个产品对象需要构建的情况下,会增加具体建造者的数量。

  2. 需要额外的开发工作:相比直接创建对象,使用建造者模式需要额外定义建造者接口、具体建造者类以及指挥者类,增加了开发工作量。

  3. 不适用于对象较简单的情况:如果产品对象的构建过程相对简单,没有太多的参数设置或者参数之间的依赖关系,使用建造者模式反而会显得繁琐,不适用于此类情况。

  4. 增加了代码量:引入建造者模式会增加代码量,特别是在有多个产品对象需要构建的情况下,需要编写大量的具体建造者类和指挥者类,增加了代码的复杂性。

对比工厂模式

相同点:

  1. 都用于对象的创建:建造者模式和工厂模式都是用来创建对象的,它们都将对象的实例化过程封装起来,使得客户端不需要直接与具体的对象创建过程打交道。

  2. 都可以隐藏对象的创建细节:无论是建造者模式还是工厂模式,都可以将对象的创建过程隐藏起来,使得客户端无需了解对象的具体创建细节,只需与工厂或建造者接口交互即可。

不同点:

  1. 建造者模式 关注的是对象的构建过程,如何将一个复杂对象的构建过程分解为一系列步骤,并封装在具体建造者中。

  2. 工厂模式 关注的是对象的创建过程,根据不同的情况来创建不同的对象实例,隐藏了对象的具体创建过程。
posted @ 2024-02-28 09:08  咸鱼翻身?  阅读(7)  评论(0编辑  收藏  举报