带有可插拔组件的应用程序的面向对象设计中的java问题
我正试图重构一个丑陋的代码,并使其在将来易于扩展
应用程序应该是一系列具有输入和输出的组件。组件的链接方式使当前组件的输入是一个(或多个)先前组件的输出
以下是我到目前为止的简要概述:
Reader
- 表示数据源
- 可以是硬盘上的文件、在线资源、数据库等
Splitter
- 输入为
Reader(s)
- 将reader提供的内容拆分为多个部分
- 输出是
Reader(s)
的拆分内容
- 输入为
Model
- 输入为
Splitter(s)
- 基于
Splitter(s)
输出创建某物的模型 - 输出是静默的,但您可以说输出是一个内部状态,可以查询单个输入
- 输入为
Tester
- 输入是一个模型
- 它可以查询模型以获得某些数据的结果
- 输出是可选的,但如果使用它,它是(queryInput,queryOutput)数据流
Writer
- 输入实际上是产生对象集合的任何东西
- 将该集合写入任何位置
- 我不知道现在的输出应该是什么
因此,我希望能够通过以下方式插入它们:
-->Reader-->Splitter-->Model-->Tester-->Writer-->
然而,这也是一个有效的组合(它显然只不过是一个简单的数据传输)
-->Reader-->Writer-->
现在,由于我希望能够(几乎)将所有内容都插入到所有内容,并(可能)创建相当长的链,因此我假设我必须有某种Pluggable
接口
另外,在创建如此大的链时,我可能希望将其包装在Facade
后面。由于我希望每个可插拔组件(类)都被其他组件替换,所以我想到了Strategy
模式
现在,由于我已经在这里提到了术语链,我想到了Chain of Responsibility
模式,方式如下(或类似方式):
public interface Pluggable<InputType, OutputType> {
public void consume(Pluggable<?, InputType> previous);
public Collection<OutputType> produce();
}
例如,如果我想让我的Splitter
拆分由Reader
提供的File
列表,它可能看起来像这样:
public class Splitter<InputType, OutputType> implements Pluggable<?, InputType> {
public void consume(Pluggable<?, InputType> previous) {
// retrieves for example a list of InputType objects
}
public Collection<OutputType> produce() {
// filters the collection it got and returns a sublist for example
}
}
最后,组件可能看起来像这样:
Reader<File, Foo> --> Splitter<Foo, Foo> --> Model<Foo, Void> --> Test<Model, Bar> --> Writer<Bar, DAO>
我不知道如何描述我遇到的问题,但我相信这样的事情是可以实现的。例如,这里是RapidMiner进程的图像
请注意,我不是试图复制或复制Rapid Miner,只是分配给我的项目看起来可以以类似的方式实现
我非常感谢任何关于如何设计这样的应用程序的帮助
# 1 楼答案
在我看来,这是一个结构性问题,而不是行为问题。因此,我想到了两种模式
复合图案。它以树状的方式组织对象。我想说的和你的差不多。子对象链接到其父对象,如果接口正确,只需在父对象上调用“doWork()”-方法并遍历到叶子
我想到的模式二是装饰师。您可以创建一个表示数据的类,并在每个步骤中对其进行修饰
老实说,我会选择第一种选择
当然,您可以将这些模式与其他模式(例如访问者或迭代器等)结合起来,但在我看来,这将是未来的趋势:)