java - 没有方法的接口(interface)与字段

标签 java oop design-patterns

我有两个类,LivingCreature 和继承自它的Animal

我想为每个现有的动物实现一个类,但由于不同的动物有很多共享的功能,我希望能够将动物分为几个类别: 飞行、行走、游泳、肉食、素食等等...

每种动物都可以居住在多个动物中,甚至可以来自同一区域,例如飞行动物、行走动物和食肉动物。

此外,每个类别可能拥有几个独特的属性,例如飞行动物应包含速度和进食类型(例如,它是否坐在树上采摘蠕虫,或“袭击”地球并用腿采食动物)

我绝对要避免的第一件事是为每个具体动物实现保留一组不同的字段。

现在,由于有些类别只是二元的(食肉动物或素食主义者),而有些绝对不是,我想知道实现它的正确方法是什么。

我倾向于为每个类别提供接口(interface),即使它们不会包含任何方法,但我遇到了冲突:

  • 拥有一个像 isMeatEating 这样拥有单个 boolean 字段的简单用途的接口(interface)看起来很奇怪。
  • 另一方面,将多个类别作为 Animal 的字段,并将其他几个类别实现为 Interface,听起来非常错误且令人困惑。

从设计角度来看,正确/最佳的选择是什么? (也许有一个 与此用例匹配的设计模式)

最佳答案

您描述的模式似乎是 trait 的模式或者也许是mixin .

Mixins are a language concept that allows a programmer to inject some code into a class. Mixin programming is a style of software development, in which units of functionality are created in a class and then mixed in with other classes.

某些语言,例如 Scala,有 built-in support for these concepts .

在 Java 8 中,借助默认方法,we can do traits在某种程度上,我这么说是因为那是not the reason为什么设计默认方法。

现在,如果没有您正在做的事情的完整细节,很难就您的设计提出想法,但我会尝试举一个例子,说明我如何从我的角度看待它。

让我们关注饮食概况:食肉动物与食草动物。食肉动物吃其他动物,食草动物吃植物或植物来源的东西,杂食动物可能两者都吃。动物和植物都是可食用的 Material 。

interface Edible {
   Collection<Nutrients> getNutrients();
}

interface Vegetal extends Edible {}
interface Animal extends Edible{}

所有动物都吃东西,所以我们可以将动物定义为:

interface Animal<T extends Edible> extends Edible {

    Stomach getStomach();
    Collection<Bolus> masticate(T food);

    default void eat(T food) {
        Objects.requiresNonNull(food, "The food must not be null");
        for(Bolus bolus : this.masticate(food)) {
            this.getStomach().ingest(bolus);
        }
    }
}

请不要告诉我食团的细节,我们假设所有动物都有胃和咀嚼食物的方式,将其变成食团并摄入它进入他们的胃。

现在,我们终于可以得出我们的定义:

interface Carnivore extends Animal<Animal> { }
interface Herbivore extends Animal<Vegetal> { }
interface Omnivore extends Animal<Edible> { }

现在您可以定义一个

class Chicken implements Herbivore {}
class Lion implements Carnivore {}
class Bear implements Omnivore {}

现在只能吃植物类型的东西,而狮子只能吃动物类型的东西,而可以吃任何可食用的东西。

我在 Animal 接口(interface)的默认方法上添加的细节越多,我需要在这些类中实现的细节就越少,这也许是实现您想要的效果的一种方法。

我知道我可能无法回答您的问题,但我希望我至少为您提供了一些想法,让您可以继续对理想解决方案进行调查和实验。

关于java - 没有方法的接口(interface)与字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44131459/

相关文章:

java - 如何在每次FFT计算中检索不同的原始频率并且在java中没有任何频率泄漏

java - 如何将 XML 文件直接写入 zip 存档?

java - 为什么 List<String> 不能同时作为基类泛型方法和派生类非泛型方法的参数?

php - Pdo多行插入问题

python : Difference between static methods vs class method

algorithm - 如何像 Excel 一样发现和分析相似的模式?

java - SVG 线性渐变比例和平移问题

javascript - 两种方法有什么区别?

entity-framework - 不使用存储库模式,按原样使用 ORM (EF)

oop - 访客模式的替代方案?