我有以下代码和体系结构(实际上这是一个非常简化的版本)consting一个抽象和一个具体的类。
public abstract class AbstractProcessor {
public void updateDataFromUrl(String url) {
//Download url
//Decrypt, and do a lot of stuff,
String data = "abc"; //Result from downloading
String processed = processData(data);
//Do a lot of other things with the transformed data
}
public abstract String processData(String data);
}
final class ConcreteProcessor extends AbstractProcessor {
public void updateData(int year, int month, int day) {
String url = String.format("http://%d.%d.%d", year, month, day);
updateDataFromUrl(url);
}
@Override
public String processData(String data) {
//Process the data
//---------------
//PROBLEM:
//----------------
//Need access to year, month, day ....
return null;
}
}
updateDataFromUrl
方法包含很多代码(在processData
调用之前和之后的展位),我想在几个处理器中重用它,因此我将代码放入一个抽象类中。
问题是:我想访问提供给新添加的updateData
方法的数据(此处为year
,month
,day
)。当调用流经不知道这些参数的抽象类时,这些信息就会丢失。如何修改此体系结构以保留此信息?
以下解决方案出现在我的脑海中,都有明显的缺点:
procecssData
方法中只需要哪些参数,而且从不在网址中?)updateDataFromUrl
方法拆分为两种方法(processData
调用之前的部分和之后的部分)。现在直接在ConcreteProcessor中使用这些方法。 (问题:在updateDataFromUrl
调用之前和之后,processData
方法有很多我需要的上下文。如何在新创建的方法之间传输这些数据?)答案 0 :(得分:2)
两个想法:
使用ConcreteProcessor
中的实例变量来存储年,月,日。两种方法都可以访问对象的实例变量。但是,抽象类无法访问它们。注意:对象不再是线程安全的。您必须具有多个独立处理器才能同时处理数据。
反转依赖关系并使用合成。泛型类Processor
包含通用逻辑。当您调用updateDataFromUrl
时,您还会传递实现ProcessingStrategy
的{{1}}实例(实际上是一种回调)。
可能有几种不同的想法。
答案 1 :(得分:1)
只有微小的修改才会导致这种解决方案(如果我没有错过某些观点(未经测试))。
您将获得以下好处:
ConcreteProcessor
可以保持不变最好不要从ConcreteProcessor
返回updateData
,而是从表示转换数据的某些不可变类型返回。
public abstract class AbstractProcessor {
public void updateDataFromUrl(String url) {
//Download url
//Decrypt, and do a lot of stuff,
String data = "abc"; //Result from downloading
String processed = processData(data);
//Do a lot of other things with the transformed data
}
public abstract String processData(String data);
}
final class ConcreteProcessor extends AbstractProcessor {
public static ConcreteProcessor updateData(int year, int month, int day) {
ConcreteProcessor p = new ConcreteProcessor(year, month, day);
p.updateDataFromUrl(url);
return p;
}
private /* instance vars for year, month, day, url, ... */
private ConcreteProcessor(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
this.url = String.format("http://%d.%d.%d", year, month, day);
}
@Override
public String processData(String data) {
//Process the data
//---------------
// NO PROBLEM:
//----------------
//Easy to access to year, month, day using the instance vars
return null;
}
}
但整体概念看起来像一个线性管道,因此最好使管道更明确。你需要某种状态,但我认为这不应该是使用泛型的大问题。