注入对象改变状态是一种不好的做法吗?

3
假设我在我的代码中的多个不同类中注入了同一实例的列表。从一个类中操纵该列表(例如添加/删除项目)以便其他类可以使用该列表的新状态,这种做法是否不好?除了并发问题外,这是传达类之间变化的正确方式吗?或者,我应该在函数和不同层之间传递列表(如果我必须在许多层之间传递许多变量,则可能会变得混乱),相对于在底层更改列表,并使实例被注入的任何位置都更新,而不污染任何方法签名。
Note: HTML标记已保留

简而言之:是的,这是一个糟糕的模式,原因有很多,尤其是包括线程。 - chrylis -cautiouslyoptimistic-
@chrylis -罢工中- 那些其他原因是什么? - MasterLu32
2个回答

1
我认为更好的解决方案是使用同步访问,这将有助于在实例同时更改列表的情况下,但请允许我告诉您,允许实例直接更改列表是一种非常糟糕的做法,理想情况下应该使对象不可变,然后每个实例都可以在没有问题的情况下使用自己的列表,但如果您需要这种行为,请在业务逻辑中创建持久化策略,一个封装列表并进行全局更改而不共享状态的对象,然后其他实例可以在更改时获取列表的新副本,或者您可以创建一个订阅/通知策略以通知实例列表状态的更改,然后更新它们的列表对象。

那么,您仍然建议只通过列表的包装器来更改状态吗?我不明白这如何有助于避免意外行为。例如,A类通过包装器更改列表状态,但所有其他注入了包装器的类仍然不知道列表状态的更改来自哪里,对吧? - MasterLu32
不,我建议您创建一个持久化策略、一个存储器,该类将处理更改列表的逻辑,将其保存在文件、内存数据库或其他位置,并且其他类可以调用此“包装器”并获取当前列表状态的副本,当列表更改时,它们可以获得新的列表表示(发布/订阅提示)。这样做的好处是,行为不会出现意外,因为您知道列表可能会发生变化,必须向包装器询问(这就是避免意外的方法),以获取新的副本。请记住,我说要将其保存在对象之外的另一个位置。 - Kaneda

0

是的,你说得对。如果你使用任何并发模型,改变注入对象(实例级属性)可能会带来很大的危害。

为了与其他线程通信,我建议使用具有ACID属性的持久性来存储和检索状态更改。

如果您想在不同的对象但相同的执行线程之间传递值,您也可以尝试使用线程本地存储值。 https://dzone.com/articles/painless-introduction-javas-threadlocal-storage


我意识到并发问题。我的问题更关注类之间通信的设计;-) 我编辑了我的原始帖子。 - MasterLu32

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