Language agnostic 对于只运行自包含计算的类,哪种设计更好?
我目前正在处理一个类,该类计算两个对象之间的差异。我正在努力决定这门课最好的设计是什么。我看到两种选择: 1) 一次性使用类实例。将对象带到构造函数中的diff,并计算该对象的diffLanguage 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
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 );