setter是否应始终设置其直接属性的值而不是关联对象的属性?例如,我有类似下面的内容,其中API客户端采用XML:
Class XML {
private $value;
// Setter for $value exists here
...
}
Class Client {
private $xml; // XML
public function __construct(XML $xml)
{
$this->xml = $xml;
...
}
}
我想在实例化$value
之后修改Client
,因为我想更改或添加一些选项。我应该在XML
中使用setter并在修改请求时重新实例化Client
,或者直接在Client
设置一个setter,这样我就不需要重新实例化{ {1}}?
我通常更喜欢前者,但有理由认为后一种方法更受欢迎吗?除了快速更改之外,我无法想到任何事情。
答案 0 :(得分:1)
通常,如果某个类具有公共方法,则应该访问它们。所以,你可能会认为使用它们没有害处。
然而,问问自己:为什么一个班级首先有吸气剂/孵化器?通常在数据对象的类上找到访问器。这些对象的主要目的是携带数据,它们通常不会做任何东西 - 例如,服务或控制器类。
下一个问题:什么是构造函数?构造函数用于设置对象的内部状态,它将需要 dependencies 作为参数。本着松散耦合的精神,依赖性不应该是其他类的可变性。
查看您的代码,我想您正在编写某种基于XML的客户端应用程序,并且您希望Client
类依赖于XML
类的实例。
从XML
修改Client
对象的内部状态是一个坏主意。其他类依赖于该实例将不知道修改,并可能会得到意想不到的结果。
有几种方法可以解决这个问题,具体取决于要执行的实际任务:
1)如果您只需要为XML
的单个方法调用的上下文设置值,请修改方法以将$value
作为参数。但是不要将它设置为XML
内的对象成员!
class XML
{
public function doSomething($value)
{
…
// do whatever you need with $value,
// but do *not* do something like $this->value = $value
}
}
2)如果与$value
的交互需要在多个操作中保持一致,则应将这些操作从XML
提取到自己的工作者或数据对象类中。然后XML
应该有一个工厂方法来创建这个帮助器类的实例。然后XML
或Client
可能有方法来使用worker:
class XML
{
public function createWorker($value)
{
return new XmlWorker($value, $this);
// XmlWorker might even contain a reference to the XML instance, e.g.
return new XmlWorker($value, $this);
}
public function doSomethingWithWorker(XmlWorker $worker)
{
$value = $worker->getValue();
$worker->doWork();
}
}
class Client
{
private function doSomething()
{
$worker = $this->xml->createWorker($value);
$worker->doWork();
}
}
我建议您阅读设计模式;在这种情况下,特别是关于松耦合&分离关注点,工厂方法和依赖注入。