Java OO - 提供与其他对象交互的新方法的对象?

时间:2013-03-14 18:02:43

标签: java terminology

假设我有一个List<Apple>个对象,每个苹果都有一个颜色。

我实现了另一个使用其输入构建的对象的苹果对象列表。我可能会在这个对象上实现像“让我得到绿苹果的数量。”的功能,我可以在不知道该对象的内部表示的情况下调用它。

你会怎么称呼这个人?它似乎是基本的OO,但我在思考描述性名称时遇到了麻烦。

1 个答案:

答案 0 :(得分:0)

由于你所说的List<Apple>几率很高,你也在讨论Collection<Apple>(列出继承集合)。

如果你想强调&#34;收集&#34;然后我会命名&#34;集合&#34;。苹果传统上是以蒲式耳出售的,但你并不关心测量,所以我会使用更通用(不依赖于尺寸)的术语&#34;篮子&#34;。

public class Basket {

   private int greenCount;

   public void addApple(Apple apple) {
     if (apple.isGreen()) {
        greenCount++;
     }
   }

   public int getGreenAppleCount() {
      return greenCount;
   }

}

这恰当地说明了计算篮子里的青苹果的责任。

另一方面,实用程序似乎将任务的责任与特定的类型绑定对象分开。例如,让我们看一个假设的AppleCounterUtil

public class AppleCounterUtil {

    public int getCount(Collection<Apple> apples, AppleCondition condition) {
        int count = 0;
        for (Apple apple : apples) {
            if (condition.isSatisfied(apple)) {
               count++;
            }
        }
    }

}

现在我们有一个很好的实用程序,它确实不会保持计数,但每次需要从可能不同的苹果列表中重新计算计数。

关键是后一个例子是不是面向对象的,因为没有概念对象。说明没有对象的理由是因为包含该实用程序的类缺少状态。对象是数据密切相关的代码的集合。当你只有代码时,可以合理地论证你有一个名称间隔函数而不是一个对象。

要再次看到差异,让我们比较两段代码。使用我们的第一个&#34;篮子&#34;的方法:

...
int greenOnes = basket.getGreenAppleCount();
basket.addApple(new GreenApple());
greenOnes = basket.getGreenAppleCount();
...

变得非常笨重,但由于我们面向对象,我们可以轻松地将Basket Listener接口添加到Basket

public class Basket {

   public void addListener(BasketListner listener) {
     ...
   }

   public void addApple(Apple apple) {
     ...
     for (BasketListnener listner : listeners) {
       listener.appleAdded(this);
     }
   }

}

... some other class ... implements BasketListener {

   int greenOnes = 0;

   ...

   public void appleAdded(Basket basket) {
      greenOnes = basket.getGreenAppleCount();
   }
}

使用效用导向技术

...
int greenOnes = AppleCounterUtil.getCount(apples, new GreenCountCondition());
apples.addApple(new GreenApple());
greenOnes = AppleCounterUtil.getCount(apples, new GreenCountCondition());
...

在表面上看起来类似,直到您尝试添加更多功能。试图添加一个&#34;苹果列表监听器&#34;你很快意识到AppleCounterUtil并不负责维持一个计数,而且无法收听。苹果&#34;也没有#34;负责维护计数,而通用列表通常会出现错误的监听界面。

不幸的是,当人们面向实用程序时,他们通常会尝试通过添加更多实用程序方法来解决问题。这最终意味着特定问题(管理苹果组)可以在许多实用程序之间分配,而没有任何实用程序完全负责该任务。每个实用程序仅提供一些&#34;功能&#34;这可以按需计算。

在某些情况下,计算按需功能可能会依赖于其他按需计算功能,这样您就可以在两者之间获得功能耦合(即使没有直接代码耦合)。这种有效的耦合意味着如果您无法按顺序调用某组实用程序,或省略所需的实用程序调用,则代码会中断。最极端的情况是,对象最终会失去其行为,使其成为数据结构,或者缺乏通常与对象关联的行为。它是一种面向对象的设计反模式,被称为“贫血物体”。