2011-06-17 85 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构造变得更大,并且扩展到很多很多的子类。