5

我想知道我是否可以实现 Builder 设计模式,但没有从中派生具体构建器的接口/抽象类?我可以只有一个 builder 吗?

如果我只有一个concretebuilder和一个director,它仍然是builder设计模式吗?

更加具体:

我有一些对象想“组合”成一个复杂的对象。更准确地说,我有以下课程:

门墙房

我想从这些类中构建一个“世界”,即所有这些类组合起来给我一个世界。

谢谢

4

3 回答 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,以便您获得此 ID,这允许您引用尚未加载的对象:

Door door = new Door(roomOneId, roomTwoId);

但是如果文件中有错误并且房间 2 从未定义过,那么 World 将是无效的。

Builder 可以处理正确构造、连接和验证 World 创建过程的所有细节,为想要创建世界的客户端代码提供灵活性,并释放复杂构造逻辑的 World 对象。

于 2012-09-21T15:45:55.670 回答
2

您可以将构建器模式与访问者模式结合起来:将某种数据树传递给构建器,每个构建器都实现一个accept(Visitor v)方法,并让构建器遍历树,通过接受方法将每个节点传递回访问者。

于 2012-09-20T20:13:28.070 回答
2

如果我只有一个concretebuilder和一个director,它仍然是builder设计模式吗?

我不会在一开始就挂断这个问题。如果您的项目只需要构建一种类型的“世界”,并且您确实不需要多个构建器子类,那么使用导向器和单个具体构建器是一种有效的方法。而是专注于模式的精神——即将你的导演与世界应该如何构建的细节隔离开来。

一旦您的代码正常工作并且您对结果感到满意,请返回并查看您的主管和构建器的实际交互方式。然后考虑重构构建器以提取一个通用接口,以真正确定主管和构建器之间的合同。

我发现从工作的具体类中提取一个合理的接口要容易得多,然后尝试预先猜测这个接口可能是什么,并尝试同时开发接口和类。

于 2012-09-20T21:33:15.813 回答