Language agnostic 对于只运行自包含计算的类,哪种设计更好?

Language agnostic 对于只运行自包含计算的类,哪种设计更好?,language-agnostic,oop,Language Agnostic,Oop,我目前正在处理一个类,该类计算两个对象之间的差异。我正在努力决定这门课最好的设计是什么。我看到两种选择: 1) 一次性使用类实例。将对象带到构造函数中的diff,并计算该对象的diff public class MyObjDiffer { public MyObjDiffer(MyObj o1, MyObj o2) { // Calculate diff here and store results in member variables } public boolean

我目前正在处理一个类,该类计算两个对象之间的差异。我正在努力决定这门课最好的设计是什么。我看到两种选择:

1) 一次性使用类实例。将对象带到构造函数中的diff,并计算该对象的diff

public class MyObjDiffer {
  public MyObjDiffer(MyObj o1, MyObj o2) {
    // Calculate diff here and store results in member variables
  }

  public boolean areObjectsDifferent() {
    // ...
  }

  public Vector getOnlyInObj1() {
    // ...
  }

  public Vector getOnlyInObj2() {
    // ...
  }

  // ...
}
2) 可重用的类实例。构造函数不接受参数。有一个“calculateDiff()”方法,该方法将对象带到diff并返回结果

public class MyObjDiffer {
  public MyObjDiffer() { }

  public DiffResults getResults(MyObj o1, MyObj o2) {
    // calculate and return the results.  Nothing is stored in this class's members.
  }
}

public class DiffResults {
  public boolean areObjectsDifferent() {
    // ...
  }

  public Vector getOnlyInObj1() {
    // ...
  }

  public Vector getOnlyInObj2() {
    // ...
  }
}
微分将是相当复杂的(细节对问题来说无关紧要),因此需要有许多辅助函数。如果我采用解决方案1,那么我可以将数据存储在成员变量中,而不必传递所有信息。它稍微紧凑一些,因为所有内容都在一个类中处理

然而,从概念上讲,“不同”是特定于某一组结果的,这似乎很奇怪。选项2从实际计算结果的逻辑中分割结果

编辑:选项2还提供了使“myObjDifferent”类保持静态的功能。谢谢kitsune,我忘了提那件事了

我很难看到任何一个选项有任何明显的赞成或反对意见。我认为这种事情(一个只处理一些一次性计算的类)必须经常出现,也许我遗漏了一些东西。所以,我想我应该向云提出这个问题。这里的一个或另一个选项是否有重要的优点或缺点?一个天生更好吗?这有关系吗


我是用Java做的,所以可能会有一些限制,但是设计的总体问题可能与语言无关。

我会选择numero 2并思考我是否应该将其设置为静态。

我会选择numero 2并思考我是否应该将其设置为静态。

这取决于你将如何使用差异。在我看来,将diff视为逻辑实体是有意义的,因为它需要支持一些操作,如“getDiffString()”或“numHunks()”或“apply()”。我可能会选择你的第一个,然后像这样做:

public class Diff
{
    public Diff(String path1, String path2)
    {
        // get diff

        if (same)
            throw new EmptyDiffException();
    }

    public String getDiffString()
    {

    }

    public int numHunks()
    {

    }

    public bool apply(String path1)
    {
        // try to apply diff as patch to file at path1.  Return
        // whether the patch applied successfully or not.
    }

    public bool merge(Diff diff)
    {
        // similar to apply(), but do merge yourself with another diff
    }
}

使用像这样的diff对象也可能有助于保存一堆补丁,或者序列化到压缩的归档文件,或者“撤消”队列,等等。

这取决于如何使用diff。在我看来,将diff视为逻辑实体是有意义的,因为它需要支持一些操作,如“getDiffString()”或“numHunks()”或“apply()”。我可能会选择你的第一个,然后像这样做:

public class Diff
{
    public Diff(String path1, String path2)
    {
        // get diff

        if (same)
            throw new EmptyDiffException();
    }

    public String getDiffString()
    {

    }

    public int numHunks()
    {

    }

    public bool apply(String path1)
    {
        // try to apply diff as patch to file at path1.  Return
        // whether the patch applied successfully or not.
    }

    public bool merge(Diff diff)
    {
        // similar to apply(), but do merge yourself with another diff
    }
}

使用这样一个diff对象也可能有助于保存一堆补丁,或者序列化到压缩的归档文件,可能是一个“undo”队列,等等。

为什么要编写一个只用于计算两个对象之间差异的类?这听起来像是静态函数或类的成员函数的任务

为什么要编写一个类,其唯一目的是计算两个对象之间的差异?这听起来像是静态函数或类的成员函数的任务

我会选择静态构造函数方法,比如

Diffs diffs = Diffs.calculateDifferences(foo, bar);

这样,在计算差异时就很清楚了,并且没有办法滥用对象的接口。

我会选择静态构造函数方法,类似这样的方法

Diffs diffs = Diffs.calculateDifferences(foo, bar);

这样,在计算差异时就很清楚了,并且没有办法滥用对象的接口。

我喜欢明确开始工作的想法,而不是让它在实例化时发生。此外,我认为结果足够充分,足以证明他们自己的水平。你的第一个设计对我来说没那么干净。使用该类的人必须理解,在执行计算之后,其他一些类成员现在持有结果。选项2更清楚地说明了正在发生的事情。

我喜欢明确开始工作的想法,而不是让它在实例化时发生。此外,我认为结果足够充分,足以证明他们自己的水平。你的第一个设计对我来说没那么干净。使用该类的人必须理解,在执行计算之后,其他一些类成员现在持有结果。选项2更清楚地说明了正在发生的事情。

使用面向对象编程 使用选项2,但不要将其设置为静态

战略模式 这样,可以将一个实例
myobjdifferent
传递给需要计算对象之间差异的任何人

如果您发现在不同的上下文中使用不同的规则进行计算,您可以创建一个新的策略来适应。使用现有的代码,您可以扩展MyObjDifferent并重写其方法,这当然是可行的。更好的方法是定义一个接口,并将其作为一个实现

任何合适的重构工具都能够从myobj中“提取接口”,并在以后的某个时候用接口类型替换对该类型的引用,如果您想延迟决策的话。将“选项2”与实例方法(而不是类过程)结合使用,可以提供这种灵活性

配置实例 即使您永远不需要编写新的比较方法,您也可能会发现指定选项来定制基本方法的行为是有用的。如果你想使用“DIFF”命令来比较文本文件,你会记得有多少种不同的选项:空白和大小写敏感度,输出选项等等。在面向对象编程中,最好的模拟是将每个差异过程视为一个对象,选项设置为该对象的属性。 使用选项2,但不要将其设置为静态

战略模式 这样,可以将一个实例
myobjdifferent
传递给需要计算对象之间差异的任何人

如果,沿着这条路走,你会发现
DifferFactory df= new DifferFactory();
MyObjDiffer mod= df.getDiffer();
mod.getResults( x, y );