【问题标题】:Which design pattern to use (Active and passive methods)?使用哪种设计模式(主动和被动方法)?
【发布时间】:2016-05-30 11:28:03
【问题描述】:

我有一个玩家,可以喂或砍

以下是我写的类:

public class Dog {

    private int health;

    public void feed(Food food){
        health = health + food.getNutritionalValue();
    }
}

public class Player{

    public void feed(Dog dog, Food food) {
        dog.feed(food);
    }

PlayerDog 都有“活跃” 的方法。

玩家喂狗,狗开始吃食物(我不确定以这种方式结合方法是否好)。

另一方面,我有玩家可以砍树。

公共类播放器{

public void chop(Tree tree) {
        //At this point I am not sure
    }

我不确定是否会使用 Tree 类的 getterssetters 与 Tree 进行交互。

或者如果我应该为此编写一个自己的方法,因为树被砍断了,所以我不会调用它。

所以,最终会有两种或多种实现,但我想到的两种是:

tree.setAmountofWood = x

tree.gettingChopped(Damage int)

我想我应该为这个chopping-process创建一个自己的方法。

或者有什么我应该遵循的设计原则?

【问题讨论】:

    标签: java oop design-patterns


    【解决方案1】:

    我在这里看到了 3 个原则,

    1. SRP - 砍倒和倒下是树的责任,但砍伐是人的责任!
    2. 得墨忒耳定律 - 从我的 POV 看起来不错。
    3. OCP - 树在被砍伐时必须能够执行进一步的操作。

    所以你必须使用

    tree.gettingChopped(Damage damage)
    

    到你的代码:

    1. 方法Dog.feed错误,重命名为Dog.eat,因为狗不喂食,狗在吃东西。顺便说一句,食物必须降低其NutritionalValue
    2. 健康状况是一个整数值,这很糟糕,因为实际上没有数字健康状况。我们可能有一个以百分比表示的残障数字值,但这更像是一个不能为负值的字节。您应该为 Health 创建一个自定义类!这样一来,您的代码就可以开放 (OCP) 以供毒化或压抑等扩展使用。

    【讨论】:

      【解决方案2】:

      我会从这样的事情开始。

      树木可以生长并受到伤害。

      public class Tree {
          private int lumber;
      
          public Tree(int size) {
              this.lumber = size;
          }
      
          public void grow() {
              this.lumber++;
          }
      
          public void grow(int size) {
              this.lumber += size;
          }
      
          public int receiveDamage(int damage) {
              int lumber = 0;
              if (damage > this.lumber) {
                  lumber = this.lumber;
                  this.lumber = 0;
              } else {
                  lumber = damage;
                  this.lumber -= damage;
              }
              return lumber;
          }
      }
      

      食物只是储存营养价值。

      public class Food {
          private int nutrition;
      
          public Food(int nutrition) {
              this.nutrition = nutrition;
          }
      
          public int getNutritionalValue() {
              return this.nutrition;
          }
      } 
      

      我不确定是否所有类型的玩家都可以砍树,所以我创建了一个类来分离职责。如果您愿意,可以将方法移至 Player 类。

      public class Woodcutter extends Player {
          public int chop(Tree tree) {
              // lumber amount may depend on a tool,
              // i.e. axe, chainsaw, etc.
              return tree.receiveDamage(10);
          }
      
          // fell down the tree
          public int fell(Tree tree) {
              int result = 0;
              int lumber = 0;
              do {
                  lumber = chop(tree);
                  result += lumber;
              } while (lumber > 0);
              return result;
          }
      }
      

      代码中的某处

      // create a tree and let it grow for a while
      Tree tree = new Tree(10);
      tree.grow(90);
      
      // Start chopping
      Woodcutter woodcutter = new Woodcutter();
      System.out.println("Lumber received: " + woodcutter.chop(tree));
      System.out.println("Lumber received: " + woodcutter.fell(tree));
      
      Dog dog = new Dog();
      Food food = new Food(5);
      woodcutter.feed(dog, food);
      

      【讨论】:

        【解决方案3】:

        我不会在这里深入探讨被动/主动方法。 “活动树”可能确实是用词不当。

        我宁愿考虑调用对象的方法作为向对象传递消息。而且您显然需要将 消息 发送到当前正在被某人砍伐的树上,并让树决定何时砍伐。 fall()bend()shake()

        树有一些内部状态(strengththickness 的树干?health?)。 '向树发送 message' 意味着调用它的方法,例如beingCut(),这反过来又恶化了树的状态。在树的状态达到一定限度后,其他动作(=树坏状态的后果)可能由树启动

        当然,在你的主循环的每次迭代中,你的树也有机会将 消息 发送到grow(),所以它的状态每次都会有所改善,所以最终它甚至可以从仅被部分切割并返回其初始的完美状态。

        所以,是的,虽然树木看起来相当被动,但它们仍然会对信息/刺激做出反应。 :-)

        【讨论】:

        • 您将如何实现这些向对象传递消息?
        猜你喜欢
        • 2014-04-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多