PHP类定义:单个访问器/变异器或带有开关()的_集()?
定义PHP类时,首选/最佳做法是什么?我忽略了哪些关键的区别 似乎编写一个PHP类定义:单个访问器/变异器或带有开关()的_集()?,php,oop,coding-style,Php,Oop,Coding Style,定义PHP类时,首选/最佳做法是什么?我忽略了哪些关键的区别 似乎编写一个\uu set()魔术方法,并在其中放入一个开关()构造,以及我希望允许访问的所有私有成员的案例,会更简洁、方便。它不会从类内部自动调用,但同样也不会setFoo(),因此如果我想在内部使用访问器/变异器,我必须以任何方式显式调用方法 另一个区别是,在类外的代码中,我总是可以使用与$obj->foo相同的方式访问成员变量,无论是公共(直接)还是私有(使用\u set()),而不是使用许多单独的方法 我想这主要归结为一种审美
\uu set()
魔术方法,并在其中放入一个开关()
构造,以及我希望允许访问的所有私有成员的案例,会更简洁、方便。它不会从类内部自动调用,但同样也不会setFoo()
,因此如果我想在内部使用访问器/变异器,我必须以任何方式显式调用方法
另一个区别是,在类外的代码中,我总是可以使用与$obj->foo
相同的方式访问成员变量,无论是公共(直接)还是私有(使用\u set()
),而不是使用许多单独的方法
我想这主要归结为一种审美选择。例如,如果我有一个购买的地址数据,我不希望有16个或更多单独的访问器方法,仅用于名字、姓氏、address1、address2、city、state等,每个方法用于装运和计费数据
有什么我忽略的关键区别吗?(一个复杂的IDE可能会因为标记为private而拒绝在类外自动完成成员名吗?)?提前感谢您的输入。为您希望从外部访问的每个成员提供单独的访问器。我尝试了这两种方法,并发现使用访问器的原因如下:
- 无论您使用什么来记录您的API(doxygen/PHPdoc/Zend),生成的文档都不会显示可通过神奇函数访问的成员
- 您可以记录访问器。您应该能够在文档中写一行这样的内容:“重要!此函数连接到数据库,速度会非常慢,如果可以,请使用otherFunction()
- 访问器的实现对任何人都很容易看到。我不想深入研究200行魔术函数的细节,以检查访问器除了设置/获取值之外是否还有其他作用(这就是我们编写访问器的原因)
- 您已经提到了IDE的自动完成
- __get()函数有一个定义良好的函数头,因此您将无法创建返回引用的getter,例如(这在处理数组时非常有用,例如,
-如果没有引用,您将需要再次调用setter。)$numbers=&$object->getNumbers();$numbers[]=4;
- 使用
,您将无法为每个访问者生成phpdoc\u set
- 现代IDE正在使用phpdoc,这也意味着如果使用神奇的方法,您将不会得到类型提示或代码完成(不过,在这一点上,使用
可能会有所帮助)@property
- phpdoc没有问题
- 您可以使用所需的任何参数和返回类型
- 您可以明确指出可以使用哪些方法
- 更容易为每个项目使用特定的代码,而无需使用非常长的
方法\u集
最后,如果您只是使用一些属性来存储数据,并且不需要定义任何特定的行为,为什么不将它们公开为公共,并允许用户直接访问这些属性?在大多数情况下,我确实需要使用特定的行为,即使只是用regex验证电子邮件地址。无论如何,对简单属性使用访问器也不是一个坏主意——如果以后确实需要添加特定的行为,则不必重写代码的其余部分来使用访问器,而直接使用公共道具。(这就是_set()方便的地方。)关于返回类型,这个问题可以用更强类型的语言来回答,因为我没有一个神奇的方法可以返回各种类型。从这个意义上说,uu set()只是一个便宜的快捷方式。谢谢。来自经验之声的精彩观点。我以前倾向于个人访问器,但现在我被说服了。感谢您的回复。“为您希望从外部访问的每个成员使用单独的访问器”ew,不!抽象失败。对于要从外部访问的对象的每个语义属性,使用单独的访问器。在您的特定用例中,这些概念之间可能存在一对一的相关性,也可能没有。例如
getX、getY、getZ
vsgetDimensions
。