首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >面向对象设计

面向对象设计
EN

Stack Overflow用户
提问于 2011-09-14 18:52:41
回答 2查看 434关注 0票数 3

我有两个csv文件A和B。A是主资料库。我需要读取这些文件,将B的记录映射到A,并将映射的记录保存到另一个文件。保存记录的类是,比如说Record。保存匹配记录的类是,比如说,RecordMatch。

代码语言:javascript
复制
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类,如下所示:

代码语言:javascript
复制
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类,如下所示:

代码语言:javascript
复制
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设计是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-09-14 21:42:14

我试过了。当涉及到OO原则或设计模式时,我认为除了使用MatchingAlgorithm的组合(如果需要,还可以使用策略和模板)之外,您可以做的并不多。这是我想出来的:

代码语言:javascript
复制
    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++编写的,所以可能会有打字错误等;而且,建议的类肯定可以从更多的重构中受益,但如果您选择使用这种布局,我将把它留给您。)

票数 1
EN

Stack Overflow用户

发布于 2011-09-14 21:58:11

有趣的是,我现在正在做一个几乎和这个完全一样的项目。

简单的回答:好的,首先,如果一个方法在错误的类中出现了一段时间,这并不是世界末日!如果你的类都被测试所覆盖,那么函数所在的位置很重要,但可以根据你这个领域之王的意愿流畅地进行更改。

如果您不是在测试这个,那么,这将是我的第一个建议。许多比我更聪明的人已经评论过TDD和测试如何帮助您的类自然地实现最佳设计。

Longer回答:而不是寻找应用于设计的模式,我喜欢这样思考:你的每个类必须改变的原因是什么?如果您将这些原因彼此分开(这是TDD可以帮助您做的一件事),那么您将开始看到设计模式自然地出现在您的代码中。

下面是我在阅读你的问题时可以想到的一些修改的理由:

  1. 数据文件更改格式/添加列
  2. 您可以找到更好的匹配算法,或者:"now we
  3. to filter on cell phone number

  1. 系统要求您也使其与xml/yaml/etc文件匹配
  2. 系统要求您将其保存在新的are中。

好吧,所以,如果实现其中的任何一个会让你需要在某个地方添加"if语句“,那么也许这就是实现公共接口的子类的接缝。

另外,假设您想要将创建的文件保存到一个新位置。这是改变的一个原因,不应该与你需要改变你的合并策略重叠。如果这两个部分在同一个类中,那么该类现在有两个职责,这就违反了single responsibility principle

所以,这是一个非常简短的例子,为了更深入地了解好的OO设计,请查看SOLID principles。学习这些并在整个OO设计中谨慎地应用它们是不会错的。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7415139

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档