В своей основе 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));
}
}
Как насчет отсортированных ключей?
public class SortedGlobalTable extends GlobalTable {
@Override
public Iterator <Key> iterator() {
return Collections
.unmodifiableSortedSet(new TreeSet<Key>(keySet())).iterator();
}
}
В любое время, когда вам нужно одно или другое представление данных, вы просто создаете соответствующий подкласс.
Конечно, действительно ли глобальные данные - хорошая идея, во-первых, это другой вопрос, но, по крайней мере, Monostate дает вам больше гибкости в их использовании.