我刚刚遇到过一种我以前见过的模式,并希望得到它的意见.有问题的代码涉及这样的接口:
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(); Mapresults = new HashMap (); for(String item : items) { crazy.setText(item); results.put(item, crazy.getOccurances); }
有一些原因是有原因的.setText(...)和getOccurances(...)就在那里,因为在对数据进行相同的昂贵分析之后,您可能想要做多个查询,但这可以重构为结果类.
为什么我认为这是如此糟糕:实现是以一种接口无法清楚指示的方式存储状态.我也看到类似的涉及需要调用"prepareResult"的接口,然后是"getResult".现在,我可以想到使用其中一些功能的精心设计的代码.Hadoop Mapper接口扩展了JobConfigurable和Closeable,但我看到了一个很大的不同,因为它是一个使用实现这些接口的用户代码的框架,而不是可能有多个实现的服务.我认为任何与包括必须被调用的"关闭"方法有关的事情都是合理的,因为没有任何其他合理的方法来做到这一点.在某些情况下,就像JDBC一样,这是抽象漏洞的结果,但在我想到的两段代码中,很明显是程序员急忙在意大利面条代码类中添加一个接口来清理它的结果.
我的问题是:
大家都认为这是一个设计不佳的界面吗?
这是一种描述的反模式吗?
这种初始化是否属于接口?
这对我来说只是错了,因为我偏爱功能风格和不变性吗?
如果这足以得到一个名字,我建议界面的"秘密握手"反模式,当界面本身不具有状态时(如集合),强制您以特定顺序调用多个方法.
是的,这是一种反模式:顺序耦合.
我将重构Options
- 传递给工厂,并Results
从一个analyseText()
方法返回.