问题描述
当一个人使用单静止图案而不是单句内订单维护全局对象的情况是什么?
编辑: 我知道什么是单身和单声道图案.在许多情况下还实施了单身人士.只想知道需要实现单音频模式的方案(案例示例).
例如.我需要在我的Windows表单应用程序中维护每个屏幕列的列表.在这种情况下,我可以使用单身词典.但是,我正在静态全局var中存储一个列表,我想提供索引器(如果不存在键,我需要动态添加新的条目),我可以在其中指定screendetails.screennames.screennames.screenname作为键并获取Screendetails .columnstable.由于索引器无法在静态类上操作,因此我将模式更改为单静电素.
所以我想知道哪些其他情况可能会强迫用户使用单静电素而不是单例.
推荐答案
在其基本单静电脉中,只是周围的句法糖.单音阶变得有趣的地方是当您开始进行子类别时,因为子类可以以不同的行为装饰共享状态.
一个简单的 - 如果有些人为而不是很高效:) - 示例:
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)); } }
排序键怎么样?
public class SortedGlobalTable extends GlobalTable { @Override public Iterator <Key> iterator() { return Collections .unmodifiableSortedSet(new TreeSet<Key>(keySet())).iterator(); } }
任何需要数据的视图时,您只需实例化适当的子类.
当然,首先,全球数据是否真的是一个好主意,但至少是单静止的,您的使用方式更具灵活性.
其他推荐答案
单声道和辛格尔顿是同一奖牌(全球状态)的两个面:
- 单声道迫使A 行为(在所有类实例中只有一个值)
- 单身人士强迫A 结构约束(仅一个实例)
单例使用不透明
即:
Singleton singleton = Singleton.getInstance();
单静止用法是透明的
IE.:MonoState m1 = new MonoState(); MonoState m2 = new MonoState(); // same internal state of m1 (e.g. static)
其他推荐答案
这是 Robert C. Martin 必须说的:http://staff.cs.utu.fi/~jounsmed/doos_06/material/material/singletonandonandmonostate .
当您拥有要约束的现有类时,最好使用单身 通过派生,您不介意每个人都必须调用实例() 获得访问的方法.当您想要的奇异性质时,最好使用单静止 课程要透明到用户,或者当您想使用多态性衍生物时 单个对象的.
问题描述
What are the scenarios when one would use a Monostate pattern instead of singleton inorder to maintain a global object?
Edit: I know what Singleton and Monostate patterns are. Have also implemented Singleton in quite a few scenarios. Just want to know the scenarios (case examples) where MonoState pattern needs to be implemented.
For eg. I need to maintain list of columns per screen in my windows forms app. I could use a Singleton Dictionary in this case. However, I am storing a List in the static global var and I wanted to provide indexers (since I need to dynamically add new entry to the list if key is not present) where I could specify ScreenDetails.ScreenName as a key & get the ScreenDetails.ColumnsTable. Since indexers can't operate on a static class I changed the pattern to Monostate.
So I would like to know which other scenarios may compel a user to use Monostate instead of Singletons.
推荐答案
At its base Monostate is just syntactic sugar around Singleton. Where Monostate gets interesting is when you start subclassing, because the subclasses can decorate the shared state with different behavior.
A simple -- if somewhat contrived and not very efficient :) -- example:
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(); } }
Now what if we want indexed access?
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)); } }
How about sorted keys?
public class SortedGlobalTable extends GlobalTable { @Override public Iterator <Key> iterator() { return Collections .unmodifiableSortedSet(new TreeSet<Key>(keySet())).iterator(); } }
Any time you need one or the other view of the data, you just instantiate the appropriate subclass.
Of course, whether global data is really a good idea in the first place is another question, but at least Monostate gives you more flexibility in how you use it.
其他推荐答案
monostate and singleton are two faces of the same medal (global state):
- monostate forces a behaviour (only one value along all class instances)
- singleton forces a structural constraint (only one instance)
singleton usage is not transparent
i.e.:
Singleton singleton = Singleton.getInstance();
monostate usage is transparent
i.e.:MonoState m1 = new MonoState(); MonoState m2 = new MonoState(); // same internal state of m1 (e.g. static)
其他推荐答案
Here's what Robert C. Martin has to say about it: Singleton vs. Monostate (pdf)
SINGLETON is best used when you have an existing class that you want to constrain through derivation, and you don’t mind that everyone will have to call the instance() method to gain access. Monostate is best used when you want the singular nature of the class to be transparent to the users, or when you want to employ polymorphic derivatives of the single object.