Я только что натолкнулся на образец, который видел раньше, и хотел узнать мнение по этому поводу. В рассматриваемом коде используется такой интерфейс:
public interface MyCrazyAnalyzer {
public void setOptions(AnalyzerOptions options);
public void setText(String text);
public void initialize();
public int getOccurances(String query);
}
И ожидаемое использование выглядит так:
MyCrazyAnalyzer crazy = AnalyzerFactory.getAnalyzer();
crazy.setOptions(true);
crazy.initialize();
Map<String, Integer> results = new HashMap<String, Integer>();
for(String item : items) {
crazy.setText(item);
results.put(item, crazy.getOccurances);
}
Есть причины для этого. SetText (...) и getOccurances (...) существуют потому, что есть несколько запросов, которые вы, возможно, захотите выполнить после того же дорогостоящего анализа данных, но это может быть реорганизовано в класс результата.
Почему я думаю, что это так плохо: реализация хранит состояние так, как это явно не указано интерфейсом. Я также видел нечто подобное с интерфейсом, который требовал вызвать «prepareResult», а затем «getResult». Теперь я могу думать о хорошо разработанном коде, который использует некоторые из этих функций. Интерфейс Hadoop Mapper расширяет JobConfigurable и Closeable, но я вижу большую разницу, потому что это платформа, использующая пользовательский код для реализации этих интерфейсов, а не сервис, который может иметь несколько реализаций. Я полагаю, что все, что связано с включением «закрытого» метода, который должен быть вызван, является оправданным, поскольку другого разумного способа сделать это не существует. В некоторых случаях, например, в JDBC, это является следствием утечки абстракции, но в двух частях кода, о которых я думаю, это довольно очевидно, что программисты поспешно добавляют интерфейс к классу кода спагетти, чтобы очистить его.
Мои вопросы:
- Все согласны с тем, что это плохо спроектированный интерфейс?
- Это описанный анти-паттерн?
- Этот тип инициализации когда-либо принадлежит интерфейсу?
- Мне это кажется неправильным только потому, что я предпочитаю функциональный стиль и неизменность?
Если это достаточно распространено, чтобы заслужить имя, я предлагаю антишаблон «Секретное рукопожатие» для интерфейса, который заставляет вас вызывать несколько методов в определенном порядке, когда интерфейс по сути не является состоянием (например, Коллекция). .