2011-06-17 84 views
2

我有一大堆的類,如:OO設計問題

abstract class Product { 
    BigDecimal price 
    String name 
} 

class EdibleProduct extends Product { 
    Date sellByDate 
} 

class FinancialProduct extends Product { 
    Currency currency 
} 

在現實中有2級以上的子類,每個子類將多個屬性添加到父。我想用這些類與API,如:

interface ProductDao {  

    Product create(Product product) 
    Product update(Product product) 
} 

通過上面提出的幼稚模型中,一個需要做這樣的事情的ProductDao方法的實現內

Product create(Product product) { 
    // save the fields common to all Products 

    if (product instanceof EdibleProduct) { 
    // save fields specific to this implementation  

    } else if (product instanceof FinancialProduct) { 
    // save fields specific to this implementation  
    } 
} 

顯然,像這樣投射到執行類型很糟糕,所以我正在尋找創建,更新等不同類型產品的方法,而不涉及實現類型(至少在ProductDao實現中)。

我已考慮過多種解決方案,其中大部分涉及移除子類和移動產品的具體領域爲單獨的類,都實現了相同的接口,像

interface ProductType {} 

class EdibleProductType { 
    Date sellByDate 
} 

class FinancialProductType { 
    Currency currency 
} 

再加入ProductTypeProduct。我也考慮過使用裝飾器,但似乎不能避免沮喪。

實現語言將是Java或Groovy。

回答

-1

看來,我假設你正在使用的Java/Groovy版本可以做到這一點,你需要一個接口,你可以變形到這些對象中的任何一個。

換句話說,有一個IProduct,只是使用它,使用動態類型,然後將在運行時根據它從屬性的角度具有的行爲。

2

如果ProductDao.create只是複製它的參數,添加新的方法到產品的界面就像

public Product createCopy(); 

,然後每個具體類中,它會知道如何使自身的副本,例如,一個拷貝構造函數。因此,對於EdibleProduct你可能有:

public Product createCopy() { 
    return new EdibleProduct(this); 
} 

public EdibleProduct(EdibleProduct rhs) { 
    // copy construct 
} 
2

如果您不能使用Dave的答案(因爲這將是問題的,將代碼放在產品本身),你可能想看看Visitor Pattern,這是正是這個開發問題類型。

+1

據我瞭解_Visitor_,你仍然需要'產品'中的'acceptVisitor()'。你能否提供支持你想法的代碼片段? –

+0

@Op De Cirkel是的,您仍然需要修改產品,但不必將數據庫代碼放入產品。 –

0

你想要的是Chain of Reponsibilty模式。在Set中有Product的每個子類型的實例,並且只是步行Set並且每個子類別都調用.create(final Product p);,他們將決定該類型是否是正確的,並且做他們需要做的事情。這使得令人討厭的if/elseif構造變得更大,並且擴展到很多很多的子類。