2013-03-14 101 views
3

比方说,我有一个List<Apple>对象,每个苹果都有一个颜色。Java OO - 提供与其他对象交互的新方法的对象?

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

你会说这个人吗?它看起来像基本的面向对象,但是我在考虑描述性名称时遇到了麻烦。

+2

什么_is_这个'Ob​​ject'?如果是篮子,那么篮子就可以。如果你有一个'SchoolChild'并且你有一个容器用于'Collection ''那么也许'School'。选择描述“对象”角色的内容。 – 2013-03-14 18:08:25

+0

AppleSupervisor?园丁? AppleOverseer?史蒂夫乔布斯曾经? – ghdalum 2013-03-14 18:09:11

+2

我会叫它乔治 – radai 2013-03-14 18:10:16

回答

0

既然你正在谈论一个List<Apple>的可能性是你也在谈论Collection<Apple>(列表继承集合)。

如果你想强调“收藏”,那么我会命名为“收藏”。传统上苹果是以布什尔的名义出售的,但你不关心测量,所以我会用更通用的(不是尺寸相关的)术语“篮子”。

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++; 
      } 
     } 
    } 

} 

,现在我们有一个很好的工具,它真的不保持计数,但每次从苹果可能不同的名单还需要时间重新计算计数。

关键是后面的例子是不是面向对象的因为没有概念对象。说明没有任何对象的理由是因为包含效用的类缺乏状态。对象是数据集合密切相关的代码。当你只有代码时,可以有一个合理的说法,即你有一个名字空间函数而不是一个对象。

为了再次看到差异,我们来比较两个代码片段。使用我们的第一个“篮子”的做法:

... 
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()); 
... 

表面看起来很相似,直到您尝试添加mo重新功能。在尝试添加“苹果列表监听器”时,您很快意识到AppleCounterUtil不负责维护计数,也不能被监听。 “苹果列表”也不是负责维护计数的工具,而通用列表通常呈现错误的倾听界面。

不幸的是,当一个人获得面向工具的时候,他们通常会尝试通过添加更多的实用方法来解决问题。这最终可能意味着具体的问题(管理苹果群的人)可以在许多公用事业中分发,而不需要任何公用事业单独负责任。每个实用程序只提供一些可按需计算的“功能”。

计算需求的特点,在某些情况下,可能会依赖上点播功能等计算,这样你会得到两个(即使不是直接的代码耦合)之间的功能耦合。这种有效的耦合意味着如果您未能按顺序调用某些实用程序,或者省略了所需的实用程序调用,则代码会中断。一个极端的例子是,对象最终失去行为的程度成为数据结构,或者缺乏通常与对象关联的行为。它是一种面向对象设计的反模式,被称为“贫血对象”。