清洁代码:对象应该具有公共属性吗?

JSp*_*ang 27 c# abstraction properties object data-structures

我正在阅读"清洁代码"这本书,并且正在努力解决这个问题.在讨论对象和数据结构时,它指出以下内容:

  • 对象将其数据隐藏在抽象之后,并公开对该数据进行操作的函数.
  • 数据结构公开其数据并且没有有意义的功能.

所以,我从中获得的是我不应该在我的对象上有任何公共属性,我应该只有对属性执行操作的方法.如果我确实需要访问属性,它们应该在数据结构上,可以从我对象上的方法返回?使用这种方法,似乎我需要为我的对象上的Height属性使用GetHeight()和SetHeight()方法,而不是仅使用属性的getset.

也许我不明白究竟是什么建议,但这是我对" 对象隐藏他们的数据 "的理解.如果你能帮助我理解这一点,我将非常感激!

提前致谢!

ono*_*nof 31

实际上,C#属性不是数据,是一个访问器,因此它是一个操作数据的函数.

你应该避免公共领域,而不是公共财产.

  • 是的,但公共字段在数据转换对象上是可以的 (3认同)
  • 我避免使用DTO,但在特定情况下.当必须使用它们时,我更喜欢自动属性. (2认同)

Tho*_*mas 19

公共财产很好.不必编写显式GetHeight()SetHeight()方法就是属性的全部内容.C#中的属性不是数据; 它最好被视为一对getter/setter方法.(属性实际上被编译成生成的IL中的方法.)

数据隐藏是可能的,因为您可以在不更改接口的情况下更改实现.例如,你可以改变

public int Height { get; set; }
Run Code Online (Sandbox Code Playgroud)

public int Height { get { return m_width; } set { m_width = value; } }
Run Code Online (Sandbox Code Playgroud)

如果你认为你的对象应该总是正方形.使用您的类的代码不需要任何修改.

因此,如果您的对象公开公共属性,它仍然"将数据隐藏在抽象背后并公开对该数据进行操作的函数",正如本书所推荐的那样.


Mor*_*dur 10

它主要是"财产"一词的另一个定义.C#中的属性不是大多数其他语言所认为的属性.

示例:
C++公共属性是:

class foo
{
  public:
    int x;
};
Run Code Online (Sandbox Code Playgroud)

C#中的相应术语将是一个公共字段:

class foo
{
  public int x;
}
Run Code Online (Sandbox Code Playgroud)

我们在C#中命名为属性的是其他语言的setter和getter:

C#:

class foo
{
  public int X { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

对应的C++:

class foo
{
  private:
    int x;

  public:
    void setX(int newX) { this->x = newX; }
    int  getX() { return this->x; }
}
Run Code Online (Sandbox Code Playgroud)

简而言之:
C#属性是完全正常的,只是不要盲目地默认它们来获取设置,并且不要让你的类中的每个数据字段都成为公共属性,考虑一下你的类的用户真正需要知道/改变的内容.


Rob*_*boy 9

完成清洁代码后,我建议你阅读Bob Martin的另一本书:

C#中的敏捷原则模式和实践

在本书中,本书的大量内容讨论了一个案例研究,并在其中,Bob应用了清洁代码中讨论的原则.我首先阅读清洁代码但回想起来我认为应该首先阅读"敏捷模式......",因为清洁代码更像是日常手册或良好软件原则的手册.

例如,在"敏捷模式..."中使用以下代码:

public class OrderData
{
public string customerId;
public int orderId;
public OrderData() {}

...

}
Run Code Online (Sandbox Code Playgroud)

以下对公共数据使用的验证处理您的问题:

不要被使用公共数据成员冒犯.这不是真正意义上的对象.它只是数据的容器.它没有需要封装的有趣行为.将数据变量设为私有,并提供getter和setter将是浪费时间.我可以使用结构而不是类,但我希望OrderData通过引用而不是值传递.


在旁边:

就个人而言,我不得不说罗伯特·马丁已经为SW开发者社区(以及Martin Fowler,Michael Feathers ......)做了大量的贡献.我认为他们必须阅读.


Tru*_*ill 5

虽然公共属性不是直接的代码味道,但请考虑以下文章:

Yechiel Kimchi的理性编码(来自每个程序员应该知道的97件事)

"......不要让对象获取信息.相反,要求对象使用已有的信息进行工作."

这不会一直发挥作用(例如,数据传输对象).我要注意的是不恰当的亲密关系.

  • 挂在我桌上的报价+1!感谢您的参考. (2认同)