视图层的'getter和setter是邪恶的'失败了吗?

时间:2009-08-20 17:50:12

标签: model-view-controller oop encapsulation setter getter

很多人都知道这篇文章:more on getters and setters。我认为它描绘了吸气者/制定者的邪恶方面的令人信服的工作。我还尝试将现有项目(未完成)转换为没有getter / setter的代码来测试它。有效。代码可读性大大提高,代码更少,我甚至设法摆脱了我最初认为它们确实是必要的getter / setter。除了一个地方。

将模型放到视图部分是我认为这种方法错过了重点的地方。在文章中,作者使用构建器来导出模型。问题是:对于使用getter获得的内容,可以控制构建器中的内容。是的,它隐藏了实现,它在模型中的表示方式。但是吸气者并没有从模型中脱离出与那里放置的东西截然不同的东西。如果你创建一个通过构造函数传递'5'的Money对象,money.getAmount()将不会将此转换为其他货币或者包含一个元素'5'的数组。

你得到了什么。通过视图,我们设置值,以及当我们从一个应该保存我们首先设置的对象的它们(get)时我们期望的那些值。导出这些的构建器只是期望相同。

这个问题有点长。但我想对我的观点提出质疑。 getter和setter对于将模型数据传输到视图层是不是很邪恶?

有很多人认为getter / setter根本不是邪恶的。这也不是我想听到的辩护,因为我认为他们在其他地方是邪恶的,而不是我提到的那些。

2 个答案:

答案 0 :(得分:3)

对于非常简单的情况,数据对象没有任何封装行为,因此基于改进行为封装的参数并不真正适用。

我构建的大多数视图都是事件驱动的。在事件驱动视图中,您在模型上注册更改事件并在模型更改时更新视图,而不是传递“模型”并获取每个属性的值,然后更新其状态是否已更改。鉴于事件机制允许模型将其状态推送到视图,视图不需要getter来拉动状态(如果模型也是监听器,则不需要构建器)。如果只更改具有数千个属性的模型中的一个属性,那么构建器和将新模型传递给视图的效果如何?

如果不是将模型视为数据的全局,而是将其视为在从构建器/持久层向侦听器/视图转发状态通知事件时实现缓存,那么很容易看出它具有可以封装的行为,而不是纯粹可以被轮询的状态。

答案 1 :(得分:1)

Scala语言中使用了另一种模型,但它可以在任何地方使用。它是Constructor / Extractor模型。构造函数就是一个类的构造函数。提取器是一种方法,当被调用时,将返回参数,这些参数传递给构造函数,将创建此对象的克隆。

对于动态语言,您只需返回一个列表并完成它。对于静态类型语言,您可以使用对象列表的方式,然后必须将其处理为可以正确分配每个类型,或者您必须具有类型参数化的元组类,以便您可以返回每个参数正确的类型。

在Scala的特定情况下,它的Extractors类似于Java的静态方法,它们接收一个对象作为输入。它返回参数,或返回None,它执行类似于Java null的函数。

这个想法是你可以分解你的作品,这几乎就是一个观点所需要的。

现在,您可能拥有的另一个概念是“告诉,不要问”打算将业务规则应用于其中。现在,视图的业务规则必然属于视图,因此您不得不向模型询问数据...如果您不反转游戏。模型可以告诉视图显示数据,将相关字段传递给它而不是被要求它们。因此模型告诉视图显示数据,视图告诉模型更新它。