在JavaScript中,依赖于对象引用来“监听”变化是否是一种好的实践?

3

我需要实现一个类似仓储模式的对象,用于维护一系列项目列表。这个仓储看起来可能是这样的:

var repository = {

    data: [],

    getAll: function() {
        return this.data;
    },

    update: function() { ... }
}

该 repo 数据的最终消费者将是某些组件。我考虑利用对 repo 数据数组的引用,以便在其发生更改时更新 DOM:

function ItemList() {
    this.data = repository.getData();

    when (this.data is changed) {
        update the view
    }

    this.userInput = function() {
        repository.update();
    }
}

虽然它看起来很整洁,而且据说使用了合法的功能,但这真的是个好主意吗?我应该在存储库中使用观察者/通知吗?

var repository = {
    ...
    onDataChange: function(callback) { ... }
}

这里有一个使用Angular的示例: http://jsfiddle.net/xen8m148/
2个回答

3

取决于您如何实现那个绝对非内置的“已更改”=)通常,如果您想减少虚假处理,发布/订阅模型更好。如果您不关心浪费的CPU周期,那么可以使用Object.observe来查看对象更改。

从软件工程的角度来看,似乎您正在两个所有者之间共享数据,而这比您如何监听更改可能是将来潜在的更大问题。


我怀疑 OP 试图像使用数据存储一样使用 repository。在这种情况下,由于仓库实际上并不操作数据,也不依赖于数据,因此不存在真正的数据耦合问题。 - light
我从不相信事物的名称就代表它们本身,所以即使它被称为“存储库”,我也不会相信没有人最终会在某个时刻让它自己操纵数据。最好事先澄清这些事情(请注意,OP将其称为类似于存储库模式的对象,而不是存储库。这总是令人担忧)。 - Mike 'Pomax' Kamermans
你说得有道理,但我认为这是一个架构问题。如果应用程序的模型采用了一种架构,其中“存储库”是用于存储数据(可能是持久到磁盘?)而不是其他任何操作的层之一,那么我们就不希望它去操纵数据。 - light
如果问题陈述中没有那个“like”,我会同意 =) - Mike 'Pomax' Kamermans
想象一下它不叫做repository。 :) - Ivan Ivanov
我有两个组件引用了同一个对象。 考虑到我的特殊情况,别人可能会破坏某些东西,所以最好使用一些观察者机制。谢谢! - Ivan Ivanov

0

如果您正在使用存储库来抽象化系统中所有数据的基础持久性机制,那么我通常认为发布/订阅模式是不必要的。那么这个存储库实际上是架构中的一个重要组成部分。

如果通信模块不知道彼此的存在,则发布/订阅模式非常有用。如果一个模块/对象试图与像repository这样的架构对象进行通信,则它已经通过约定知道了repository。如果存储库已经作为接口提供了底层复杂性的抽象,为什么您希望您的模块不知道这个接口呢?

但是,如果您不确定存储库是否是架构的一部分,或者如果您只是希望数据和存储库完全解耦到最大程度,则发布/订阅将起作用。

话虽如此,我认为对于像JS这样的前端解释语言,更直接的方法通常是更好的方法。我经常使用发布/订阅进行组件通信,但我认为在架构层之间进行通信时,它们并不需要。事实上,如果您过度使用发布/订阅模式,可能会在发布/订阅消息中遇到命名空间问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接