此方法是否属于Value对象或Manager

时间:2014-02-05 16:00:28

标签: java atg

在电子商务应用程序中,以下是高级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中添加这些内容。但是,这会导致Order和PaymentGroup实现者之间的耦合(如CreditCard,GiftCard)示例 -

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

2)将这些移至OrderManager

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

我个人更喜欢2),我只是好奇有没有理由选择1)超过2)

1 个答案:

答案 0 :(得分:2)

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

让我们先解决New 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);
}

New Skool方法将问题摆在首位。而不是让Order和OrderManager负责繁重的工作,而是将工作推送到下级对象。这些模式很光滑,因为:

  1. 他们消除了很多“if”陈述,
  2. 代码更灵活,扩展应用程序更容易,
  3. 而不是每个开发人员对Order和OrderManager进行更改,工作分散在更多类中,而代码合并更容易。
  4. 那是新的Skool。回到那一天,我写了很多Old Skool面向对象的代码。如果你想走那条路,这是我的建议。

    • 恕我直言,您既不需要PaymentGroup接口,也不需要PaymentGroupImpl类。如果所有支付类都扩展了PaymentGroupImpl,那么摆脱界面并使PaymentGroup成为一个类。
    • 将类似isCreditCard(),isGiftCertificate()的方法添加到PaymentGroup类。让他们都返回“假”。
    • 在PaymentGroup的子类中,覆盖这些方法以在适当的位置返回true。例如,在CreditCard类中,isCreditCard()应返回“true”。
    • 在订单类中,创建按类型过滤付款的方法。创建getCreditCards(),getGiftCertificates()等方法。在传统的Java(没有lambdas或helper库)中,这些方法可能看起来像这样
    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范例的很多地方添加代码。