设计模式 — 生成器模式 (Builder)

本文通过C++展示了生成器模式的应用,用于构建复杂的房间对象。生成器模式允许客户通过CreateRoom函数直接获得完整的房间,而不是分别获取门、窗、墙。相比抽象工厂模式,生成器更专注于构建最终对象并隐藏装配细节,提供更大的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文使用C++来介绍生成器模式。

小新接到客户需求,需要建造一个房间,该房间非常简单,由门、窗和墙组成,客户希望通过CreateRoom函数来完成房间的建造。在上一节,小新使用抽象工厂模式,帮助客户解决了这个问题。

小新善于思考,再一次分析上一节抽象工厂模式方案。在该方案中,抽象工厂可以给客户返回Room(房间)、Door(门)、Window(窗)、Wall(墙)对象,客户将这些对象组装成目标房间对象。

“客户只是想要一个建好的房间,其实并不需要单独的门、窗和墙啊。”小新心想,能不能把门、窗和墙的建造都放在我的工厂中,最后直接返回给客户建好的房间呢?小新心里规划出生成器的模型,写出了以下代码。

class RoomBuilder {
public:
    virtual void BuildRoom() { }
    virtual void BuildDoor() { }
    virtual void BuildWindow() { }
    virtual void BuildWall() { }

    virtual Room* GetRoom() { return 0; }
protected:
    RoomBuilder();
};
客户可以按照如下方式使用RoomBuilder类。

Room* CreateRoom(RoomBuilder& builder) {
    builder.BuildRoom();
    
    builder.BuildDoor();
    builder.BuildWindow();
    builder.BuildWall();

    return builder.GetRoom();
}
可以看到客户在使用过程中,并没有接触到门、窗和墙对象,客户通过发送指令(调用相应函数),所有的生成都在生成器中完成,最后最后客户通过指令(GetRoom)得到建好的房间。

有了这个生成器模型,小新的思路越发的清晰。客户如果要求建造一个木门(WoodenDoor)、隔音墙(SoundProofWindow)和绿墙(GreenWall),则派生出一个具体类即可,这里我们使用WsgRoomBuilder来命名(由于本文主要介绍设计模式,所以成员函数的实现直接写在类中,也没有相关安全性的检测)。

class WsgRoomBuilder : public RoomBuilder {
public:
    RoomBuilder() { _currentRoom = 0; }
    
    virtual void BuildRoom() { _currentRoom = new Room; }
    virtual void BuildDoor() { WoodenDoor* aDoor = new WoodenDoor; _currentRoom->AddDoor(aDoor); }
    virtual void BuildWindow() { SoundProofWindow* aWindow = new SoundProofWindow; _currentRoom->AddWindow(aWindow); }
    virtual void BUildWall() { GreenWall* aWall = new GreenWall; _currentRoom->AddWall(aWall); }

    virtual Room* GetRoom() { return _currentRoom; }
private:
    Room* _currentRoom;
};

该类增加一个_currentRoom成员变量来存放建造过程中的房间,并在用户调用GetRoom时返回该对象。客户可以使用如下方式来建造房间。

WsgRoomBuilder builder;
Room* room = CreateRoom(builder);
要想建造红色的房间,则继承RoomBuilder类,并且重载BuildWall函数即可。

使用生成器模式,小新也可以完成客户的需求。那它和抽象工厂模式有什么区别呢?小新思考了以下总结如下:

1、生成器着重于结果的呈现,即着重于构造最终的对象。抽象工厂着重于多个产品。在该例中,生成器着重于生成最终的房间对象,而抽象工厂着重于将房间、门、窗、墙等产品交付客户,这也说明第二点区别。

2、生成器在最后一点返回产品,而抽象工厂立即返回过程中使用到的产品。也就是说,生成器将装配方式隐藏在类中。


生成器模式适用于以下情况(参考自《设计模式》)

1、当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。

2、当构造过程必须允许被构造的对象有不同的表示时。


生成器模式的效果包括(参考自《设计模式》)

1、因为生成器模式隐藏了产品的装配方式,因此它使你可以改变一个产品的内部表示。

2、它将构造代码和表示代码分开,如在本例中,客户不需要知道Door、Window、Wall的存在以及Room的AddDoor等方法。

3、它使你可对构造过程进行更精细的控制。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值