面向对象的设计
我有两个 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 类。
但从另一个角度来看,我看到该类实现了类似于存储库模式的东西。
我认为的另一种方法是保留 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.
}
}
现在我对这个简单的场景感到完全困惑。在这种情况下,理想的良好面向对象设计应该是什么样的?
I have two csv files A and B. A is the master repository. I need to read those files, map the records of B to A and save the mapped records to another file.
The class to hold records is, say Record. The class to hold the matched records is, say, 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;
}
The mapping scenario goes thus : First, against each record of B, the records of A are filtered using state, city and then zipcode. The records of A thus filtered are then compared with the record of B. This comparison is between the name field, and is a best-match comparison using a fuzzy string algorithm. The best match is selected and saved.
The string matching algorithm will give a percentage of match. Thus, the best result out of all the matches have to be selected.
Now that I tried my best to explain the scenario, I will come to the design issue. My initial design was to make a Mapper class, which will be something as below :
class Mapper
{
List<Record> ReadFromFile(File);
List<Record> FilterData(FilterType);
void Save(List<Record>);
RecordMatch MatchRecord(Record A, Record B);
}
But looking at the design, it simply seems to be a class wrapper over some methods. I dont see any OO design in it. I also felt that the Match() belongs more to the Record class than the Mapper class.
But on another look, I saw the class as implementing something resembling to Repository pattern.
Another way I think is to keep the Mapper class, and just move the Match() method to the Record class, something like this :
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.
}
}
Now I am totally confused in this simple scenario. What would ideally be a good OO design in this scenario?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有趣的是,我现在正在做一个几乎与此完全相同的项目。
简单回答:好的,首先,如果一个方法暂时处于错误的类中,那并不是世界末日!如果您的类都包含测试,那么函数所在的位置很重要,但可以根据您(您所在领域的国王)认为合适的方式进行流畅地更改。
如果您不对此进行测试,那么这将是我的第一个建议。许多比我聪明的人都谈到了 TDD 和测试如何帮助您的类自然地达到最佳设计。
更长的答案:我不喜欢寻找适用于设计的模式,而是喜欢这样思考:每个类必须改变的原因是什么?如果您将这些原因分开(这是 TDD 可以帮助您做的一件事),那么您将开始看到设计模式自然地从您的代码中出现。
以下是一些更改的原因,我可以在阅读您的问题的几遍后想到:
好的,所以,如果实现其中任何一个将使您需要在某处添加“if 语句”,那么也许是实现公共接口的子类的接缝。
另外,假设您想将创建的文件保存在新位置。这是改变的原因之一,并且不应与您需要改变合并策略的情况重叠。如果这两个部分位于同一个类中,则该类现在有两个职责,这违反了单一职责原则< /a>.
所以,这是一个非常简短的示例,要进一步深入了解良好的 OO 设计,请查看 坚实的原则。学习这些内容并在整个面向对象设计中谨慎应用它们是不会出错的。
Amusingly enough, I am working on a project almost exactly like this right now.
Easy Answer: Ok, first off, it is not the end of the world if a method is in the wrong class for a while! If you have your classes all covered with tests, where the functions lives is important, but can be changed around fluidly as you, the king of your domain, sees fit.
If you are not testing this, well, that would be my first suggestion. Many many smarter people than me have remarked on how TDD and testing can help bring your classes to the best design naturally.
Longer Answer: Rather than looking for patterns to apply to a design, I like to think it through like this: what are the reasons each of your classes has to change? If you separate those reasons from each other (which is one thing TDD can help you do), then you will start to see design patterns naturally emerge from your code.
Here are some reasons to change I could think of in a few passes reading through your question:
Ok, so, if implementing any of those would make you need to add an "if statement" somewhere, then perhaps that is a seam for a subclasses implementing a common interface.
Also, let's say you want to save the created file in a new place. That is one reason to change, and should not overlap with you needing to change your merging strategy. If those two parts are in the same class, that class now has two responsibilities, and that violates the single responsibility principle.
So, that is a very brief example, to go further in depth with good OO design, check out the SOLID principles. You can't go wrong with learning those and seeking too apply them with prudence throughout your OO designs.
我尝试了一下。我认为,当涉及到 OO 原则或设计模式时,你无能为力,除了可能使用组合来匹配算法(如果需要的话,可能还可以使用策略和模板)。这是我准备的:(
这是用 Notepad++ 编写的,因此可能存在拼写错误等;建议的类肯定可以从更多的重构中受益,但如果您选择使用此布局,我会将其留给您。)
I gave this a try. There's not so much you can do when it comes to OO principles or design patterns I think, except for maybe using composition for the MatchingAlgorithm (and perhaps Strategy and Template if needed). Here's what I've cooked up:
(This is written in Notepad++ so there can be typos etc; also the proposed classes can surely benefit from a little more refactoring but I'll leave that to you if you choose to use this layout.)