2014-02-05 22 views
1

在电子商务应用,下面是高层次的API请问这种方法属于价值对象或经理

interface Order{ 
    public List<PaymentGroup> getPaymentGroups(); 
} 

interface PaymentGroup{} 

class PaymentGroupImpl implements PaymentGroup{} 

class CreditCard extends PaymentGroupImpl{} 

class GiftCard extends PaymentGroupImpl{} 

class OrderManager{ //Manager component used to manipulate Order} 

有必要增加类似hasGiftCard(), hasCreditCard(), getGiftCards(), getCreditCards()

两种方法的一些实用方法 - 1)将这些添加到Order。然而,这将导致订单和PaymentGroup实现者之间的耦合(如信用卡式,礼金券)实施例 -

interface Order { 
     public List<GiftCard> getGiftCards(); 
} 

2)将这些对OrderManager

class OrderManager{ 
    public List<GiftCard> getGiftCards(Order order){} 
} 

我个人比较喜欢2),只是好奇会有任何理由要选择1)在2)

+0

我认为这很大程度上取决于API的结构。 – m0skit0

回答

2

我有两个答案。一个是我称之为Old Skool OOP的,另一个我称为New Skool OOP。

让我们先解决新的Skool。 GoFMartin Fowler改变了人们看OOP的方式。像hasGiftCard()一样添加方法会导致在代码中添加条件逻辑/分支。它可能看起来像这样:

if (order.hasGiftCard()) { 
    //Do gift card stuff 
} else { 
    //Do something else 
} 

最终这种代码变得脆弱。在一个大的应用程序中,许多开发人员将编写谓词方法。谓词方法声明某些内容并返回true或false。这些方法通常以“has”,“is”或“contains”开头。例如,isValid(),hasAddress()或containsFood()。更多的开发人员编写使用这些谓词方法的条件逻辑。

为了避免所有这些条件逻辑软件工程师改变他们如何思考面向对象。他们不再使用谓词方法和条件逻辑,而是开始使用诸如战略模式,访问者模式和依赖注入之类的东西。从您的问题域的一个例子可能是这样的:

//Old Skool 
if (this.hasCreditCard()) { 
    orderManager.processCreditCard(this.getCreditCards()); 
} 

这里是另一种方法来解决同样的问题:

//New Skool 
for(PaymentItem each : getPaymentItems()){ 
    each.process(this); 
} 

新斯库尔办法打开它的头的问题。不要让Order和OrderManager负责繁重的工作,而是将工作推送给下属对象。这些种模式是光滑的,因为:

  1. 他们消除了很多的“如果”语句,
  2. 的代码更柔软,更容易扩展应用程序,并
  3. ,而不是每个开发人员制作对Order和OrderManager的更改,工作分散在更多的类中,并且代码合并更容易。

这是新的Skool。当天,我写了很多旧的Skool面向对象的代码。如果你想走这条路,这是我的建议。

  • 恕我直言,你不需要一个PaymentGroup接口和一个PaymentGroupImpl类。如果所有支付类都扩展了PaymentGroupImpl,那么请删除接口并使PaymentGroup成为一个类。
  • 将诸如isCreditCard(),isGiftCertificate()之类的方法添加到PaymentGroup类中。让他们都回归“假”。
  • 在PaymentGroup的子类中,重写这些方法以在适当的位置返回true。例如,在CreditCard类中,isCreditCard()应该返回“true”。
  • 在Order类中,创建方法以按类型过滤付款。创建诸如getCreditCards(),getGiftCertificates()等方法。在传统的Java(无lambda表达式或辅助库),这些方法可能是这个样子
List getCreditCards() {  
    List list = new ArrayList(); 
    for(PaymentGroup each : getPaymentGroups()){ 
     if(each.isCreditCard()) { 
      list.add(each); 
    } 
    return list; 
}

- 在Order类,创建断言方法,如hasCreditCards()。如果性能是不是一个问题,这样做:

boolean hasCreditCards() { 
    return !getCreditCards().isEmpty(); 
    }

如果性能是一个问题,做一些更聪明:

boolean hasCreditCards() { 
    for(PaymentGroup each : getPaymentGroups()){ 
     if(each.isCreditCard()) { 
      return true; 
     } 
    return false; 
    } 
}

意识到,如果你添加一个新的付款组,必须添加代码在旧Skool范例中的很多地方。

相关问题