【问题标题】:Want to Understand logic behind Template Methods想了解模板方法背后的逻辑
【发布时间】:2017-05-07 18:08:14
【问题描述】:

伙计们,我只是想澄清我对抽象类方法工作的怀疑。希望我能得到满意的答复。

我们有 Class Base(abstract class) 和 Class Derived(concrete class) 定义如下:

abstract class Base {
   abstract public void operation_first();

   public void operation_second{
      operation_first();
   }
}

class Derived extends Base {
   public void operation_first{
     //Implementation
   }
}

现在当我们像 as 一样调用 operation_second 方法时

new Derived().operaton_second();

它总是调用派生类operation_first 方法。 我只是想知道这种方法背后的逻辑,其中基类称为派生类方法。

【问题讨论】:

  • 你在 operation_second() 中调用 operation_first() 方法,所以它的调用
  • 抽象方法需要被覆盖,只有它们被称为抽象方法。所以当你调用抽象方法时,它总是会调用你的派生类覆盖方法......就是这样
  • 是的,我知道我在 operation_second() 方法中调用了 operation_first() 方法,但我想知道为什么会这样。
  • 我试了一下,但对我没有帮助。我的疑问仍然不清楚, operation_first() 方法是如何在这里调用的

标签: java android oop


【解决方案1】:

这称为“后期绑定”。唯一实现的类函数operation_first 是 Derived ,并且由于后期绑定 Base 类知道此实现。

请看https://en.wikipedia.org/wiki/Late_binding

【讨论】:

    【解决方案2】:

    当有多个(相关)类具有公共代码时,我会使用这种模式。您可以将公共部分放在基类中,并将特定代码放在派生类中,即您的 operation_first 方法。然后,在基类中,您可以使用一种方法(这将是您的 operation_second 方法),您可以在其中放置对所有派生类都相同的操作流程。这样您就可以删除重复的代码并将操作流程集中在一个位置。

    public abstract class AbstractMessageHandler<T extends RequestMessage>() {
        public ResponseMessage process(T requestMessage) {
            // some common logic
    
            validate(requestMessage);
    
            // some more common logic
    
            Transaction transaction = getTransaction(requestMessage);
    
            // some more common logic
    
            ResponseMessage response = processTransaction(transaction, requestMessage);
    
            // some more common logic
    
            return response;
        }
    
        protected abstract boolean validate(T requestMessage);
    
        protected abstract Transaction getTransaction(T requestMessage)
    
        protected abstract ResponseMessage processTransaction(Transaction transaction, T requestMessage);
    
    }
    

    使用策略模式调用流程方法的代码示例。 EXECUTOR_MAP 包含 AbstractMessageHandler 的所有具体实现。

    public ResponseMessage execute(RequestMessage requestMessage)
            throws MessageHandlerNotFoundException {
    
        if (requestMessage == null) {            
            throw new MessageHandlerNotFoundException(
                    "Request message is null so no message handler could be found.");
        }
    
        MessageHandler messageHandler = EXECUTOR_MAP.get(requestMessage.getMessageTypeIdentifier());
        if (messageHandler == null) {            
            throw new MessageHandlerNotFoundException("No message handler found for message: "
                    + requestMessage.getClass().getName());
        }
    
        ResponseMessage ctepMessageResponse = messageHandler.process(requestMessage);
        return ctepMessageResponse;
    }
    

    【讨论】:

    • 如何从超类调用 operation_first 方法,我们用派生类实例调用 operation_second 方法但是 operation_first 方法在这里如何调用,它如何知道派生类对象引用。
    • 那么你会在派生类上调用 operation_second 方法,这样 operation_second 就会从同一个(派生)类调用 operation_first 方法。
    【解决方案3】:

    假设您需要生成不同类型/结构的文档。

    确实,生成 XML 文件必须运行的算法与生成 CSV 文件、XLSX 文件的算法完全不同......

    在这种情况下,模板方法有两个级别:

    • 第一层是定义生成算法的地方;
    • 第二层是指定要检索的数据的地方。

    你可以试试这个API(有源代码)。

    来源:

    https://mvnrepository.com/artifact/net.sf.automatic-report-generator(此处提供源代码)。

    https://sourceforge.net/projects/automatic-report-generator/

    【讨论】:

      猜你喜欢
      • 2011-05-31
      • 1970-01-01
      • 2022-07-06
      • 1970-01-01
      • 2017-07-18
      • 2017-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多