【问题标题】:Java Static Variables for Data Storage vs Local数据存储与本地的 Java 静态变量
【发布时间】:2018-01-19 16:27:52
【问题描述】:

我用动物代替了我的真实代码,所以看起来有点傻,但这是一个真正的问题。

我的 java 程序获取不同动物的列表,并一次遍历它们,为每个动物执行以下操作:创建动物,动物进行一些随机运动,计算每个运动,然后程序收集运动数据,进行一些分析,然后继续列表中的下一个动物。

我有一个抽象的动物类,它由不同的动物对象扩展,狗、猫等,每个都有自己的动作。在该基础 Animal 类中,有一个 HashMap 可以计算 Animal 的随机运动。

每个移动方法都以调用 updateMap 结束,updateMap 位于 Animal 基类中。 updateMap 接收移动字符串键作为输入,然后检查给定的移动是否在 HashMap 中作为键,如果没有,则添加移动作为键,值为 1。如果移动已经是 HashMap 中的键它将增加数值。

当前设置是 HashMap 在 Animal 类中,因此每个 Animal 都有自己的。我的问题是,将 HashMap 作为具有静态 updateMap 方法的静态变量移动到单独的实用程序类是否违反 Java 最佳实践?当我想要移动数据时,我必须添加一个 getter 方法来调用,以及一个清除地图的方法,该方法将在 Animal 构造函数中调用。 Animals 一次迭代一个,并且只迭代一次,因此不会与更新发生冲突。

我想创建静态实用程序类的原因是希望它能提高性能。动物列表有数百万个项目长,我想如果不必使用这个 HashMap 作为类变量来创建每个动物,我可以稍微加快它的速度(即使它几乎不引人注意)。但我不知道对静态方法的调用是否会减慢速度。如果您知道更好的(性能方面的)设计来跟踪运动,任何对此的意见都将不胜感激。

伪代码:

当前:

Animal.java

 public abstract class Animal {
      private HashMap counter;

      public Animal(String input){
           counter = new HashMap();
           .
           .
      }

      protected void updateMap(String key){
           if(counter.contains(key)){
                counter.update(key, counter.get(key)+1);
           } else {
                counter.add(key, 1);
           }
      }

      protected void analyze(){
           some code using counter;
      }
 }

狗.java

 public class Dog extends Animal {

      public Dog(String input){
           super(input);
      }

      private void jump(){
           .
           .
           updateMap("jump");
      }

      private void run(){
           .
           .
           updateMap("run");
      }

      private void dance(){
           .
           .
           updateMap("dance");
      }

变化:

Animal.java

 public abstract class Animal {

      public Animal(String input){
           AnimalUtil.clearCounter();
           .
           .
      }

      protected void analyze(){
           HashMap count = AnimalUtil.getCounter();
           some code using counter;
      }
 }

狗.java

 public class Dog extends Animal {

      public Dog(String input){
           super(input);
      }

      private void jump(){
           .
           .
           AnimalUtil.updateMap("jump");
      }

      private void run(){
           .
           .
           AnimalUtil.updateMap("run");
      }

      private void dance(){
           .
           .
           AnimalUtil.updateMap("dance");
      }
 }

AnimalUtil.java

 public class AnimalUtil {
      private static HashMap counter;

      public static void updateMap(String key){
           if(counter.contains(key)){
                counter.update(key, counter.get(key)+1);
           } else {
                counter.add(key, 1);
           }
      }

      public static HashMap getCounter(){
           return counter;
      }

      public static void clearCounter(){
           counter = new HashMap();
      }
 }

谢谢。

【问题讨论】:

  • 我们懂代码。发布代码而不是描述它。
  • 我部分同意@JBNizet。不过,我会说邮政编码以及描述它。
  • 添加了一些粗略的代码
  • 您的建议将创建尽可能多的 HashMap,占用相同的时间和内存,但您将失去原始代码的许多有趣属性:您将无法使用/分析两种动物一次,您将无法同时使用/分析多个动物,并且您必须在最后一次分析后清除地图,而不是在您的动物超出范围后仅依靠 GC 来完成它的工作。全局可变状态通常是一个糟糕的想法,这种情况也不例外。

标签: java inheritance static abstract extends


【解决方案1】:

要问自己一个问题:每只动物都有自己的 HashMap 有意义吗?听起来答案是否定的,因为这是“全球”的“共享”数据。

将其设为static 变量是合理的。我建议还考虑其他选择。例如,听起来 HashMap 存储了有关动物所在世界的信息。所以也许这个变量属于另一个类,WorldFarm,而不是Animal 类。

【讨论】:

    【解决方案2】:

    问题是,大多数情况下,您创建实用程序类是因为您不知道其中代码的责任。根据 Clean Code,所有语言的最佳实践是,您编写的每个和平代码都有自己的领域和自己的职责。因此,将您要全局使用的 HashMap 放在一个类中,该类负责计算和观察不同动物的运动。这是我的建议。

    【讨论】:

    • 非常好。每个班级都应该有一个责任并做好。
    猜你喜欢
    • 1970-01-01
    • 2013-07-03
    • 2016-11-16
    • 2012-01-13
    • 1970-01-01
    • 1970-01-01
    • 2018-11-13
    • 1970-01-01
    相关资源
    最近更新 更多