面向对象编程语言的正式语义包括封装状态。在状态改变之前,是否有封装潜在变化的用例?虽然以下示例是使用PHP编写的,请在回答中也考虑语言无关性。
使用上述方法,
背景
我有一个Client
对象,其职责是向服务器发送请求并检索响应,并通过调用API来更改驻留在另一个服务器上的对象的状态。有几个URL,其中一个具有端点create
,另一个具有端点update
。问题是,update
可以用于更新给定对象中的多个不同元素,每个元素都需要不同的参数。
'Layer'对象
假设object
拥有以下对象:
- ImageLayer
- BackgroundLayer
- TextLayer
- AudioLayer
- (N)Layer
为了更改ImageLayer
,API需要:
- 一个ID
- 新图片的URL
为了改变TextLayer
,API需要:
- 一个ID
- 要更改的内容(是字体、大小还是文本内容?)
- 新值
现在,在你认为这可以简单地抽象出一个ID和替换值之前,请考虑AudioLayer
:
- 一个ID
- 比特率
- 新音频文件的URL
- 一些其他值
我的考虑
我最初考虑添加Client::updateImageLayer()
,Client::updateTextLayer()
,但后来意识到Client
对象可能会因未来的(N)Layer
而变得指数级增长。
然后我考虑添加Client::updateLayer(Layer $layer, array $values)
,但我觉得这还不够好。
最后,这里有另一个选项我一直在考虑:一个Change
对象。
更改对象
如果我创建了一个Change
对象来封装对任何特定图层的更改,然后将其传递给Client
,已经经过验证并准备好在请求API时发送,会怎样呢?interface Change
{
public function isValid();
public function getChanges();
}
class ImageLayerChange implements Change
{
protected $url;
protected $id;
public function __construct($id, $url)
{
$this->url = $url;
$this->id = $id;
}
public function isValid()
{
// Use a validator object to check url is valid etc
}
public function getChanges()
{
return array($this->id, $this->url);
}
}
使用上述方法,
Client
对象可以循环一组Change
对象,我甚至可以创建一个ChangeSet
,通过调用isValid()
确保它们都有效,并调用getChanges()
将特定数组直接发送到API,因为所有内容都已经过验证。
问题
我从未听说过建模更改。您对上述选项有何看法?我是否过于复杂化了事情?我喜欢能够随意添加/删除
ChangeSet
中的更改,并且只要它们符合Change
接口,一切都能按预期工作。也许我的方法不是最佳方式?我的解决方案有什么缺点吗?
在使用我的解决方案或您提出的解决方案时,我是否正在使用或应该考虑任何模式?我对良好的代码感兴趣。