我看起来像这样(当然它比这个样本复杂一点):
public class DoOnAll {
private List<IActionPerformer> actionPerformers;
public DoOnAll(List<IActionPerformer> actionPerformers) {
this.actionPerformers = actionPerformers;
}
public void callFromSomeWhere(String path) {
File f = new File(path);
List<File> list = Arrays.asList(f.listFiles());
for (File file : list) {
for (IActionPerformer action : actionPerformers) {
action.perform(file);
}
}
}
}
public interface IActionPerformer {
public void perform(File file);
}
public class SomePerformer implements IActionPerformer {
public void perform(File file) {
if (getFileType(file) = ".txt") {
doSomething
}
}
}
我有两个问题:
我应该将SomePerformer
中的条件移动到另一个方法boolean accept(File file)
,例如,还要将此方法声明添加到接口中吗?
如果是这样,我将如何“收集”DoOnAll
中所有已接受的课程?只需浏览actionPerformers
列表并将所有加入的列表添加到另一个列表中,然后浏览已接受的列表和.perform
上的列表?或者方法中是否有另一种常用的方式?
将actionPerformrs
列表注入课程有哪些方法?
我想编写独立的实现并在一个文件中定义,比如xml文件,将哪些注入到列表中。
答案 0 :(得分:5)
在回答第二个问题时,您应该查看dependency injection。 Java有一些很好的框架可以帮助你,例如:
Spring特别允许您在XML文件中定义应用程序的组件和依赖项。有关示例,请参阅:
最后一个链接有一个关于构造函数注入的小节:创建带有依赖关系的java对象,就像你的类DoOnAll
所需要的那样。
答案 1 :(得分:3)
WRT问题2:我同意Dan,Spring或Guice。
WRT问题1:恕我直言我不会创建一个条件方法作为界面的一部分。无论哪种方式,你必须在每个对象上调用一个方法,为什么要调用两个?让对象确定是否应该进行处理。这也可以防止在类上调用多个方法的任何潜在开销。它还使调用方法更直接。
答案 2 :(得分:2)
问题1.您所描述的是一种责任链模式。您还可以检查Performer是否可以在文件中执行,是否可以从列表中执行下一个执行者。如果没有剩下的表格 - 例外。如果无法执行,您可以使用其他方法或使perform
方法返回true / false throw异常。
问题2.以最简单的方式使用Spring。这样做:
ApplicationContext context = new ClassPathXmlApplicationContext("some_configuration.xml");
您也可以试用Google Guice。
答案 3 :(得分:2)
这里的一般建议:
开始简单(拥有你的拥有),并在你有一个用途(案例)时扩展你的界面。我只是在AbstractPerformer.performIfAccepted(File)方法中执行if (accept(someFile)) perform(someFile);
。
看到其他答案,我不是这方面的专家。
答案 4 :(得分:2)
1)首先要保持简单......我认为你需要决定你想做什么。是(a)给第一响应者提供响应特定类型文件存在的机会,(b)允许该类型的所有可能响应者响应或(c)识别文件的单个特定响应者类型。
如果:
a)见Peter Gwiazda的回答(IMO)。
b)类似于(a)但允许链中的多个响应者。
c)如果文件类型始终存在特定响应者,则可以使用工厂根据文件类型获取特定实例。这隐藏了实现的细节。在IoC环境中存在缺点,但如果需要,仍可以使用IoC填充工厂。
2)一般来看一般的“Inversion of Control”比喻,特别是Spring(如已经建议的那样)。