我不是PHP开发人员,所以我想知道在PHP中使用显式getter/setter的优点和缺点是什么,在纯OOP风格中,带有私有字段(我喜欢的方式):
class MyClass {
private $firstField;
private $secondField;
public function getFirstField() {
return $this->firstField;
}
public function setFirstField($x) {
$this->firstField = $x;
}
public function getSecondField() {
return $this->secondField;
}
public function setSecondField($x) {
$this->secondField = $x;
}
}
或者只是公共字段:
class MyClass {
public $firstField;
public $secondField;
}
There are many ways to create sourcecode in a netbeans-convention. This is nice. It makes thinks such easyer === FALSE. Just use the traditionel, specially if you are not sure which one of the properties should be encapsuled and which one not. I know, it is a boi.... pla... code, but for debugging-works and many other thinks it is the better, clear way. Dont spend to much time with thousend of arts how to make simple getters and setters. You cannot implement too some design patterns like the demeter-rule and so on, if you use magics. In specific situation you can use magic_calls or for small, fast and clear solutions. Sure you could make solutions for design-patters in this way too, but why to make you live more difficult.
除了这里已经很好的和受人尊敬的答案之外,我还想扩展一下没有setter /getter的PHP。
PHP没有getter和setter语法。正如Dave所指出的那样,它提供了子类或魔法方法来允许“挂钩”和覆盖属性查找过程。
魔术让我们这些懒惰的程序员在积极参与一个项目并熟悉它的时候,用更少的代码做更多的事情,但通常是以可读性为代价的。
在PHP中,由于强制使用类似getter/setter的代码架构而导致的每个不必要的函数,都会在调用时涉及自己的内存堆栈框架,并浪费CPU周期。
可读性:代码库会导致代码行膨胀,这会影响代码导航,因为更多的LOC意味着更多的滚动。
偏好:个人而言,作为我的经验法则,我接受静态代码分析的失败
作为避免走上这条神奇之路的标志,只要我当时没有明显的长期利益。
谬论:
一个常见的论点是可读性。例如,$someobject->width比$someobject->width()更容易读取。然而,与行星的周长或宽度可以假定为静态的不同,对象的实例(例如$someobject)需要一个width函数,可能需要测量对象的实例宽度。
因此,可读性的提高主要是因为确定的命名方案,而不是通过隐藏输出给定属性值的函数。
__get / __set使用:
属性值的预验证和预清理
字符串。
"
一些{mathsobj1->generatelatex}多
行文本{mathsobj1->latexoutput}
{mathsobj1->generatelatex}有很多变量
一些原因
"
在这种情况下,generatelatex将遵循actionname + methodname的命名方案
特殊的,明显的案例
dnastringobj - >同源框(one_rememberable_parameter美元)- >千钧一发——> findrelated ()
dnastringobj - >同源框(one_rememberable_parameter美元)- > gttccaatttga - > findrelated ()
注意:PHP选择不实现getter/setter语法。我并不是说getter /setter一般都不好。
Well, PHP does have magic methods __get, __set, __isset & __unset, which is always a start. Alas proper (get it?) OO properties is more than magic methods. The main problem with PHP's implementation is that magic methods are called for all inaccessible properties. Which means you have to Repeat Yourself (eg. by calling property_exists()) in the magic methods when determining if name is actually a property of your object. And you can't really solve this general problem with a base class unless all your classes inherit from ie. ClassWithProperties, since PHP lacks multiple inheritance.
相比之下,Python的新样式类提供了property(),它允许显式地定义所有属性。c#有特殊的语法。
http://en.wikipedia.org/wiki/Property_(编程)
验证+格式化/导出值
setter允许您验证数据,getter允许您格式化或派生数据。对象允许您将数据及其验证和格式化代码封装到一个鼓励DRY的整洁包中。
例如,考虑以下包含出生日期的简单类。
class BirthDate {
private $birth_date;
public function getBirthDate($format='Y-m-d') {
//format $birth_date ...
//$birth_date = ...
return $birth_date;
}
public function setBirthDate($birth_date) {
//if($birth_date is not valid) throw an exception ...
$this->birth_date = $birth_date;
}
public function getAge() {
//calculate age ...
return $age;
}
public function getDaysUntilBirthday() {
//calculate days until birth days
return $days;
}
}
您需要验证所设置的值是否为
有效日期
不是将来
而且您不希望在整个应用程序中(或在多个应用程序中)执行此验证。相反,将成员变量设置为受保护或私有(以便使setter成为唯一的访问点)并在setter中进行验证更容易,因为这样无论对象来自应用程序的哪个部分,您都知道对象包含有效的出生日期,如果您想添加更多验证,那么可以将其添加到单个位置。
你可能想要添加多个格式化程序来操作同一个成员变量,即getAge()和getDaysUntilBirthday(),你可能想要在getBirthDate()中强制一个可配置的格式,这取决于地区。因此,我更喜欢通过getter始终访问值,而不是将$date->getAge()与$date->birth_date混合。
在扩展对象时,getter和setter也很有用。例如,假设您的应用程序需要在某些地方允许150年以上的出生日期,而在其他地方则不允许。在不重复任何代码的情况下解决这个问题的一种方法是扩展BirthDate对象,并将额外的验证放在setter中。
class LivingBirthDate extends BirthDate {
public function setBirthDate($birth_date) {
//if $birth_date is greater than 150 years throw an exception
//else pass to parent's setter
return parent::setBirthDate($birth_date);
}
}