【问题标题】:OOD - Setting value once so that it cannot be changedOOD - 设置一次值,使其无法更改
【发布时间】:2011-10-05 09:35:26
【问题描述】:

我正在尝试了解信息隐藏的原理。假设我有一个车辆类,其中包含诸如 getSpeed、setSpeed、getEngine、setEngine、getVIN、setVIN 等方法。为了强制隐藏信息,我不想让客户端类能够 setVIN,因为车辆只有一个 VIN (我可能错了)。我对如何让这个类应用信息隐藏有点困惑。我不想将 setVIN 设为私有。但是您如何设置一次 VIN 并且之后不允许再次设置呢?还是我应该那样做?

【问题讨论】:

  • 就个人而言,我会使用使用构造函数设置的最终字段。这样,每个字段都必须设置一次且仅一次。

标签: java oop information-hiding


【解决方案1】:

信息隐藏意味着您不会暴露内部 VIN 字段以便从外部直接修改。拥有一个 setter 并不违反隐藏原则,因为您可以控制字段的修改。

在你的情况下,如果你想确保 VIN 只设置一次,最好的方法是在构造函数中设置它,然后删除 setVIN。

顺便说一句,虽然这是一个一般性问题(这很好),但如果您有特定的语言,可能值得一提。例如,某些语言不允许使用非默认构造函数。在那种语言中,我会留下 setVIN,但让它检查在调用时是否已经设置了 VIN。如果有,要么忽略调用,要么抛出异常。

【讨论】:

  • 你能解释更多关于控制的信息吗?假设在一个场景中我将 VIN 设置为 123,然后是客户端代码 setVIN(321)。这不是违反信息隐藏吗?我正在研究 java 顺便说一句
  • 不是,因为您可以控制是否更改实际的 VIN 成员。例如,您可以检查 VIN 成员是否不为 0,如果是,则抛出异常而不是更改成员。或者,您可以删除 setVIN 并将其设置在构造函数中。无论哪种方式,由于没有客户端可以设置v.VIN = 77(假设VIN 不公开),因此隐藏已经到位。作为旁注,您可能想将Java 标签添加到您的问题中。会给你带来更多的流量,可能还有更多的答案。
  • 我明白了。因为在我的讲义中,有一个带有 get/setVIN 的示例 Vehicle 类,它说这是糟糕的设计,因为实际上,您可以访问 VIN 但无法更改它,因此没有任何意义。它还修改了代码,使 get/setSpeed 是私有的
  • 什么违反了信息隐藏,什么可能并不总是明确的。如果您有一个相当典型的带有 get/set 方法的 POJO,它除了 get/set 一个私有变量之外什么都不做,那么在实践中实际上并没有太大区别——您不妨将字段设为 public。 (不是说你应该。)这个想法是,通过使用 get/set 方法,你可以以多种不同的方式实现 VIN 信息的存储,比如在地图中,在数据库中,只需忽略更改,并且以此类推。
  • 一个经典的例子是,如果你有getBirthdate()getAge(),你不知道类是单独存储它们,还是从另一个计算一个。这就是你隐藏的信息。
【解决方案2】:

仅仅因为类/对象具有属性,从概念上讲,并不意味着它应该是公共的。可以使用“getter”和“setter”函数分配和更改“属性”,但您只能公开您需要的那些。

你可能会说,“给我看代码”:

public class JavaClass {

    // hidden field "name"
    protected String name;  

    // start property "Name"
    // note: uses "name" field to store the property
    public void setName(String value) {
        //set passed parameter as name
        name = value;
    }
    public String getName() {
        return name;
    }
    // finish property "Name"

    // start property "Id"
    // note: uses "name" field to store the property
    public void setId(String value) {
        //set passed parameter as name
        name = value;
    }
    public String getId() {
        return name;
    }
    // finish property "Id" 

    // hidden field "years"
    protected int years
    // functions works as "read-only" properties
    public int Years() {
      return years;
    }   

    // start constructor
    public JavaClass() {
            name  = "unknown";
            years = 1;
    }
    // finish constructor

    public static void main(String args[]) {     
        JavaClass javaObject = new JavaClass();

        //set name member of this object
        javaObject.setName("Visitor");

        // print the name
        System.out.println("Hello: " + javaClassExample.getName());  

        //set name member of this object
        javaObject.setId("Employee");

        // print the name, not the Id, but are the same
        System.out.println("Hello: " + javaClassExample.getName());  

        // and current years of age
        System.out.println("Years: " + javaClassExample.Years());       
    } // public static void

} // class JavaClass

它没有经过测试,但我认为它解释了我的观点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多