在閱讀了設計模式書并在線查看了構建器模式示例后,我注意到在最終的“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);
}
}
uj5u.com熱心網友回復:
第一個似乎更糟。原始構建器隨后可用于修改構建物件的狀態,因為它仍然持有對它的參考。
MazeBuilder builder = new MazeBuilderImpl();
Maze maze = builder.rooms(1).build();
builder.rooms(2); // modifies the state of maze ...
第二個中的副本防止這種情況發生,并允許重復使用構建器。
兩者都不好,因為 Maze 被暗示是可變的。構建器最適合構建不可變物件。它需要將Maze 的欄位重新宣告為MazeBuilder 的欄位,即如果Maze 有String id欄位,則MazeBuilder 也會。Lombok可以幫助減少該樣板檔案。
uj5u.com熱心網友回復:
如果您回傳與構建器中相同的物件,如下所示:
@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://www.uj5u.com/caozuo/520199.html
標籤:爪哇哎呀设计模式建设者
