Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 面向对象设计_Oop_Design Patterns_Repository Pattern_Object Oriented Analysis - Fatal编程技术网

Oop 面向对象设计

Oop 面向对象设计,oop,design-patterns,repository-pattern,object-oriented-analysis,Oop,Design Patterns,Repository Pattern,Object Oriented Analysis,我有两个csv文件A和B。A是主存储库。我需要读取这些文件,将B的记录映射到A,并将映射的记录保存到另一个文件。 保存记录的类是,比如说记录。保存匹配记录的类是,比如说,RecordMatch class Record { string Id; string Name; string Address; string City; string State; string Zipcode; } class RecordMatch { string Aid; stri

我有两个csv文件A和B。A是主存储库。我需要读取这些文件,将B的记录映射到A,并将映射的记录保存到另一个文件。 保存记录的类是,比如说记录。保存匹配记录的类是,比如说,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的每个记录,使用state、city和zipcode过滤A的记录。然后将这样过滤的A的记录与B的记录进行比较。这种比较是在名称字段之间进行的,是使用模糊字符串算法进行的最佳匹配比较。将选择并保存最佳匹配项

字符串匹配算法将给出匹配的百分比。因此,必须从所有匹配中选择最佳结果

既然我已经尽了最大的努力来解释这个场景,那么我就来谈谈设计问题。我最初的设计是制作一个Mapper类,如下所示:

class Mapper
{
  List<Record> ReadFromFile(File);
  List<Record> FilterData(FilterType);
  void Save(List<Record>);
  RecordMatch MatchRecord(Record A, Record B);
}
类映射器
{
列表ReadFromFile(文件);
列出FilterData(FilterType);
作废保存(列表);
记录匹配匹配记录(记录A、记录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.
  }
}
类映射器
{
列表ReadFromFile(文件);
列出FilterData(FilterType);
作废保存(列表);
}
课堂记录
{
字符串id;
字符串名;
字符串地址;
//其他领域;
公共记录匹配匹配(记录)
{
//此记录将比较名称字段与传递的记录的名称字段。
//它将返回RecordMatch Specific(匹配百分比)。
}
}

现在我完全被这个简单的场景弄糊涂了。在这种情况下,理想的OO设计是什么?

我尝试了一下。我认为,当涉及到OO原则或设计模式时,除了可能使用组合来实现匹配算法(如果需要的话,还可能使用策略和模板)之外,没有什么可以做的。以下是我做的:

    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
        }
    }
类映射器{
映射(字符串文件A、字符串文件B、字符串文件C){
记录列表a=新记录列表(文件a);
记录列表b=新记录列表(文件b);
MatchingRecordsList c=新的MatchingRecordsList();
(记录rb:b){
int highestPerc=-1;
匹配记录匹配记录;
记录(ra:a){
int perc;
rb.设置匹配算法(您定义的一些算法);
perc=rb.匹配(ra);
如果(perc>最高perc){
matchingRec=新的匹配记录(rb、ra、perc);
}
}
if(matchingRec!=null){
c、 添加(匹配REC);
}
}
c、 保存文件(fileC);
}
}
类匹配算法{
整数匹配(记录b,记录a){
int结果;
//施展你的魔法
返回结果;
}
}
课堂记录{
字符串Id;
字符串名;
字符串地址;
字符串城市;
字符串状态;
字符串Zipcode;
匹配算法;
设置匹配算法(匹配算法alg){
this.alg=alg;
}
整数匹配(记录r){
int结果;--匹配百分比
//利用该算法进行匹配
结果=alg.匹配(本,r);
返回结果;
}
}
类RecordsList实现列表{
记录列表(文件f){
//通过读取csv文件创建列表)
}
}
类匹配记录{
记录a;
记录b;
int-matchingPerc;
匹配记录(记录a、记录b、int perc){
这个a=a;
这个.b=b;
this.matchingPerc=perc;
}
}
类匹配记录列表{
添加(匹配记录mr){
//加
}
saveToFile(文件x){
//保存到文件
}
}

(这是用记事本++编写的,因此可能会有打字错误等;而且建议的类肯定会从更多的重构中受益,但如果您选择使用此布局,我将把这留给您。)

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

简单回答:好的,首先,如果一个方法在一段时间内处于错误的类中,这并不是世界末日!如果您的类都包含了测试,那么函数所在的位置很重要,但是可以在您这个领域的王者认为合适的时候进行流畅的更改

如果你不测试这个,那将是我的第一个建议。许多比我更聪明的人都谈到了TDD和测试如何帮助您的类自然地达到最佳设计

更详细的回答:与其寻找适用于设计的模式,我喜欢这样思考:每个类必须更改的原因是什么?如果您将这些原因彼此分离(这是TDD可以帮助您做到的一件事),那么您将开始看到设计模式从代码中自然出现

以下是我在阅读你的问题时可以想到的一些改变的原因:

  • 数据文件更改格式/添加列
  • 你可以找到一个更好的匹配算法,或者:“现在我们也要过滤手机号码”
  • 您还需要使其与xml/yaml/etc文件匹配
  • 要求您以新格式/位置保存它
  • 好的,那么,如果实现其中任何一个将使您需要添加一个“if语句”