在阅读了Design书籍并在线查看了Builder示例之后,我注意到在最后的"build()“方法中有两种不同的返回对象的方法。我想知道在以下几个方面之间有什么区别:
简单地返回我们正在构建的maze
public class MazeBuilderImpl implements MazeBuilder {
private Maze maze;
@Override
public MazeBuilder builder() {
maze = new Maze();
return this;
}
// adding rooms, doors etc.
@Override
public Maze build() {
return maze;
}
}将maze作为构造函数中的参数传递并返回
public class MazeBuilderImpl implements MazeBuilder {
private Maze maze;
@Override
public MazeBuilder builder() {
maze = new Maze();
return this;
}
// adding rooms, doors etc.
@Override
public Maze build() {
return new Maze(maze);
}
}发布于 2022-10-25 10:56:20
第一个似乎更糟。随后,可以使用原始构建器来修改已构建对象的状态,因为它仍然持有对它的引用。
MazeBuilder builder = new MazeBuilderImpl();
Maze maze = builder.rooms(1).build();
builder.rooms(2); // modifies the state of maze ...第二个副本防止这种情况发生,并允许重新使用构建器。
这两者都是坏的,因为迷宫暗示是可变的。构建器是构建不可变对象的最佳方法。它要求将迷宫的字段重新声明为MazeBuilder的字段,也就是说,如果迷宫有一个String id字段,那么MazeBuilder也会。隆布克可以帮助减少样板。
发布于 2022-10-25 10:59:44
如果您返回与生成器中相同的对象,如下所示:
@Override
public Maze build() {
return maze;
}然后,您将引用生成器中存在的相同对象。它仍然可以被静音(改变)。所以你的目标可能仍然是从某个地方改变的。它仍然是一个对象,您可以直接影响或通过建设者。
如果返回不同的对象,则不必担心在调用build()后构建器会影响它。
但是,如果您的对象可以是不可变的,那么在构建器中拥有对象字段的副本和在build()方法中构造对象是常见的。
public class MazeBuilderImpl implements MazeBuilder {
private Room roomA;
private Room roomB;
private Door doorA;
private Door doorB;
....
// adding rooms, doors etc.
@Override
public Maze build() {
return new Maze(roomA, roomB, doorA, doorB, ...);
}
}https://stackoverflow.com/questions/74192833
复制相似问题