什么时候使用公共领域是有意义的?

Jus*_*tin 19 c# java oop design-patterns

这是我现在有一段时间的问题:

什么时候公开公开这个领域是有意义的?

public class SomeClass()
{
   public int backing;
}
Run Code Online (Sandbox Code Playgroud)

这样做的缺点(除了激怒OOP精英)之外,如果您需要在此数据之上添加任何逻辑,则必须对API进行重大更改.我想这就是精英主义者所关注的.

Java和C#的最佳实践一直是使用getter/setter或属性来访问字段.

public class SomeClass()
{
   private int backing;

   public int getBacking()
   {
      return backing;
   }

   public void setBacking(int v)
   {
      backing = v;
   }
}
Run Code Online (Sandbox Code Playgroud)

C#已将其演变为具有自动属性的非常简单的语法:

public class SomeClass()
{
   public int Backing { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

懒惰我仍觉得这太长了,因为它发现自己做了很多事情.更重要的是,我不确定我知道公共领域会更有意义.

为什么不直接将公开声明的字段视为幕后的属性(或方法)?这样就不可能激怒去耦神灵,并且不需要打字.

public class SomeClass()
{
   public int backing;   // The same as public int backing { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

对于除了包装底层字段之外什么都不做的属性,我很确定JIT优化了方法调用,因此性能可能不是问题.有什么想法吗?(除了字段名称的正确案例约定外)

编辑:感谢所有的回复.我觉得也许不是每个人都理解我的问题.什么时候公共场地比房产更好?为什么这是一个更好的选择?如果唯一的原因是方便(减少键入和混乱),那么只要遇到公共字段,编译器就会在"引擎盖下"生成属性会有什么缺点.基本上,创建一个真正的公共领域是不可能的(因为它们都是属性).这会有什么问题?谢谢.

gek*_*owa 12

在我看来,当你设计一个类的结构时,你应该更加关注未来的变化,并且应该始终对它们友好.如果未来的要求需要您在返回值之前执行某些逻辑而不是仅返回字段的值,则必须更改类的接口,并且库的所有用户都必须更改.这通常会成为灾难.

请记住,开/关原则.


emo*_*ory 5

什么时候公开揭露一个领域是有意义的?

在其他地方,私人课程如下.

public class MyOuterClass
{
      private class MyInnerClass
      {
            public int val ; // why bother w/boiler plate
      }
}
Run Code Online (Sandbox Code Playgroud)


kst*_*uch 5

公共字段是更好选择的情况之一是提供类的常量。

例如,参见:

public const double PI
Run Code Online (Sandbox Code Playgroud)

在 System.Math 中定义。

这种方法受到青睐,因为它明确地通知您的类的使用者,该成员不包含任何逻辑、验证或任何其他与状态相关的操作,因此可以在您想要的任何上下文中使用。

我能想到的另一种情况是,当您需要类作为简单操作的容器(或者只是将大量参数传递给方法)时,例如,请参阅System.Windows.Point. 在大多数情况下,这些容器被建模为结构体。


Mal*_*olm 5

以下是公共领域的优缺点摘要:

好处

  • 代码中的混乱程度较低
  • 更好的表现(在某些情况下)

缺点

  • 如果不更改API,则无法更改表示
  • 不能强制执行不变量(除非该字段是不可变的)
  • 访问这些字段时无法执行其他操作

那么我们何时应该使用公共领域?要看.很明显,对于公共类来说,缺点超过了优点.在代码中发展代码的可能问题比代码中更混乱和性能影响更小.

但是,类可以是包私有或甚至是私有嵌套,在这种情况下,代码的可能更改将被本地化.因此,绝对可以使用公共字段.还有一些情况下性能差异不是很小.例如,Android开发者指南声称,在可能的情况下使用直接字段访问而不是getter/setter是一种很好的做法,因为它的速度要快几倍.

总而言之,我将引用我最喜欢的书之一,J. Bloch撰写的Effective Java,第14项:

总之,公共类不应该公开可变字段.公共类暴露不可变字段的危害较小,但仍然有问题.但是,有时候包私有或私有嵌套类需要公开字段,无论是可变的还是不可变的.


Veg*_*ger 4

我认为当你想对一些变量/对象进行分组时(有点像 C struct),这是有意义的。例如:

class Pixel {
  public int x;
  public int y;
  Color c;
  // Other Pixel related information
}
Run Code Online (Sandbox Code Playgroud)

由于没有方法,因此如果使用错误的值也不会造成任何破坏,并且它可以很好地将这些变量放在一起。

  • 直到有一天您决定 x 和 y 都必须为正,或者您尝试将颜色匹配或“c”上的其他转换作为实现细节时,一切都不会中断。:-) 我同意,对于我们编写的很多代码来说,这一天永远不会到来。我希望您的示例具有视觉上的简单性和吸引力以及内置属性的灵活性。 (4认同)
  • 我不这么认为。如果示例中的“x”已经是底层的属性,那么稍后使用显式 get/set 方法扩展它不会更改接口。“x”仍然只是一个属性。所以,这就是我认为的优势。但有什么缺点呢?我可能错过了一些东西。 (2认同)