【问题标题】:How to call the template method by two names in a Template Method Pattern如何在模板方法模式中通过两个名称调用模板方法
【发布时间】:2014-01-22 08:26:33
【问题描述】:

我这样做有点倒退,因为我遵循的是特定的项目说明序列。我有两个java类。其中一个模拟 Linux 的 grep 函数,另一个模拟 lineCount 功能。我已经实现了它们,但项目中的下一步是使用模板方法模式创建一个超类,该模式“将包含其他两个程序共有的所有字段和算法”。

两者之间有很多共同的功能,很明显哪些部分需要成为模板的一部分,哪些需要成为实现的一部分。例如,他们每个人都需要能够根据用于调用该方法的路径字符串创建 File 对象,并使用用于调用该方法的正则表达式搜索 File 的列表方法。这是常见的功能,绝对应该是模板/抽象类的一部分。

如果能声明这样的东西就好了:

public abstract class RegexCommands{
    protected Variables;
    public Map<things> myMethod(variables){
        //common functionality which includes storing and using the variables
        hookMethod(); //based on what you create in commonFunctionality
        return resultAfterHookMethod;
    }
}

public class Grep extends RegexCommands{
    public hookMethod(){
        class specific things;
    }
}

public class lineCount extends RegexCommands{
    public hookMethod(){
        class specific things;
    }
}

只需调用它

RegexCommands myObject = new Grep();
myObject.myMethod(variables);

并让它返回我正在寻找的内容(用于 Grep 对象的 grep 命令,用于 LineCount 对象的 lineCount)。但是,说明明确指出它将像这样调用:

RegexCommands myObject = new Grep();
myObject.grep(variables);

RegexCommands myObject = new LineCount();
myObject.lineCount(variables);

而且使用的变量也有细微的差别。 (例如,lineCount 不需要 substringSelectionPattern)我现在设置它的方式是,hook 方法调用 super 到它们的父级,模板调用 myMethod。这显然不是它应该工作的方式。一方面,我似乎不得不在我的模板中引入非常用方法,这些方法只调用主模板方法,这意味着理论上(虽然我还没有测试过)可以做类似的事情

RegexCommands myObject = new LineCount();
myObject.grep(variables);

这不是我想要允许的行为,并且似乎违背了使用模板的目的。另一个问题(我实际上遇到过)是我的 hookMethods 似乎无法访问在 commonFunctionality 中创建的实例变量(即,当我尝试访问在 commonFunctionality 中创建的匹配器时,即使我返回 null将其声明为实例变量而不是方法级别的范围,就像我更喜欢的那样)。

所以我有点卡住并寻求帮助。我如何让这些对象在模板中使用 myMethod 模式,而没有这种破坏对象分离性的可怕变通方法,以及如何让非常用方法使用 commonFunctionality 中的 ArrayLists 和/或 Maps 而无需将所有内容作为参数传递(有人建议我不要这样做,因为它破坏了使用模板的意义)?

【问题讨论】:

    标签: java


    【解决方案1】:

    一方面,我似乎不得不在我的模板中引入非常用方法,只调用主模板方法,

    是的,您需要针对您的给定要求引入此类方法。但正如您稍后所说,这是不正确的,因为 LineCount 对象可以调用 grep 方法,这可以通过在您将要编写的非常用方法中执行 instance of 检查来避免。如果它符合预期的调用或退出,则执行该工作。

    对于您遇到的原始问题

    我的 hookMethods 似乎无法访问在 commonFunctionality 中创建的实例变量(即,当我尝试访问在 commonFunctionality 中创建的匹配器时,即使我将其声明为实例变量而不是方法,它也会返回 null级范围,就像我更喜欢的那样)。

    你不能在java中定义一个抽象变量,java中唯一合法的变量修饰符是

    public, protected, private, static, final, transient, volatile 
    

    你需要有一个commonFunctionality 的具体实现,你可以有一个getter 方法。您可以在抽象类中为此定义一个抽象方法。更多信息请参考这篇文章的答案Abstract variables in Java?

    【讨论】:

    • 抱歉,打错了。应该是在抽象类中声明的受保护变量,这似乎符合模板模式的方法。我已经更新了问题
    • 另外,commonFunctionality 实际上不应该是一个类。它是包含两个类共有功能的代码的具体实现,相当于此处显示的“某些实现”:oodesign.com/template-method-pattern.html 通用功能包括使用基于匹配器和模式的文件中的 ArrayList 实例化变量正则表达式,但我的钩子方法之后似乎无法访问变量。
    【解决方案2】:
    RegexCommands myObject = new Grep();
    myObject.grep(variables);
    
    RegexCommands myObject = new LineCount();
    myObject.lineCount(variables);
    

    这只有在接口/抽象类RegexCommands 定义了这两种方法时才有可能(在Java 中)。因此,两种实现也需要实现它们。如果你想坚持这个要求,你可以这样做并让Grep.lineCount() 抛出一些异常。

    一种解决方法是让RegexCommands 成为一个外观,仅将来自RegexCommands.grep() 的方法调用委托给new Grep().myObject()

    但是,您应该联系请求者进行澄清。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-15
      • 2013-01-11
      • 2013-03-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多