Синтаксический шаблон не является проблемой сам по себе. Проблема в том, что шаблон часто используется людьми, разрабатывающими программное обеспечение с объектно-ориентированными инструментами, не имея полного понимания концепций ОО. Когда в этом контексте вводятся синглтоны, они, как правило, превращаются в неуправляемые классы, которые содержат вспомогательные методы для каждого небольшого использования.
Синглтоны также являются проблемой с точки зрения тестирования. Они, как правило, затрудняют запись изолированных модульных тестов. Инверсия управления (IoC) и инъекции зависимостей - это шаблоны, предназначенные для преодоления этой проблемы объектно-ориентированным способом, который поддается модульному тестированию.
В сборке собранных мусора синглэты могут быстро стать проблемой в отношении управления памятью.
Существует также многопоточный сценарий, в котором одиночные игры могут стать узким местом, а также синхронизацией вопрос.
Памятный шаблон используется для сохранения состояния объекта, не зная его внутренних структур данных.
Я пытаюсь объяснить это с помощью примера Iterator
public class MementoListIterator<E> implements Iterator<E> {
public static class Memento {
private int savedIndex;
private Memento(MementoListIterator<?> mementoListIterator) {
this.savedIndex = mementoListIterator.index;
}
}
private List<E> elements;
private int index = 0;
public MementoListIterator(List<E> elements) {
this.elements = elements;
}
public Memento save() {
return new Memento(this);
}
public void restore(Memento memento) {
this.index = memento.savedIndex;
}
@Override
public boolean hasNext() {
return this.index < elements.size();
}
@Override
public E next() {
return elements.get(index++);
}
@Override
public void remove() {
throw new UnsupportedOperationException("Not implemented yet");
}
}
Теперь клиент может сохранить любое состояние итератора, не зная, как итератор внутренне управляет его состоянием.
public class Main {
public static void main(String[] args) {
List<String> list = Arrays.asList("A", "B", "C", "D", "E");
MementoListIterator<String> mementoListIterator = new MementoListIterator<String>(
list);
Memento initialState = mementoListIterator.save();
while (mementoListIterator.hasNext()) {
String string = mementoListIterator.next();
System.out.println(string);
}
// Normally we can not re-use the iterator, but
// fortuanatly we saved the initial state.
// restore the initial state and we can use the Iterator again
mementoListIterator.restore(initialState);
while (mementoListIterator.hasNext()) {
String string = mementoListIterator.next();
System.out.println(string);
}
}
}