我们应该在哪里使用模板方法——模式?

发布于 2024-08-07 16:24:12 字数 103 浏览 7 评论 0原文

谁能告诉我一些应该使用模板方法 - 模式的示例情况?

根据您自己的经验,给我一些实际用途。

(到目前为止,我发现它仅对映射 DA 层中的数据有用。抱歉!!!)

Can anyone let me know some example situations where Template Method - pattern should be used?

Give me some real-world use from your own experience.

(I have so far found it useful only for mapping data in the DA layer. Sorry!!!)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

浸婚纱 2024-08-14 16:24:12

模板方法模式提供了执行任何类型的算法或操作的框架,并且它允许子类重新定义部分逻辑。

优点:自然适合构建框架,以便父框架类可以回调子框架中实现的方法。

示例:

  • java.util.AbstractList
  • Servlet 的 doGet 和 doPost 方法
  • MDB 的 onMessage 方法
  • Struts Action 类
  • Spring 的数据访问类

缺点: 限制您只能使用 Java 中的单个继承。

A Template method pattern provides a skeleton for performing any sort of algorithm or an operation, and it allows the sub-classes to re-define part of the logic.

Pros: Natural fit for building frameworks, so that parent framework classes can make callbacks into methods implemented in child.

Examples:

  • java.util.AbstractList
  • Servlet's doGet and doPost methods
  • MDB's onMessage method
  • Struts Action class
  • Spring's data access classes

Cons: Restricts you to a single inheritance in Java.

夏末 2024-08-14 16:24:12

模板方法模式的应用程序有两个主要特征:

  1. 有一个基类(在 Java 中,一个仅具有受保护的构造函数,并且可以选择声明为抽象) 它将在客户端代码中进行子类化。
  2. 基类中定义了两组方法:a) 一个或多个模板方法(通常只有一个)和一个或多个原始操作 > 方法(通常不止一种)。每个模板方法都代表一个高级操作,在基类本身中根据原始操作实现,这些操作意味着在每个特定子类中实现/重写。通常,模板方法是公共且不可重写的(Java 中的final);它的API文档必须准确指定它调用哪些原始操作方法以及何时调用(即它必须描述“算法”)。表示算法中的一个步骤的原始操作方法应该是非公共的但可重写的(在 Java 中受保护),并且可以有两种类型:a) 抽象方法,必须在子类中实现; b) 具有默认/空实现的方法,可以在子类中重写。

Java 6 SDK 中的一个很好的例子是 javax.swing.SwingWorker 类的 execute() 方法(它是一个 public final void方法)。在本例中,原始操作方法是 doInBackground()process(List)done()。第一个是抽象的,因此需要在子类中实现;它由后台线程中的模板方法调用。另外两个具有空实现,可以选择在子类中重写;它们分别在处理过程中和处理结束时在 EDT(Swing 事件调度线程)中调用,以允许更新 UI。

根据我自己的经验,我有时会使用这种模式。
其中一种情况是实现 java.util.Iterator 接口的 Java 基类,其中 next() 是模板方法,并且只有一个原始操作方法负责实例化特定的域实体类(这意味着在使用 JDBC 迭代持久域实体对象列表时使用)。
同一应用程序中的一个更好的例子是一个基类,其中模板方法实现了一个多步骤算法,旨在从给定的持久实体列表填充“业务实体维护屏幕”(使用 Swing);调用原始操作方法来 1) 清除当前屏幕状态,2) 在屏幕内的表视图中添加实体;如果屏幕可编辑,则可以选择从模板方法调用其他原始操作。

最后,我必须说,虽然这确实是一种有用的设计模式,但真正适用的情况并不常见。仅仅拥有一个带有在子类中重写的方法的基类(根据我的经验,这是一种更常见的情况),其本身不足以成为该模式的应用程序。

An application of the Template Method pattern has two main characteristics:

  1. There is a base class (in Java, one only with protected constructors and optionally declared as abstract) which will be subclassed in client code.
  2. There are two groups of methods defined in the base class: a) one or more template methods (typically only one) and one or more primitive operation methods (typically more than one). Each template method represents a high level operation, implemented in the base class itself in terms of the primitive operations, which are meant to be implemented/overriden in each specific subclass. Normally, the template method is public and non-overridable (final, in Java); its API documentation must specify precisely which primitive operation methods it calls, and when (that is, it must describe the "algorithm"). A primitive operation method, which represents a step in the algorithm, should be non-public but overridable (protected, in Java), and can be of two types: a) an abstract method which must be implemented in the subclass; b) a method with a default/empty implementation which may be overriden in the subclass.

One good example in the Java 6 SDK is the execute() method of the javax.swing.SwingWorker class (it is a public final void method). In this case, the primitive operation methods are doInBackground(), process(List), and done(). The first one is abstract and therefore requires an implementation in the subclass; it's called by the template method in a background thread. The other two have empty implementations and can optionally be overriden in the subclass; they are called during and at the end of processing, respectively, in the EDT (the Swing Event Dispatch Thread), to allow updates to the UI.

In my own experience, I have sometimes used this pattern.
One such case was a Java base class implementing the java.util.Iterator interface, where next() was the template method and there was only one primitive operation method responsible for instantiating a specific domain entity class (this was meant to be used when iterating over a list of persistent domain entity objects, using JDBC).
A better example in that same application was a base class where the template method implemented a multi-step algorithm intended to populate a "business entity maintenance screen" (using Swing) from a given list of persistent entities; primitive operations methods were called to 1) clear the current screen state, and 2) add an entity in a table view inside the screen; optionally, other primitive operations were called from the template method if the screen was editable.

In the end, I must say that although this certainly is a useful design pattern, not so often a situation comes up where it really is applicable. Simply having a base class with methods that get overriden in a subclass (a much more common situation, in my experience) is not enough, by itself, to qualify as an application of the pattern.

不语却知心 2024-08-14 16:24:12

我试图为您提供一些现实世界的示例,以及一些应使用模板方法模式的常见情况。

  • 当你希望你的程序“开放进行扩展”并且“关闭进行修改”时。这意味着模块的行为可以扩展,这样我们就可以让模块的行为在随着应用程序的要求发生变化,或者为了满足新应用程序的需要,任何人都不允许对其进行源代码更改。可以在不改变之前代码的情况下添加新的薪资计算方式(如Remotely class)。

    公共抽象类薪资{
    
       公共最终无效计算(){
            System.out.println("第一个共享任务完成。");
            获取基本工资();
            System.out.println("第二个共享任务完成。");
       }
    
       公共抽象无效 getBaseSalary();
    
    }
    
    公共课每小时延长工资{
    
        @覆盖
        公共无效 getBaseSalary() {
            System.out.println("特殊任务完成。");
        }
    
    }
    
    公开课测试{
    
        公共静态无效主(字符串[] args){
            工资工资=....
            工资.calculate();
        }
    }
    
  • 当您通过推迟算法的某些步骤来面对许多重复的相同代码行时。 当您实现方法或函数的内容时,您会发现代码的某些部分从一种类型到另一种类型有所不同,这些部分的特点是可以重新定义或修改方法或函数的这些部分。不改变算法(方法或函数)的主要结构。例如,如果您想在没有这种模式的情况下解决此问题,您将面临以下示例:

function0: function1: ... functionN:

1       1               1
2       2               2
...     ...             ...
5       6               n
3       3               3
4       4               4
...     ...             ...

如您所见,部分代码 5, 6, n 因一个函数而异,而另一个函数则有所不同,但是您共享了重复的部分,例如 1、2、3、4。让我们考虑使用著名的 java 库之一的解决方案。

public abstract class InputStream implements Closeable {

    public abstract int read() throws IOException;

    public int read(byte b[], int off, int len) throws IOException {
        ....

        int c = read();
        ....
    }

    ....

}

public class ByteArrayInputStream extends InputStream {  

    ...

    public synchronized int read() {
        return (pos < count) ? (buf[pos++] & 0xff) : -1;
        }
    ...
}
  • 当您作为框架的设计者时,希望您的客户端仅使用作为参数传递给框架的任何可执行代码,该代码预计会在给定时间回调(执行)该参数 此执行可能是立即执行(如在同步回调中​​),也可能稍后发生(如在异步回调中)。让我们考虑一下著名的之一。

    公共抽象类 HttpServlet 扩展 GenericServlet 
        实现 java.io.Serialized {
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
            ...
        }
    
    protected void 服务(HttpServletRequest req、HttpServletResponse resp)
        抛出 ServletException、IOException {
            ....
            doGet(req, resp);
            ...
        }
        ...
    }
    }
    
    公共类 MyServlet 扩展 HttpServlet {
    
        protected void doGet(HttpServletRequest 请求,HttpServletResponse 响应)
            抛出 ServletException、IOException {
    
                //做某事
            ...
        }
        ...
    }
    

I tried to give you some real-world examples, and some common situations where Template Method pattern should be used.

  • When you want your program be "Open For Extension” and also “Closed for Modification”. This means that the behavior of the module can be extended, such that we can make the module behave in new and different ways as the requirements of the application change, or to meet the needs of new applications. However, The source code of such a module is inviolate. No one is allowed to make source code changes to it. In following example, you can add new manner of salary calculation (such as Remotely class) without changing the previous codes.

    public abstract class Salary {
    
       public final void calculate() {
            System.out.println("First shared tasks is done.");
            getBaseSalary();
            System.out.println("Second shared tasks is done.");
       }
    
       public abstract void getBaseSalary();
    
    }
    
    public class Hourly extends Salary {
    
        @Override
        public void getBaseSalary() {
            System.out.println("Special Task is done.");
        }
    
    }
    
    public class Test {
    
        public static void main(String[] args) {
            Salary salary = ....
            salary.calculate();
        }
    }
    
  • When you face many same line of codes that are duplicated through deferring just some steps of your algorithm. When you are implementing content of a method or function you can find some section of your code that vary from one type to another type. The feature of this sections are that one can redefine or modify these sections of an method or function without changing the algorithm's (method or function) main structure. For example if you want to solve this problem without this pattern you will face this sample:

function0: function1: ... functionN:

1       1               1
2       2               2
...     ...             ...
5       6               n
3       3               3
4       4               4
...     ...             ...

As you can see, section cods 5, 6, n are different vary from one function to another function, however you have shared sections such as 1,2,3,4 that are duplicated. Lets consider a solution with one of famous java libraries.

public abstract class InputStream implements Closeable {

    public abstract int read() throws IOException;

    public int read(byte b[], int off, int len) throws IOException {
        ....

        int c = read();
        ....
    }

    ....

}

public class ByteArrayInputStream extends InputStream {  

    ...

    public synchronized int read() {
        return (pos < count) ? (buf[pos++] & 0xff) : -1;
        }
    ...
}
  • When you as a designer of a framework, want that your clients just to use any executable code that is passed as an argument to your framework, which is expected to call back (execute) that argument at a given time. This execution may be immediate as in a synchronous callback, or it might happen at a later time as in an asynchronous callback. Lets consider one of famous ones.

    public abstract class HttpServlet extends GenericServlet 
        implements java.io.Serializable  {
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
            ...
        }
    
    protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
            ....
            doGet(req, resp);
            ...
        }
        ...
    }
    }
    
    public class MyServlet extends HttpServlet {
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
    
                //do something
            ...
        }
        ...
    }
    
沉默的熊 2024-08-14 16:24:12

模板方法中最重要的是你必须定义一系列抽象方法作为步骤或算法,并让子类替换这些方法的具体实现。

我应用了其中一个文档生成程序。

public abstract DocumentGenerator() 
{
   generateHeader();
   generateBody();
   generateDetails();
}
public HTMLDocGenerator : DocumentGenerator()
{
   public override generateBody()
   {
     //generate as in html format
   }
}

您可以有不同的实现,例如 PDF 生成器 csv 生成器,这里的值是它们符合算法(生成 -> 标题、正文、详细信息)。

The most important thing in template method is that you have to define a series of abstract methods as steps or an algorithm and let the sub class substitute with the concrete implementation for those methods.

I applied in one of the document generation program.

public abstract DocumentGenerator() 
{
   generateHeader();
   generateBody();
   generateDetails();
}
public HTMLDocGenerator : DocumentGenerator()
{
   public override generateBody()
   {
     //generate as in html format
   }
}

You can have different implementation like PDF generator csv generator and the value here is they comform to the algorithm (generate -> header, body, details).

窗影残 2024-08-14 16:24:12

当存在具有多种实现的算法时,应使用模板模式。该算法在基类的函数中定义,并由基类和子类完成实现。 http://preciselyconcise.com/design_patterns/templatemethod.php 中给出了实时示例的详细说明

A template pattern should be used when there is an algorithm with many implementations. The algorithm is defined in a function in base class and implementation is done by the base class and subclasses. A detailed explanation with a real-time example is given in http://preciselyconcise.com/design_patterns/templatemethod.php

菊凝晚露 2024-08-14 16:24:12

我将描绘一个真实世界的示例,其中我使用了一些模板方法。

在 C++ 计算机视觉算法应用程序中,算法的行为被设计为根据运行时读取的一些选项(根据启动时加载的配置文件中的枚举)假设多种算法行为。算法的整体框架是相同的,除了一些关键回调填充在代码的中间,否则这些代码将被粗暴地复制只是为了调用该级别的不同函数。我想要使​​用的这些回调被抽象到模板方法基类中,并且模板方法模式防止了所有代码重复。我们使用的枚举基本上决定了我实例化基类指针所指向的子类,从而为算法提供了与其相关的行为风格。

现在,这种不同风格的运行算法背后的一些动机是控制我们仪器的软件的在线与离线功能。离线风格带来了更丰富的调试/诊断输出,并保留了某些图像像素的局部坐标系,而在线风格则将事物保留在绝对坐标空间中,并保持了特定于正在运行的仪器及其所有机器人技术等的关注点。另一个枚举驱动了我们用于某些机器学习的一组分类器的选择,因为不同的分类器是在不同的数据集下进行训练的,否则这些数据集在代码主体中的流动相同,但需要根据一些管理条件进行不同的解释该数据已创建。

我相信我的这种用例源自所谓的 中间有洞问题。

I'll sketch one real world example where I utilized some template methods.

In a C++ computer vision algorithm application the behavior of the algorithm was designed to assume a couple of flavors of algorithm behavior based upon some options read at run time according to an enum tucked into a config file loaded at startup. The overall skeleton of the algorithm was identical except for some key callbacks stuffed in the middle of what would otherwise be an identical section of code that would be brutally duplicated just to call different functions at that level. These callbacks I wanted to use were abstracted into the template method base class and the template method pattern prevented all that code duplication. The enum we used basically dictated what subclass I instantiated my base class pointer to point to and thus lend the algorithm its associated bit of flavor in behavior.

Now some of the motivations behind this variety of flavors of the running algorithm was an online vs offline functionality of software that controlled our instrument. The offline flavor pulled with it richer debug/diagnostic output and kept a coordinate system local to some image pixels while the online flavor kept things in an absolute coordinate space and maintained concerns specific to the running instrument with all its robotics and what not. Another enum drove a selection among a set of classifiers we used for some machine learning as well since different classifiers were trained under different sets of data that otherwise flowed identically through the body of code but needed to be interpreted differently based on some governing conditions for how that data was created.

I believe this sort of use case I had arose from what has been called the hole in the middle problem.

万劫不复 2024-08-14 16:24:12

我使用了业务逻辑的模板方法,其中许多组件共享相同的流程,但实现略有不同。

I have used the template method for Business Logic where a number of components shared the same process but the implementation was slightly different.

穿透光 2024-08-14 16:24:12

模板方法定义了算法的骨架结构,但是
将某些步骤和细节推迟到子类。结构和
算法的流程保持静态,但步骤的细节是
推迟到子类。

我使用模板方法模式来准备文档内容。有许多不同类型的文档,每种类型都有自己的小修改。然而,文件准备的主要过程对于所有人来说都是相同的。

The Template method defines the skeleton structure of an algorithm but
defers certain steps and details to subclasses. The structure and the
flow of the algorithm remain static, but the details of the steps are
deferred to subclasses.

I used Template Method Pattern to prepare document content. There were many different kinds of document that each type has its own small modifications. However, the main process of document preparation was same for all.

留蓝 2024-08-14 16:24:12

本文讨论了模板模式的 6 种常见用法。在 ADO.NET 时代,我经常使用模板模式,因为我们有固定的顺序,如打开、执行查询和关闭连接,但执行查询会根据不同的表结构有不同的查询。

https://www.codeproject。 com/Articles/307452/common-use-of-Template-Design-pattern-Design-pat

以上文章讨论了模板模式的六种常见用法:-

  1. 灵活的可扩展通用专用用户界面
  2. ASP.NET 页面生命周期
  3. 代码生成器
  4. XML 解析器
  5. 业务组件中的验证
  6. 可定制的日志记录实用程序

This article talks about 6 common uses of Template pattern.In the era of ADO.NET i had used template pattern a lot as we had fixed sequence like open , executequery and close connection , but the executequery would have queries different as per different table structure.

https://www.codeproject.com/Articles/307452/common-use-of-Template-Design-pattern-Design-pat

Above articles talks about six common uses of template pattern :-

  1. Flexible extendable generalized specialized user interfaces
  2. ASP.NET page life cycle
  3. Code generators
  4. XML parser
  5. Validation in business components
  6. Customizable logging utility
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文