[英]Composition best practice with internal object instantiation
我在玩作曲,有一個問題。 說我有一個Fruit
和Apple
課程,其中apple
是水果的傳遞
public class Apple {
Fruit fruit;
}
水果具有許多成員字段,例如skin
, color
等。實例化Apple
對象時的最佳實踐是什么? 我是否應該在內部構造fruit
對象而沒有任何跡象表明蘋果包含水果對象? 即,在構造Apple對象時,我調用apple.setColor()
,它在內部設置了fruit.setColor()
屬性。 還是應該構造完整的fruit
對象,並在apple
實例化過程中傳遞完全構造的fruit
對象?
這實際上取決於您如何建模問題。 但是我認為關注OOP的封裝原理會有所幫助。 封裝要求我們在其內部隱藏有關對象的信息,或者換句話說,賦予每個對象執行其自己的動作的責任。
回到您的問題,首先讓我們考慮“ Fruit
對象只是基礎數據結構的情況(即Apple
對象是“ Fruit
”職責的完整超集)。 在這種情況下,如果您要求開發人員為您構造Fruit
對象並將其傳遞,則您將承擔內部責任,並且可能使開發人員可以訪問不需要的數據或行為。
Fruit f = new Fruit();
f.doSomethingPrivate(); // This is not intended for an Apple to be set externally
Apple a = new Apple(f); // Now the Fruit object may not comply with Apple definition
現在很明顯,在某些情況下,上面的示例正是您要執行的操作。 現在考慮合成模式(請參閱此處 )。 在組合中,您有一個容器 ,預計該容器不會封裝其所包含元素的職責。
一個非常簡單的示例可以是一門大學課程,其中一些學生報名並有一名講師:
public class Course {
private Person instructor;
private Person[] students;
}
在這里,暴露老師或學生的行為不是Course
對象的責任。 相反,容器對象可以具有getInstructor()
和setInstructor()
方法,並讓開發人員確定合成中包含的元素。
好像在蘋果里面有水果很奇怪。 在這種情況下,我將使用繼承。 或者至少讓Apple實現了Fruit接口並隱藏委托成員。 因此,對於構造Fruit成員而言,這意味着:在Apple構造函數內部進行此操作。 這是由於Apple和Fruit概念之間的is-關系。
在其他情況下,為構造函數中的成員傳遞預構造實例可能會很有用。 例如,如果更多的蘋果引用了相同的水果實例,情況就是這樣。 通常,Apple和Fruit之間更像是has-a或use關系
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.