在 php 中避免访问修饰符的原因 [关闭]
Posted
技术标签:
【中文标题】在 php 中避免访问修饰符的原因 [关闭]【英文标题】:Reasons to avoid access modifiers in php [closed] 【发布时间】:2011-04-13 03:17:37 【问题描述】:什么是不在 php 中使用关键字 public、private、protected 的正当理由?
故事:我与一个团队开始了一个项目,该团队在他们的代码中积极使用访问修饰符(甚至明确地“公开”)并希望说服我也这样做。我总是发现这种东西在像 php 这样的动态语言中完全没用,但我意识到我的直觉在技术讨论中几乎不是一个论据。因此,我正在寻找一个可靠、清晰的解释,为什么访问修饰符在 php 中是无用的(甚至是有害的)。
我知道一些类似的主题已经存在
Importance of protected/private in PHP classes Why not use 'protected' or 'private' in PHP? Best to use Private methods or Protected methods?但是我发布这个有几个原因
我不是在问我是否应该使用“public”。我已经不用了。 我显然不想知道为什么访问修饰符是好的(我知道它们不好,我只需要专家来确认)。 如果您要告诉我“最佳实践”和“OOP 原则”,请不要打扰。TIA
【问题讨论】:
也许您可以详细说明“我知道 [访问修饰符] 不好”部分。 我知道他们很好,但从你的问题来看,我什至懒得去说服你。 唯一不使用访问修饰符 IMO 的原因是,如果您仍在使用古老的 PHP 4,其中不存在它们。 访问修饰符在 Java/C++ 和一般编译代码中是有意义的,它们是可执行的。在未编译的脚本语言中,它们很容易被删除。因此它们应该被认为只是装饰器,因此实际上可以作为编码约定来实现。 (请参阅 Python 中的 underscoritis 以及几乎所有其他脚本语言。PHP 非常孤单,拥有无目的的访问装饰器。) @mario: 多么无争议。它与可执行性无关,但开发人员不关心为什么特定属性/方法是私有/受保护的。不要让我开始谈论 runkit... 这是一个可怕的问题;它假定一个答案,要求提供支持证据,并明确表示它将忽略任何相反的证据。 【参考方案1】:当你想向后兼容 PHP4 时(因为它们在 PHP4 中不存在) 当code convention 定义/允许它时 当不关心encapsulation和information hiding时 当不是 using the OOP paradigm in PHP 时(没有类,没有可见性)在 php 中不使用关键字 public、private、protected 的正当理由?
【讨论】:
@stereofrog 不。我无法摆脱你试图把我吸引到狡辩中的感觉 :) 我很确定你知道我指的是控制对封装状态的访问,而不仅仅是将相关状态分组到对象中。另外,您说我不应该详细说明 OO 原则。 @stereofrog 好吧,那你想听什么?可见性修饰符控制从外部和继承类对封装状态的访问,从而可以更好地控制您的 oo 设计。我带你知道。如果你觉得这是一件多余或毫无意义的事情,那就这样吧。 可见性与编程范式无关。有许多 FP 语言提供模块而不是对象,并为这些模块的“成员”提供可见性。此外,Erlang 允许将参数传递给模块,这与 OO 语言中将参数传递给构造函数的方式非常相似。 我非常同意可见性与封装和信息隐藏没有太大关系。 @Ionut 你关于 Erlang 和其他 FP 语言的论点可能是真的(没有线索),但它们不适用于 PHP。在 PHP 中使用可见性修饰符的唯一范例是在使用 OOP 时。我更改了最后一点以使其更清楚。【参考方案2】:private
修饰符 - 恕我直言 - 被过度使用。它的问题是它无法扩展类。但更重要的是,它是一个概念导致人们编写面向类而不是面向对象的代码。
我对 protected
的属性没有意见。事实上,我认为它应该是唯一使用的范围。 protected
方法通常很麻烦,因为它使测试更加困难。
【讨论】:
我同意保留属性protected
而不是private
。至于测试私有和受保护的方法,看看sebastian-bergmann.de/archives/881-Testing-Your-Privates.html
可能永远不应该使用商定的私有(除非可能在硬件设备驱动程序中 - 但有人用 PHP 编写这些吗?)。但是您真的是要我们推断您认为永远不应该使用“public”吗?
@symcbean 是的,属性应该是protected
- 方法public
。如果您需要public
属性,那么您处理的是数据,而不是对象。为此使用关联数组。
一个类应该使用私有成员和方法,除非它在设计时明确考虑了扩展。将内部标记为私有的类更容易推理,因为您不必掌握扩展类引入的每个行为更改的知识。如果你正在扩展一个类,你应该只改变它的身份,而不是它的功能。
不能再不同意了。 继承是被过度使用的——不是私有关键字。【参考方案3】:
在 PHP 这样的动态语言中,假定程序员知道代码是如何工作的。这意味着程序员知道要调用哪些方法,不应该直接调用哪些方法。
这类似于无类型变量:在有类型语言中,每个变量都是显式类型的,但在 PHP 中,假定程序员知道每个变量的类型。
【讨论】:
这只有在每个程序员都负责整个代码库的情况下才有效。在大型项目中,情况并非总是如此。 在 PHP 这样的语言中,使用这些修饰符比在编译语言中重要得多。程序员可以阅读所有源代码,并需要有关哪些方法对他们有用或只是内部机制的指导【参考方案4】:mario 搞定了(抄自 cmets)
访问修饰符在 Java/C++ 和一般编译代码中是有意义的,它们是可执行的。在未编译的脚本语言中,它们很容易被删除。因此它们应该被认为只是装饰器,因此实际上可以作为编码约定来实现。 (请参阅 Python 中的 underscoritis 以及几乎任何其他脚本语言。PHP 非常孤独,拥有无目的的访问装饰器。)
让你的队友相信有用的 API 相对于限制性封装的优势不会取得太大的成功。语法强制访问装饰器的使用通常是货物崇拜驱动的。
【讨论】:
确实如此。它没有在编译时帮助程序员,只会让程序在运行时更有可能失败。 C++ 中可执行的访问修饰符?从何时起?据我所知,您可以修改头文件,并且始终可以#define private public。不确定这会如何改变 DLL 和静态库的 ABI,但它肯定是可能的。理论上,您始终可以反编译 Java 类文件,将私有更改为公有,然后重新编译。所以它们并不是真正可执行的。 我不明白为什么这里的人们将access modifiers
视为任何一种安全措施......它不是!它旨在组织您的代码,并隐藏您的 API 的user
不需要知道或关心的东西,因此可以减轻他的负担,让他处理更大的问题。这个问题可能只是说“我试图让我的队友相信课程是邪恶的!”并声明功能/程序结构没有任何问题......(这在某些小型项目中可能是有效的)以上是关于在 php 中避免访问修饰符的原因 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章