OO设计问题

时间:2011-06-17 17:12:42

标签: java design-patterns language-agnostic oop

我有一堆类,如:

abstract class Product {
  BigDecimal price
  String name
}

class EdibleProduct extends Product {
  Date sellByDate
}

class FinancialProduct extends Product {
  Currency currency
}

实际上有两个以上的子类,每个子类都会向父级添加多个属性。我想将这些类与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
}

然后向ProductType添加Product字段。我也考虑过使用装饰器,但似乎无法避免需要垂头丧气。

实现语言将是Java或Groovy。

4 个答案:

答案 0 :(得分:2)

如果ProductDao.create只是复制其参数,请将新方法添加到Product的接口中,如

public Product createCopy();

然后在每个具体类中,它将知道如何使用例如复制构造函数来创建自身的副本。因此,对于EdibleProduct,您可能有:

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

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

答案 1 :(得分:2)

如果您不能使用Dave的答案(因为将代码放入Product本身会有问题),您可能需要查看Visitor Pattern,它是针对此类问题而开发的。

答案 2 :(得分:0)

你想要的是Chain of Reponsibilty模式。在Product中拥有Set的每个子类型的实例,只需走Set并在每个子类型上调用.create(final Product p);,他们将决定该类型是否正确,并且做他们需要做的事。这会扼杀讨厌的if/elseif构造,并扩展到许多子类。

答案 3 :(得分:-1)

看起来,我假设您正在使用的Java / Groovy版本可以执行此操作,您需要一个可以多态化为这些对象的接口。

换句话说,有一个IP产品,只需使用它,使用动态类型,然后在运行时能够根据它从属性角度看它的作用。