すべてのパラメータを上から下に渡してオブジェクトの階層を初期化するのは珍しいことを心配するのは正しいです。
講師は、Compositeパターンの線に沿って何かを実装することをほのめかしている可能性があります。これにより、階層内の各クラスが共通のメソッドを共有します(例getValue()
)。Product
(つまりリーフノード)の場合、これは単に製品の値を返しますが、aStore
またはの場合は、構成要素s(またはs)Company
を反復処理して、結果を呼び出して合計します。Product
Store
getValue()
これと上記で記述したものとの主な違いは、通常Product
、別のオブジェクトからデータを渡すのではなく、コンストラクターを介してそれぞれを個別に初期化することです。製品が不変である場合は、そのフィールドをとしてマークすることを選択できますfinal
。次に、階層内の他のクラスにユーティリティメソッドを追加することを選択できます(例moveProduct(Store store1, Store store1)
)。言い換えると、他のクラスは単なる「データコンテナ」ではなく動作を示します。
例
/**
* Optional interface for uniting anything that can be valued.
*/
public interface Valuable {
double getValue();
}
/**
* Company definition. A company's value is assessed by summing
* the value of each of its constituent Stores.
*/
public class Company implements Valuable {
private final Set<Store> stores = new HashSet<Store>();
public void addStore(Store store) {
this.stores.add(store);
}
public void removeStore(Store store) {
this.stores.remove(store);
}
public double getValue() {
double ret = 0.0;
for (Store store : stores) {
ret += store.getValue();
}
return ret;
}
}
/**
* Store definition. A store's value is the sum of the Products contained within it.
*/
public class Store implements Valuable {
private final List<Product> products = new LinkedList<Product>();
public void addProduct(Product product) {
this.products.add(product);
}
public void removeProduct(Product product) {
this.products.remove(product);
}
public double getValue() {
double ret = 0.0;
for (Product product : products) {
ret += product.getValue();
}
return ret;
}
}
/**
* Product definition. A product has a fixed inherent value. However, you could
* always model a product to depreciate in value over time based on a shelf-life, etc.
* In this case you might wish to change the Valuable interface to accept a parameter;
* e.g. depreciationStrategy.
*/
public class Product implements Valuable {
private final double value;
public Product(double value) {
this.value = value;
}
public double getValue() {
return value;
}
}