【问题标题】:does the 'getters and setters are evil' fail for the view layer?视图层的“getter and setter are evil”是否失败?
【发布时间】:2010-11-21 10:09:27
【问题描述】:

很多人都知道这篇文章:more on getters and setters。我认为它在描绘 getter/setter 的邪恶方面方面做得很有说服力。我还通过尝试将现有项目(未完成)转换为没有 getter/setter 的代码来测试它。有效。代码可读性大大提高,代码更少,我什至设法摆脱了我最初认为确实必要的 getter/setter。除了一处。

让模型进入视图部分是我认为这种方法没有抓住重点的地方。在文章中,作者使用构建器来导出模型。问题是:对于放入构建器的内容的控制与使用 getter 获得的控制一样多。是的,它隐藏了实现,它在模型中的表示方式。但是吸气剂不会从模型中得到与放入其中的非常不同的东西。如果您创建一个通过构造函数传递“5”的 Money 对象,money.getAmount() 将不会返回转换为其他货币或包含一个元素“5”的数组。

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

这个问题有点长。但我想在我的观点上受到挑战。将模型数据传输到视图层时,getter 和 setter 是否邪恶?

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

【问题讨论】:

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


【解决方案1】:

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

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

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

【讨论】:

  • 模型将一些数据推送到视图,但这与获取数据或多或少相同。您是否期望 StackOverflowPost.getTitle() 和 StackOverflowPost.RegisterObserver(view) 之间的结果不同,然后视图会推送(get)标题?
  • 附带说明:以这种方式使用的观察者不是希望在“getSomething”发生变化时得到通知的方式吗?
  • “数据对象”是“结构”在一切都是对象语言中的名称。
  • > 附带说明:以这种方式使用的观察者不是希望在“getSomething”发生变化时得到通知的方式吗?是的,特别是在网络应用程序中,有效负载“foo 在 29843214324 毫秒 UTC 时变为 7”的通知会花费一个消息延迟,但“foo 已更改”、“foo 是什么”、“foo=7”会花费 3 个,并且更容易混淆如果数据以接近延迟的速率变化。
  • @PeteKirkham:让消息包含新值有时可能是有利的,但有时反之亦然。例如,对于进度条之类的东西,让其“完成百分比”的第一次更改触发 UI 队列中的“更新进度条”消息可能会有所帮助,但对于后续更改,在 UI 完成之前不要这样做已更新。显示完成状态的代码不应该关心 UI 多久执行一次此类更新;控件应通过丢弃除最新值之外的所有值来快速处理重复更新。
【解决方案2】:

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

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

在 Scala 的特定情况下,它的提取器类似于 Java 的静态方法,它们接收一个对象作为输入。它要么返回参数,要么返回None,它执行类似于Java 的null 的功能。

这个想法是你可以分解你所写的东西,这几乎是视图可能想要的。

现在,您可能有的另一个概念是,“告诉,不要问”旨在保留业务规则它适用的数据。现在,视图的业务规则必然属于视图,所以你不得不向模型询问数据的问题......如果你不反转游戏。模型可能告诉视图显示数据,将相关字段传递给它,而不是被要求提供它们。所以模型告诉视图显示数据,视图告诉模型更新数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多