我應該在意人們是否會重新使用相同的構建器對象?
那麼你想觀察副作用,但我認爲這就是你問的原因,因爲你知道人們/代碼會在構建器中留下垃圾。
所以,我應該有一個「reset()」方法來清除所有可選參數;
我認爲,如果你傳遞一個構建器,清理的責任應該在消費者(將構建器作爲輸入的函數或類)上。所以我們不會造成副作用。例如:
public class SomeClass {
public SomeClass(Log.Builder builder){
builder.tag("SomeClass"); //bad, we caused a side effect
//someone class forgets to set the tag
//later, then they get this tag
log = builder.build();
}
}
一個解決方案是提供一個拷貝構造函數:
public class SomeClass {
public SomeClass(Log.Builder builder){
Log.Builder localBuilder = new Log.Builder(builder); //copy constructor being used.
localBuilder.tag("SomeClass"); //only applies to the local builder
log = localBuilder.build();
} //builder is as it was before the call, no side effect
}
你甚至可以調用SomeClass
一份副本,這樣你就不需要關心它是否被實現爲無副作用或不:
Log.Builder defaults = new Log.Builder(...whatever...).tag("notag");
new SomeClass(new Log.Builder(defaults));
new SomeClass2(new Log.Builder(defaults));
爲了進一步鎖定下來,你可以有一個接口Log.ReadOnlyBuilder
它沒有制定者,是真的只用於建築或c好reating副本:
public class Log {
public interface ReadOnlyBuilder {
Builder copy();
Log build();
}
public static class Builder implements ReadOnlyBuilder {
Builder tag(String tag){
...
}
}
}
public class SomeClass {
public SomeClass(Log.ReadOnlyBuilder builder){
log = builder.copy().tag("SomeClass").build();
} //builder is as it was before the call, no side effect
}
我喜歡這一點,因爲責任是回到了消費者不會引起副作用,但它是強制執行,雖然類型和接口。另外如果他們不需要設置任何字段,他們可以只使用只讀構建器,我們不必爲了以防萬一。
P.S.我不認爲可選的和要求的是您想要決定要重置什麼和要設置什麼的劃分點。我認爲複製構造函數應該將構建器中的每個字段複製到新構建器。但是你可以自由地開發copy
方法/構造函數,但是你喜歡。