建造者设计模式 - 没有抽象类/接口

5

我想知道是否可以实现建造者设计模式,但不需要从接口/抽象类中派生具体构建者?我只能有一个构建者吗?

如果我只有一个具体构建者和一个指导者,这仍然是建造者设计模式吗?

更具体地说:

我有一些对象,我想将它们组合成一个复杂的对象。更精确地说,我有以下类:

门 墙 房间

我想通过这些类来构建一个“世界”,也就是说,所有这些类组合起来给我一个世界。

谢谢

3个回答

3

是的,绝对可以拥有一个简单的WorldBuilder,其工作是创建由门、墙和房间组成的完全配置的世界。当您不想公开部分构建的、可能无效的World对象时,这非常有用。

假设使用该构建器的方式如下:

WorldBuilder builder = new WorldBuilder();

// read the definition of a room from an XML file or other source.
// this is vastily simplified, you'd probably be iteration 
// something like this:
//
//   for each Room in file
//      for each wall in room
//         for each door in wall
//
roomId = readRoomId();
wallId = readWallId();
doorId = readDoorId();
destRoomId = readDestinationRoomId();

builder.AddRoom(roomId);
builder.AddWallToRoom(roomId, wallId, SIDE.NORTH);
builder.AddDoorToWall(wallId, DOORSTYLE.WOODEN | DOORSTYLE.LOCKED, destRoomId);

// etc, etc

World world = builder.makeWorld();

一种非构建器方法可能会这样连接两个房间对象:
Door door = new Door(roomOne, roomTwo);

但是,如果您像以前一样从文件中迭代每个房间,则可能没有对第二个房间的引用,因为它可能尚未到达。

另一种方法是仅给每个对象其相邻对象或父对象的ID,因此您可以得到以下内容,这使您可以引用尚未加载的对象:

Door door = new Door(roomOneId, roomTwoId);

但是,如果文件中出现错误,房间2从未定义,则世界将无效。

构建器可以处理正确构建、连接和验证世界创建过程的所有细节,为希望创建世界的客户端代码提供灵活性,并减轻世界对象复杂构建逻辑的压力。


谢谢。这是我考虑的方法。我想我不需要一个导演吗? - mrjasmin
我会说,我发布的迭代 XML 文件的示例代码可以作为指导者。你完全可以使用另一个指导者从数据库中提取数据。无论哪种情况,构建器都可以保持不变,使指导者和构建器之间有一个清晰的分离。 - tcarvin

2
你可以将构建器模式和访问者模式相结合:将某种数据树传递给构建器,每个节点都实现了accept(Visitor v)方法,并让构建器遍历整棵树,通过accept方法将每个节点传递回访问者中。

嗨。我只能使用建造者模式。 - mrjasmin

2
如果我只有一个ConcreteBuilder和一个Director,那还算是建造者模式吗?在开始时,我不会被这个问题所困扰。如果您的项目只需要构建一种类型的“世界”,并且您真的不需要多个建造者子类,则使用Director和单个ConcreteBuilder是一种有效的方法。重点放在模式的精神上-即将您的Director与如何构建世界的细节隔离开来。一旦您的代码正常工作并且您对结果满意,请回顾一下您的Director和Builder实际上是如何交互的。然后考虑重构Builder以提取一个公共接口,以真正确定Director和Builder之间的合同。我发现从工作的具体类中提取出一个合理的接口要容易得多,而不是事先猜测这个接口可能是什么,并尝试同时开发接口和类。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接