Ras*_*dit 45 language-agnostic singleton design-patterns
当人们使用Monostate模式而不是singleton来维护全局对象时,会出现什么情况?
编辑:我知道Singleton和Monostate模式是什么.在很多场景中也实现了Singleton.只想知道需要实现MonoState模式的场景(案例).
例如.我需要在我的Windows窗体应用程序中维护每个屏幕的列列表.在这种情况下,我可以使用Singleton Dictionary.但是,我在静态全局var中存储了一个List,我想提供索引器(因为我需要动态地将新条目添加到列表中,如果key不存在),我可以将ScreenDetails.ScreenName指定为键并获取ScreenDetails .ColumnsTable.由于索引器无法在静态类上操作,因此我将模式更改为Monostate.
所以我想知道哪些其他场景可能迫使用户使用Monostate而不是Singletons.
dfa*_*dfa 68
monostate和singleton是同一枚奖牌的两个面(全球状态):
即:
Singleton singleton = Singleton.getInstance();
Run Code Online (Sandbox Code Playgroud)
即:
MonoState m1 = new MonoState();
MonoState m2 = new MonoState(); // same state of m1
Run Code Online (Sandbox Code Playgroud)
ega*_*aga 41
以下是Robert C. Martin对此的评论:Singleton vs. Monostate(pdf)
如果您希望通过派生限制现有类,则最好使用SINGLETON,并且您不介意每个人都必须调用instance()方法来获取访问权限.当您希望类的单一性质对用户透明,或者您希望使用单个对象的多态导数时,最好使用Monostate.
Dav*_*les 17
Monostate的基地就是Singleton周围的语法糖.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();
}
}
Run Code Online (Sandbox Code Playgroud)
现在如果我们想要索引访问怎么办?
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));
}
}
Run Code Online (Sandbox Code Playgroud)
排序键怎么样?
public class SortedGlobalTable extends GlobalTable {
@Override
public Iterator <Key> iterator() {
return Collections
.unmodifiableSortedSet(new TreeSet<Key>(keySet())).iterator();
}
}
Run Code Online (Sandbox Code Playgroud)
只要您需要一个或另一个数据视图,就可以实例化相应的子类.
当然,首先,全球数据是否真的是一个好主意是另一个问题,但至少Monostate为您提供了更灵活的使用方式.
有人应该注意单身人士和单身人士是非常危险的模式.他们倾向于被懒惰的程序员误用,他们不想考虑他们想要成为单身人士的对象的生命周期.它们使测试更加困难,并创建了紧密绑定的不灵活系统.
找到真正需要单身人士或单人身份的情况极为罕见.对象协作的首选方法是依赖注入.
有很多关于此的文章: