我有两个csv文件A和B。A是主资料库。我需要读取这些文件,将B的记录映射到A,并将映射的记录保存到另一个文件。保存记录的类是,比如说Record。保存匹配记录的类是,比如说,RecordMatch。
class Record
{
string Id;
string Name;
string Address;
string City;
string State;
string Zipcode;
}
class RecordMatch
{
string Aid;
string AName;
string Bid;
string BName;
double NameMatchPercent;
}映射场景是这样的:首先,针对B的每条记录,使用州、城市和邮政编码过滤A的记录。然后,将这样过滤的A的记录与B的记录进行比较。这种比较是在名称字段之间进行的,并且是使用模糊字符串算法的最佳匹配比较。选择并保存最佳匹配。
字符串匹配算法将给出匹配的百分比。因此,必须从所有匹配中选择最好的结果。
现在,我已经尽了最大努力来解释场景,接下来我将讨论设计问题。我最初的设计是创建一个Mapper类,如下所示:
class Mapper
{
List<Record> ReadFromFile(File);
List<Record> FilterData(FilterType);
void Save(List<Record>);
RecordMatch MatchRecord(Record A, Record B);
}但从设计上看,它看起来就像是某些方法上的类包装。我在里面没有看到任何面向对象的设计。我还觉得Match()更多地属于Record类而不是Mapper类。
但从另一个角度来看,我认为这个类实现了类似于Repository模式的东西。
我认为另一种方法是保留Mapper类,只需将Match()方法移动到Record类,如下所示:
class Mapper
{
List<Record> ReadFromFile(File);
List<Record> FilterData(FilterType);
void Save(List<Record>);
}
class Record
{
string id;
string name;
string address;
// other fields;
public RecordMatch Match (Record record)
{
// This record will compare the name field with that of the passed Record.
// It will return RecordMatch specifyin the percent of match.
}
}现在我完全被这个简单的场景搞糊涂了。在这种情况下,理想的OO设计是什么?
发布于 2011-09-14 21:42:14
我试过了。当涉及到OO原则或设计模式时,我认为除了使用MatchingAlgorithm的组合(如果需要,还可以使用策略和模板)之外,您可以做的并不多。这是我想出来的:
class Mapper {
map(String fileA, String fileB, String fileC) {
RecordsList a = new RecordsList(fileA);
RecordsList b = new RecordsList(fileB);
MatchingRecordsList c = new MatchingRecordsList();
for(Record rb : b) {
int highestPerc = -1;
MatchingRecords matchingRec;
for(Record ra : a) {
int perc;
rb.setMatchingAlgorithm(someAlgorithmYouVeDefined);
perc = rb.match(ra);
if(perc > highestPerc) {
matchingRec = new MatchingRecords(rb, ra, perc);
}
}
if(matchingRec != null) {
c.add(matchingRec);
}
}
c.saveToFile(fileC);
}
}
class MatchingAlgorithm {
int match(Record b, Record a) {
int result;
// do your magic
return result;
}
}
class Record {
String Id;
String Name;
String Address;
String City;
String State;
String Zipcode;
MatchingAlgorithm alg;
setMatchingAlgorithm(MatchingAlgorithm alg) {
this.alg = alg;
}
int match(Record r) {
int result; -- perc of match
// do the matching by making use of the algorithm
result = alg.match(this, r);
return result;
}
}
class RecordsList implements List<Record> {
RecordsList(file f) {
//create list by reading from csv-file)
}
}
class MatchingRecords {
Record a;
Record b;
int matchingPerc;
MatchingRecords(Record a, Record b, int perc) {
this.a = a;
this.b = b;
this.matchingPerc = perc;
}
}
class MatchingRecordsList {
add(MatchingRecords mr) {
//add
}
saveToFile(file x) {
//save to file
}
}(这是用Notepad++编写的,所以可能会有打字错误等;而且,建议的类肯定可以从更多的重构中受益,但如果您选择使用这种布局,我将把它留给您。)
发布于 2011-09-14 21:58:11
有趣的是,我现在正在做一个几乎和这个完全一样的项目。
简单的回答:好的,首先,如果一个方法在错误的类中出现了一段时间,这并不是世界末日!如果你的类都被测试所覆盖,那么函数所在的位置很重要,但可以根据你这个领域之王的意愿流畅地进行更改。
如果您不是在测试这个,那么,这将是我的第一个建议。许多比我更聪明的人已经评论过TDD和测试如何帮助您的类自然地实现最佳设计。
Longer回答:而不是寻找应用于设计的模式,我喜欢这样思考:你的每个类必须改变的原因是什么?如果您将这些原因彼此分开(这是TDD可以帮助您做的一件事),那么您将开始看到设计模式自然地出现在您的代码中。
下面是我在阅读你的问题时可以想到的一些修改的理由:
“
好吧,所以,如果实现其中的任何一个会让你需要在某个地方添加"if语句“,那么也许这就是实现公共接口的子类的接缝。
另外,假设您想要将创建的文件保存到一个新位置。这是改变的一个原因,不应该与你需要改变你的合并策略重叠。如果这两个部分在同一个类中,那么该类现在有两个职责,这就违反了single responsibility principle。
所以,这是一个非常简短的例子,为了更深入地了解好的OO设计,请查看SOLID principles。学习这些并在整个OO设计中谨慎地应用它们是不会错的。
https://stackoverflow.com/questions/7415139
复制相似问题