Monostate与Singleton
当一个人使用一个Monostate模式而不是Singleton来维持一个全局对象时,情况是什么?
编辑:我知道什么Singleton和Monostate模式。 在很多情况下也实现了Singleton。 只是想知道需要实现MonoState模式的场景(例子)。
例如。 我需要维护我的Windows窗体应用程序的每个屏幕列的列表。 在这种情况下,我可以使用单例字典。 然而,我在静态全局variables存储一个列表,我想提供索引(因为我需要dynamic地添加新的条目,如果键不存在),我可以指定ScreenDetails.ScreenName作为一个关键&得到ScreenDetails .ColumnsTable。 由于索引器无法在静态类上运行,因此将模式更改为Monostate。
所以我想知道哪些其他场景可能迫使用户使用Monostate而不是Singletons。
在它的基础上,Monostate仅仅是单身的语法糖。 Monostate变得有趣的地方在于开始子类化时,因为子类可以用不同的行为来装饰共享状态。
一个简单的 – 如果有点人为和不是很有效率:) – 例如:
public class GlobalTable implements Iterable<Key> { /** Shared state -- private */ private static final Map<Key, Value> MAP = new LinkedHashMap<Key, Value>(); /** Public final accessor */ public final Value get(Key key) { return MAP.get(key); } /** Public final accessor */ public final boolean put(Key key, Value value) { return MAP.put(key); } /** Protected final accessor -- subclasses can use this to access the internal shared state */ protected final Set<Key> keySet() { return MAP.keySet(); } /** Virtual -- subclasses can override for different behavior */ public Iterator<Key> iterator() { return Collections.unmodifiableSet(MAP.keySet()).iterator(); } }
现在如果我们想索引访问呢?
public class IndexedGlobalTable extends GlobalTable { public List<Key> getKeysAsList() { return Collections.unmodifiableList(new ArrayList<Key>(keySet())); } public Key getKeyAt(int index) { return getKeysAsList().get(index); } public Value getValueAt(int index) { return get(getKeyAt(index)); } }
如何sorting的密钥?
public class SortedGlobalTable extends GlobalTable { @Override public Iterator <Key> iterator() { return Collections .unmodifiableSortedSet(new TreeSet<Key>(keySet())).iterator(); } }
无论何时您需要数据的一个或另一个视图,只要实例化适当的子类即可。
当然,全球数据是否真的是一个好主意还是另外一个问题,但至lessMonostate为您提供了更多的使用灵活性。
单身和单身是同一枚奖牌(全球国家)的两面:
- monostate强制行为 (所有类实例只有一个值)
- 单身人士迫使一个结构约束 (只有一个例子)
单身使用不透明
即:
Singleton singleton = Singleton.getInstance();
单一用法是透明的
即:
MonoState m1 = new MonoState(); MonoState m2 = new MonoState(); // same state of m1
以下是罗伯特·C·马丁(Robert C. Martin)对此的评价: Singleton vs. Monostate(pdf)
当你有一个你想通过推导来限制的现有类时,最好使用SINGLETON,并且你不介意每个人都必须调用instance()方法来获得访问权限。 当您希望类的单数性质对用户透明时,或者当您想要使用单个对象的多态衍生物时,最好使用单稳态。
有人应该注意单身和单身是极端危险的模式。 他们倾向于被懒惰的编程人员滥用,他们不想将自己想要创build的对象的生命周期考虑为单例。 他们使testing变得更加困难,创造出紧密联系的不灵活的系统。
发现真正需要单身人士或单身人士的情况极为罕见。 对象协作的首选方法是dependency injection。
有很多关于这方面的文章:
- 准单体反模式文章
- scot densmore singltons是邪恶的
- 关于单例堆栈超载