你会在这个项目中改变什么? (JAVA)

时间:2010-10-30 11:06:52

标签: java

 public class Zoo{
    public static void main (String[] args){
        Animal animal1 = new Animal ("Giraffe", 5, 'M');
        Animal animal2 = new Animal ("Lion", 10, 'F');

        System.out.println (animal1.getName () + " " + animal1.getAge () + " " + animal1.getGender ());
        System.out.println (animal2.getName () + " " + animal2.getAge () + " " + animal2.getGender ());
    }


 }
    class Animal{
        private int age;
        private char gender;
        private String name;

        public Animal(){
            this.name = "Giraffe";
            this.age = 5;
            this.gender = 'M';
        }

        public Animal (String name, int age, char gender){
            this.name = name;
            this.age = age;
            this.gender = gender;
        }

        public void setName (String name){
            this.name = name;
        }

        public String getName (){
            return name;
        }

        public void setGender (char gender){
            this.gender = gender;
        }

        public char getGender(){
            return gender;
        }

        public void setAge (int age){
            this.age = age;
        }

        public int getAge (){
            return age;
        }
    }

您是否会认为此代码是正确的并且显示封装的概念? 谢谢:))

9 个答案:

答案 0 :(得分:7)

这是学生代码。

一些建议:

  1. 我将性别列为枚举。我可以将任何字符串传递给你的构造函数。
  2. 我在你的Animal中重写了equals,hashCode和toString。谷歌为“Joshua Bloch第3章”找出了解决方法。
  3. 什么,没有继承?那似乎是学生的经典之作。

答案 1 :(得分:6)

您可以考虑添加验证以确保动物无法处于无效状态。如果有人试图设定负年龄等,则抛出IllegalArgumentException

答案 2 :(得分:5)

一个问题,您不应重复System.out.println代码。您应该在Animal类中使用toString方法。

另一个问题。您可能应该拥有一个动物列表,而不是自己明确创建它们。

尝试进行这些更改,如果您遇到问题,我会给您一些建议。我不愿意提供实际的代码解决方案,因为这看起来像是我的作业。

答案 3 :(得分:3)

它似乎工作,但您并没有真正封装任何内容,因为您的所有字段都是通过设置者公开的 - 您可以致电animal1.setGender('x')animal1.setName(null) ,使对象处于无效状态。当然,你可以说“很好,我不会传递'x'null”,但是当你在一个团队工作时这不会扩展,因为每个人对什么都有不同的假设构成“合理的”期望(例如,性别区分敏感吗?)。最糟糕的情况是,如果没有验证,每次添加一段调用getGender()getName()的新代码时,如果该值不是作者预期的值,它必须处理错误的返回值或冒险。

封装的要点是你在原始字段和外部代码之间添加一个层 - 这个层负责确保对象处于有效状态,并执行需要额外了解对象内部的操作(例如作为Brian的出生日期建议 - 我喜欢这样。)

正如其他人发布的那样,一个良好的开端是为设置者添加验证(负年龄/无效名称),并使用enum进行性别(或常数+验证,如果必须的话)。

答案 4 :(得分:3)

这种动物改变性别的可能性有多大?名称 ?也许。年龄?当然。但是我会减少代码中的可变性。这将使您的代码更可靠(特别是面对多线程,但这是一个很好的做法)。

我当然会检查无效输入。什么是有效年龄?什么是有效名称? (是否可以接受空白字符串?)。您的动物对象应该验证此类设置,因为它将包含此类有效性概念。

也许代替年龄,我会给你的动物一个出生日期(再次,不可变)。然后当你问这个动物的年龄时,它可以直接计算出来。

一个好的指导方针是,让你的对象为你做事。当对象可以派生出这样的东西时,不要设置个别属性等。

答案 5 :(得分:2)

Bloch, J., 2008. Effective Java. 2nd ed

第15项:最小化可变性:类应该是不可变的,除非有充分的理由使它们变得可变。不可变类更容易设计和实现,不易出错,更安全。它们本质上是线程安全的,因此可以自由共享。要使Animal类不可变,你会:

  1. 删除“setter”方法。
  2. 制作课程final,使其无法延长。
  3. 制作所有字段final
  4. 制作所有字段private

答案 6 :(得分:1)

动物不能飞,走路?动物园也需要合适的方法。

对象模型是http://en.wikipedia.org/wiki/Anemic_Domain_Model。 (这是作业,所以没关系)

答案 7 :(得分:0)

在上面的其他评论中,我认为Animal是一个非常重要的类,可以公开(讨论开放)并驻留在自己的文件中。

这会将您的“客户端”程序或可执行代码(您的Zoo类与其主要内容)从您的业务逻辑中分离出来(您现在只有一个Animal对象,但如果您成长,您必然会在应用程序中拥有更多内容它,在这种情况下,我会开始考虑在包中分离类。)

答案 8 :(得分:0)

还要确保通过参数化的方法重用真正的构造函数:

    /**
     * Constructs a default <tt>Animal</tt>. Current implementation
     * constructs a 5 years old male Giraffe.
     */
    public Animal() {
        this("Giraffe", 5, 'M');
    }

    public Animal (String name, int age, char gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
    }