当使用Monostate模式而不是singleton来维护全局对象时,会发生什么情况?

编辑:
我知道什么是Singleton模式和Monostate模式。在很多情况下还实现了Singleton。只想知道需要实现MonoState模式的场景(案例示例)。

例如。我需要在Windows窗体应用程序中维护每个屏幕的列列表。在这种情况下,我可以使用“单例字典”。但是,我将列表存储在静态全局变量中,并且我想提供索引器(因为如果不存在键,则需要动态向列表中添加新条目),可以在其中指定ScreenDetails.ScreenName作为键并获取ScreenDetails .ColumnsTable。由于索引器无法在静态类上进行操作,因此我将模式更改为Monostate。

因此,我想知道还有哪些其他情况可能会迫使用户使用Monostate而不是Singletons。

最佳答案

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();
  }
}

现在,如果我们想要索引访问该怎么办?

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();
  }

}

任何时候您需要一个或另一个数据 View 时,只需实例化适当的子类即可。

当然,首先要考虑全局数据是否真的是一个好主意,但这是另一个问题,但是至少Monostate为您提供了更多使用方式上的灵活性。

10-08 14:47