为什么《代码整洁之道》建议避免使用受保护的变量?

这是一系列每周发布的帖子的一部分,重点介绍技术爱好者遇到的常见问题,并由Stack Exchange的用户回答,这是一个由社区驱动的免费网络,包含 80 多个问答站点。

Matsemann 询问:《Clean Code》(http://rads.stackoverflow.com...建议在“格式”章节的“垂直距离”部分避免使用受保护变量,书中提到:概念紧密相关的应在垂直方向上彼此靠近。显然,此规则不适用于属于不同文件的概念。但紧密相关的概念不应分开到不同文件中,除非有非常好的理由。实际上,这是应避免使用受保护变量的原因之一。原因是什么?相关:"为什么我们需要私有变量?"

答案:问题所在(135 票)

Telastyn 回复:应避免使用受保护变量,原因如下:

  1. 它们往往会导致YAGNI问题。除非有子类实际使用受保护成员,否则应将其设为私有。
  2. 它们往往会导致LSP问题。受保护变量通常具有一些内在的不变性(否则它们将是公共的)。继承者需要维护这些属性,人们可能会搞砸或故意违反。
  3. 它们往往会违反OCP。如果基类对受保护成员做了太多假设,或者继承者对类的行为过于灵活,可能会导致基类的行为被该扩展修改。
  4. 它们往往会导致为扩展而继承,而不是组合。这往往会导致更紧密的耦合、更多违反SRP的情况、更难测试,以及一系列属于“优先使用组合而不是继承”讨论的其他问题。但正如你所看到的,所有这些都是“往往”。有时受保护成员是最优雅的解决方案。受保护的函数往往有较少的这些问题。但有很多事情需要谨慎对待。对于任何需要这种谨慎的事情,人们都会犯错误,在编程世界中这意味着错误和设计问题。

答案:具体来说…(13 票)

Robert Harvey 回复:我没有读过这本书,但我可以尝试理解 Uncle Bob 的意思。如果在某个东西上放置protected,意味着类可以继承它。但成员变量应该属于包含它们的类,这是基本封装的一部分。在成员变量上放置protected会破坏封装,因为现在派生类可以访问基类的实现细节。这与在普通类上使变量public时的问题相同。为了解决这个问题,可以将变量封装在受保护的属性中,如下所示:protected string Name { get { return name; } private set { name = value; } },这允许在派生类中使用构造函数参数安全地设置name,而不会暴露基类的实现细节。相关:"在何处声明变量?"

答案:避免寻找(7 票)

J. Polfer 回复:Uncle Bob 的论点主要是关于距离:如果有一个对类很重要的概念,将该概念与类捆绑在同一个文件中。不要在磁盘上的两个文件中分开。受保护的成员变量分散在两个地方,有点像魔法。你引用这个变量,但它在这里没有定义……它在哪里定义?于是开始寻找。他的论点是最好完全避免protected。现在我不认为这个规则需要一直严格遵守(比如:你不应该使用protected)。看看他所指的精神……将相关的东西捆绑到一个文件中——使用编程技术和特性来做到这一点。我建议你不要过度分析并陷入细节中。

认为你知道为什么最好避免受保护变量?不同意上述观点?将你的专业知识带到Stack Exchange 上的问题,这是一个包含 80 多个站点的网络,你可以在其中就像网络应用自行车专利等几乎所有主题交换专业知识。

阅读 6
0 条评论