Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/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
Java 扩展战略模式的功能_Java_Design Patterns_Strategy Pattern - Fatal编程技术网

Java 扩展战略模式的功能

Java 扩展战略模式的功能,java,design-patterns,strategy-pattern,Java,Design Patterns,Strategy Pattern,我正在开发一个比较文件的应用程序。我决定使用策略设计模式来处理不同的格式,因此我有如下内容: public class Report { CompareStrategy strategy; ... } public interface CompareStrategy { int compare(InputStream A, InputStreamB); } 然后,我自然地为不同的文件格式实现了比较方法 现在假设我想添加另一个方法,该方法处理比较的某些限制(例如,在Exce

我正在开发一个比较文件的应用程序。我决定使用策略设计模式来处理不同的格式,因此我有如下内容:

public class Report {
   CompareStrategy strategy;
   ...
}


public interface CompareStrategy {
   int compare(InputStream A, InputStreamB);
}
然后,我自然地为不同的文件格式实现了比较方法

现在假设我想添加另一个方法,该方法处理比较的某些限制(例如,在Excel或csv文件中省略一行,或者在XML中省略一个节点)

最好是:

  • 在接口和每个实现中添加另一个方法(目前很少有)
  • 编写一个从CompareStragey继承的新接口,然后实现它
  • 第二个问题是:由于差异可以是各种类型的,所以可以通过改变标记接口来实现以下功能:

    int compareWithDifferences(..., Iterable<Difference> differences);
    
    int compareWithDifferences(…,Iterable differences);
    

    然后继续定义特定文件格式的差异意味着什么?

    我认为您应该编写另一个继承自CompareStragy的接口。如果您需要
    compareWithDifferences()
    您可以,但是您不必使用此接口,您仍然可以使用没有差异的简单接口

    正如乔纳森所说,如果你能预见到困难,就要做好准备。那样的话,我想你应该做好准备。实际上,创建另一个接口不会花费您太多时间,以后也不必重构

    现在假设我想添加另一个方法,该方法处理比较的某些限制(例如,在Excel或csv文件中省略一行,或者在XML中省略一个节点)

    看来你需要

    您可以创建一些抽象类,如

    public abstract class XMLCompareStrategy implements CompareStrategy {
    
        public int compare(InputStream A, InputStreamB) {
            // several steps
            customMethod(...);
            // more steps
        }
    
        protected abstract ... customMethod(...);
    
    }
    

    通过这种方式,您可以创建几个具有主要或核心功能的类,并为每种情况提供自定义详细信息

    答案取决于您的需要:

    • 如果该方法将始终执行,请将其添加到现有接口。如果它是可选的,那么创建一个新接口来扩展当前接口,然后实现的类可以实现基接口或子接口(如果它需要这两种方法)
    • 对于你的第二个问题——在我看来,这有点像过度设计,但同样取决于你的需要

    不错。简明扼要!所以(只是为了满足我的分类狂热;)-这将是策略(实现每个格式的抽象类的基本接口)和模板(根据功能将抽象类扩展到具体类)的组合。是这样吗?是的。使用该策略,您可以将每种格式的实际实现解耦,使用模板,您可以为每种格式提供基本实现,还可以为您提供多个算法自定义点1。如果
    compare
    实现对所有实现类都是通用的,那么抽象类就是一个很好的解决方案。2.请记住,如果使用抽象类而不是接口,您将失去扩展任何其他类的能力。如果扩展类遇到麻烦,您可以通过再次实现策略模式来摆脱抽象方法;)提示:请确保使用浏览器具有的内置语言检查。您的设计似乎违反了LSP,因为根据输入流包含的不同策略,不同的策略会成功或失败,这是意外的,因为将一种策略替换为另一种策略不应影响程序的正确性。你真的应该质疑这个界面是否给你带来了价值。如果是这样的话,至少应该明确说明策略不能处理任何类型的内容,例如:boolcancompare(a,b)你能详细说明一下吗?我设计的策略与文件的格式紧密相连(有些是表,有些是标记语言)。InputStream的使用旨在促进单元测试。我的意思是,您必须知道哪些实例可以比较哪些文件类型,这些文件类型首先违背了接口的目的,因为应用程序必须了解实现,并且不能只使用
    compareStragy
    ,而不考虑提供了哪种实现。如果您需要可扩展性,那么您很可能需要这样一个接口,以便动态注册新的比较器,但这不是策略模式,而且必须从接口中清楚地看到,使用错误的内容调用比较器可能会引发错误。但这不是真的吗,战略模式为不同的环境定义了不同的战略?正是这种情况,因为解析文件的方法不能与文件格式分离。我遵循这里描述的原则:从你自己的来源。。。“策略定义了一组可以互换使用的算法”。这根本不是您的情况,例如,您不能将
    xmlcomparatestrategy
    与HTML内容互换使用。因此,
    strategy1.比较(a,b)
    可能有效,而
    strategy2.比较(a,b)
    可能对相同的
    a
    b
    失败。战略模式不应该如此。