为什么将变量公开可见性作为一种不良做法

时间:2014-10-29 15:15:39

标签: java

我在Java类简介中,我正在对变量进行一些研究。似乎知识渊博的程序员表示,在公众可见度中定义变量是不好的做法。我看到他们说这是不好的做法,但我无法找到他们的主张的押韵或理由。这就是我在课程的应用程序中定义变量的方法。

public class DykhoffWk3Calculator 
    {
        /*
        * This class is used to define the variables in a static form so all 
        * classes can access them.
        */
        public static double commissionRate = .03, startSalary = 45000,
                accelerationFactor = 1.25; 
        public static double annualSales, commissionTotal, totalCompensation,
                total, count, count2;
        private static Object input; Object keyboard;

public static class UserInput
    { //Then continue with my other classes

我认为这是一种定义它们的逻辑方法,因此所有类(不仅仅是主类)都可以访问它们。有人可以向我解释为什么这是不好的做法,应该在哪里定义变量?非常感谢任何帮助。

5 个答案:

答案 0 :(得分:4)

简而言之:因为你所有的公众"表面区域"一个类有效地定义了它的API。

如果您通过方法公开事物,那么您可以稍后更改它们的工作方式的详细信息。但是如果你暴露一个字段,并且你控制之外的其他一些类(很可能在你的知识范围之外)开始引用那个字段,那么你就会在剩下的时间里暴露那个字段。或者直到你决定打破向后兼容性。

  

我认为这是一种定义它们的逻辑方法,因此所有类都可以访问它们。

作为一般规则,您不希望"所有课程"访问它们。绝大多数使用软件的工作都花在维护代码上,而不是第一次编写代码。因此,经验丰富的开发人员意识到代码的最佳实践通常是使其最易于维护的实践,而不一定是那些最便于编写代码的实践。

如果你有一个可以从任何地方随时访问的变量,并且你想对它的修改方式进行一些调整 - 你怎么能确定这是安全的?您需要多长时间跟踪引用它的所有方式,并确定您的更改会产生什么影响? (具体到公共领域,你可以告别任何关于从多个线程同时运行或重复运行的可重用性。)

从广义上讲,减少表面积"课程是一件非常好的事情。限制其他类可以与这个类进行交互的方式,使得控制和理解关系变得更加容易,并且使得更容易进行内部更改"隐形"到那些其他课程。想想这个类做什么,它将为其他类提供什么,定义一个接口(无论是否是实际的interface)。并且只暴露给其他类,这是满足这些要求所需的最低限度。

这永远不会让他们对变量进行任意访问。

答案 1 :(得分:1)

所以一般来说,你实际上不希望任何人能够访问这些值。我不仅可以看到这些变量,还可以将它们更改为我喜欢的任何变量。这可能会导致更大,更复杂的程序出现问题。

此外,如果您想稍后更改类使用/存储这些值的方式,您可以不必外出并更改直接访问这些公共变量的所有其他类。相反,您应该提供仅提供您想要提供的访问量的方法。

标准类比是驾驶汽车。你知道如何转动方向盘,刹车等,但不知道汽车是如何做这些事情的。因此,如果发动机需要大幅改变,或者你有一辆新车,那么你仍然知道如何开车。您无需担心幕后发生的事情。

答案 2 :(得分:0)

一般来说,类中的公共变量是个坏主意。由于这意味着其他类/程序,可以修改实例的状态。

由于一个类负责保护其状态并确保状态是“一致的”,因此可以通过定义公共setter来强制执行此操作(因为这允许运行代码来检查/修复状态)

通过将变量设置为public,状态不受保护。如果以后并非所有可表示的状态都是有效状态,则表示存在问题。

示例

假设您要实现ArrayList<T>,那么它看起来像(未完全实现):

public class ArrayList<T> {

    public int size = 0;
    public Object[] data = new Object[5];

}

现在可以修改arrayList的size没有添加元素。现在,如果您要求ArrayList<T>实例删除/添加/复制/ ...无论如何,它所使用的数据可能是错误的。

也许你可以声称一个程序员是好的:他不会修改对象,除非他需要并且根据&#34;规则&#34;。但是这样的事情最终总会出错,如果您决定修改ArrayList的定义(例如,为int使用两个size),该怎么办?在这种情况下,您需要重写设置此类字段的所有代码。

总结:private / protected是发明保护一个类实例与其他实例会导致实例损坏/无效/不一致/...

答案 3 :(得分:0)

首先你说错了。

让你的变量公开是不好的,例如: public String name = null;这很糟糕。你应该总是那样做 private String name = null;

要理解为什么,你需要深入了解OOP的意识形态 OPPS意识形态表明你班级的每个对象都有两件事:

  • 属性:我们也称为变量或状态的东西。
  • 行为:我们称之为方法或功能的东西。

属性在一段时间内识别对象。行为允许您管理对象的属性,以便随着时间的推移相同的对象可能看起来处于不同的状态。例如:一段时间内的产品对象可以是“可用行项目”或“添加到购物车”或“出售'或'缺货'取决于其州。由于状态对于对象至关重要,因此对象不应允许对其状态进行直接的无意义变异操作。对象应将其变量保持为私有,并公开外部世界可用于与对象交互的行为,并根据行为中执行的操作更改状态。例如:在“可用行项目”状态下调用Product对象上的'addToCart()'行为可能意味着:不仅将其状态更改为“添加到购物车”,还可能让其他用户知道此产品的数量现在可用少了1个。

故事很长:除非需要,否则不要将属性直接暴露给外部工作以进行变异。这意味着不要公开它们,如果不需要也不要给出setter方法。

答案 4 :(得分:0)

按惯例字段,公共类中声明为public(限制性最小)的方法和构造函数对Java程序中的任何类都是可见的,无论这些类是在同一个包还是在另一个包中。这意味着更改字段的值肯定会影响访问该字段的其他类。这会打破整个封装意识。