我在Java中有一个数据结构,我通过不同的方法填充。一种方法从API填充它,另一种方法从解析一些HTML填充它,另一种方法以不同的方式填充它等等。基本上,每种数据源的方法都可以填充它。我想知道的是,Java为此提供了哪些设计模式?什么是解决这个问题的最好/最干净的OOP方法?
如,
public class Data {
private String foo;
private List<String> bar;
private Map<String, Integer> baz;
public Data (String foo, List<String> bar, Map<String, Integer baz) {
this.foo = foo;
this.bar = bar;
this.baz = baz;
}
// Setters and Getters here, etc
}
public class FacebookParser {
private Document dom;
public static Data parse(Document dom) {
// Parse document
// Create Data object
return Data;
}
}
public class TwitterParser {
private Document dom;
public static Data parse(Document dom) {
// Parse Twitter
Data d = new Data(stuff from twitter);
return d;
}
}
答案 0 :(得分:5)
您想要一个数据,它以不同的形式表示。您感兴趣的部分应该以抽象的方式定义。因此,将数据作为界面是一个很好的起点。
public interface Data {
String getFoo();
List<String> getBar();
Map<String, Integer> getBaz();
}
此数据来自不同的提供商。常见的是我们需要有人提供数据。最后,我们唯一感兴趣的是数据本身,而不是它如何被解析或提供。所以我们需要一个简单的DataProvider接口。
public interface DataProvider {
Data createData();
}
现在我们可以实现那些知道如何获取,解析,处理数据的提供程序类。提供者类不应该处理如何将提供者特定数据转换为我们的公共数据接口。他们只负责创建他们知道的数据实现。
public class FacebookDataProvider implements DataProvider {
public Data createData() {
FacebookSpecificInfo x = ...
FacebookData data = new FacebookData();
// Note that this class does not know anything about foo, bar and baz.
// We are still Facebook context.
data.setName(x.getName());
data.setValues(x.getValues());
data.setHeaders(x.getHeaders());
return data;
}
}
class FacebookData implements Data {
private String name;
private List<String> values;
private Map<String, Integer> headers;
void setName(String name) { this.name = name; }
void setValues(String values) { this.values = values; }
void setHeaders(String headers) { this.headers = headers; }
// This is the part where we switch the context and convert
// Facebook specific data into our expected Data
// ie. Facebook's name field corresponds my foo field.
public String getFoo() { return name; }
public List<String> getBar() { return values; }
public Map<String, Integer> getBaz() { return headers; }
}
答案 1 :(得分:3)
您可以做的是设置一个单独的类来设置Data类的值。
你可以这样:
public class DataPopulator{
public void setTwitterData(Data d){
//your data
}
public void setFacebookData(Data d){
//your data
}
}
这与Adapter Design模式类似,但不完全相同。
您可以查看here。