- 对象通过抽象隐藏其数据,并公开操作该数据的函数。
- 数据结构公开其数据,没有实际意义上的函数。
也许我没有完全理解建议的含义,但这就是我对"对象隐藏它们的数据"的理解。如果您可以帮助我理解这个问题,我将不胜感激!
提前致谢!
确实,C#属性不是数据,而是访问器,所以它是在数据上操作的函数。
应避免公开字段,而不是公开属性。
公共属性是可以的。不需要编写显式的GetHeight()
和SetHeight()
方法,这就是属性的全部意义。在C#中,属性不是数据;最好将其视为一对getter/setter方法。(实际上,属性在生成的IL中被编译为方法。)
数据隐藏是可能的,因为您可以在不更改接口的情况下更改实现。例如,你可以更改
public int Height { get; set; }
进入
public int Height { get { return m_width; } set { m_width = value; } }
如果您决定让您的对象始终保持正方形,使用您的类的代码将不需要进行任何修改。因此,如果您的对象公开属性,则仍然“将其数据隐藏在抽象之后并公开操作该数据的函数”,正如本书建议的那样。它大多是“属性”这个术语的另一种定义。在C#中,属性不是大多数其他编程语言认为的属性。
例如:
C++中的公共属性是:
class foo
{
public:
int x;
};
在C#中对应的术语是公共字段:
class foo
{
public int x;
}
在C#中,我们所称之为属性(properties)的概念,在其他编程语言中通常被称为setter和getter:
C#:
class foo
{
public int X { get; set; }
}
对应的 C++ 代码:
class foo
{
private:
int x;
public:
void setX(int newX) { this->x = newX; }
int getX() { return this->x; }
}
简而言之:
C# 属性完全没问题,只是不要盲目地将它们默认为 get 和 set,并且不要将类中的每个数据字段都作为公共属性,考虑一下你的类的用户真正需要了解/更改什么。
在你完成阅读《代码整洁之道》后,我建议你阅读鲍勃·马丁的另一本书:
在这本书中,大部分内容都是关于一个案例研究的讨论,鲍勃应用了《代码整洁之道》中讨论的原则。我先读了《代码整洁之道》,但回想起来我认为应该先读《敏捷开发》因为《代码整洁之道》更像是一本日常手册或好的软件开发原则指南。
例如,在《敏捷开发》中使用了以下代码:
public class OrderData
{
public string customerId;
public int orderId;
public OrderData() {}
...
}
以下是对使用公共数据进行验证的内容,这与您的问题有关:尽管公共属性并不是立即的代码异味,但请考虑本文:
与 Yechiel Kimchi 合作的编码(来自书籍《每个程序员都应该知道的 97 件事》)
“......不要询问一个对象以获取要使用的信息。相反,请求对象使用它已经具有的信息进行工作。”
这并不总是适用(例如,数据传输对象)。我要注意的是不当亲密关系。
属性实际上是方法。
编译器将属性编译为获取/设置MIL方法。
属性本质上是Getter和Setter方法的简写。Getter和Setter方法的目的是让对象处理变量上的任何操作,以便您可以执行任何额外的操作(例如数据验证)而不会导致不良后果。
我认为您可能会被自动属性所困扰,它们没有支持变量,因此看起来像变量本身。
在纯面向对象编程中,“真正的对象”必须完全隐藏用于实现其职责的数据。因此,应避免公开内部数据,无论是通过公共字段、公共属性还是公共getter/setter函数来完成。
仅通过属性将访问路由到内部数据并不会隐藏或抽象化内部数据!
回答您的问题: - 如果要编写对象,请避免使用公共属性 - 如果要编写数据结构,则可以使用公共属性(公共字段也可以)
下面是需要翻译的内容:
让我们看看这个问题。
虽然公开变量有时会很有用,但通常最好将它们保持私有。
如果对象是唯一控制其变量的对象,则易于使代码组织良好。
想象一下,您想保持高度在0到200之间。如果您有一个设置高度的方法,您可以轻松监视此操作。
例如(我将使用Java为例):
public void setHeight(int newHeight)
{
if (newHeight < 0)
height = 0;
else if (newHeight > 200)
height = 200;
else
height = newHeight
}
正如您所看到的,这种方法非常有结构和控制。
现在想象一下,我们有一行代码可以从外部编辑此高度,因为您选择将其公开。除非您在代码外部进行控制,否则您可能会得到一个与您的程序不兼容的高度。即使您想要控制它,您也将重复代码。
非常基本的例子,但我认为它能说明问题。