任何人都可以告诉我一些应该使用模板方法 - 模式的示例情况吗?
根据您自己的经验,给我一些真实的用途。
(到目前为止,我发现它仅适用于在DA层中映射数据。抱歉!!!)
答案 0 :(得分:8)
模板方法模式提供了执行任何类型的算法或操作的框架,它允许子类重新定义逻辑的一部分。
优点:自然适合构建框架,以便父框架类可以回调到子项中实现的方法。
示例:
缺点:将您限制为Java中的单个继承。
答案 1 :(得分:6)
模板方法模式的应用有两个主要特征:
protected
构造函数,可选地声明为abstract
),它将在客户端代码中进行子类化。final
,在Java中);它的API文档必须精确指定它调用哪些基本操作方法,以及何时(即它必须描述“算法”)。表示算法中的一个步骤的原始操作方法应该是非公共的,但是可以覆盖(Java中为protected
),并且可以有两种类型:a)必须>的抽象方法em>在子类中实现; b)具有默认/空实现的方法,可以在子类中重写。 Java 6 SDK中的一个很好的例子是execute()
类的javax.swing.SwingWorker
方法(它是public final void
方法)。在这种情况下,基本操作方法是doInBackground()
,process(List)
和done()
。第一个是抽象的,因此需要在子类中实现;它是由后台线程中的模板方法调用的。其他两个有空实现,可以选择在子类中重写;它们分别在EDT(Swing Event Dispatch Thread)中在处理期间和结束时调用,以允许更新UI。
根据我自己的经验,我有时会使用这种模式。
其中一个例子是实现java.util.Iterator
接口的Java基类,其中next()
是模板方法,并且只有一个原始操作方法负责实例化特定的域实体类(这是为了使用它)在迭代持久域实体对象列表时,使用JDBC)。
在同一个应用程序中的一个更好的例子是基类,其中模板方法实现了一个多步算法,用于从给定的持久实体列表中填充“业务实体维护屏幕”(使用Swing);调用原始操作方法1)清除当前屏幕状态,2)在屏幕内的表视图中添加实体;可选地,如果屏幕是可编辑的,则从模板方法调用其他基本操作。
最后,我必须说,虽然这肯定是一种有用的设计模式,但并不是经常会出现真正适用的情况。简单地让一个基类具有在子类中被覆盖的方法(根据我的经验,更常见的情况)本身并不足以作为该模式的应用程序。
答案 2 :(得分:3)
模板方法中最重要的是你必须将一系列抽象方法定义为步骤或算法,并让子类替换这些方法的具体实现。
我申请了其中一个文件生成程序。
public abstract DocumentGenerator()
{
generateHeader();
generateBody();
generateDetails();
}
public HTMLDocGenerator : DocumentGenerator()
{
public override generateBody()
{
//generate as in html format
}
}
您可以使用不同的实现,例如PDF生成器csv生成器,这里的值是它们符合算法(生成 - >标题,正文,详细信息)。
答案 3 :(得分:2)
当存在具有许多实现的算法时,应该使用模板模式。该算法在基类中的函数中定义,并且实现由基类和子类完成。 http://preciselyconcise.com/design_patterns/templatemethod.php
给出了一个实时示例的详细说明答案 4 :(得分:2)
我试图给你一些真实的例子,以及应该使用模板方法模式的一些常见情况。
当你希望你的程序是“Open For Extension”和“Closed for Modification”时。这意味着可以扩展模块的行为,这样我们就可以随着应用程序的需求发生变化,或者为了满足新应用程序的需要,模块会以新的和不同的方式运行。但是,这样一个模块的源代码是不可侵犯的。不允许任何人对它进行源代码更改。例如,您可以添加新的工资计算方式(例如Remotely类),而无需更改以前的代码。
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();
}
}
如果您通过延迟算法的某些步骤来面对许多相同的代码行。当您实现方法或函数的内容时,您可以找到某些部分的内容。代码从一种类型到另一种类型。这一部分的特点是可以重新定义或修改方法或函数的这些部分,而无需更改算法的(方法或函数)主结构。例如,如果您想在没有此模式的情况下解决此问题,您将面对以下示例:
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;
}
...
}
当您作为框架的设计者时,希望您的客户只需使用作为参数传递给框架的任何可执行代码,这些代码可以回调(执行)该参数。给定时间。此执行可能是在同步回调中立即执行,也可能在稍后的时间发生,如在异步回调中。让我们考虑其中一个着名的。
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
...
}
...
}
答案 5 :(得分:1)
我使用了Business Logic的模板方法,其中许多组件共享相同的过程,但实现略有不同。
答案 6 :(得分:1)
Template方法定义了算法的骨架结构 将某些步骤和细节推迟到子类。结构和 算法的流程保持静态,但步骤的细节是 推迟到子类。
我使用模板方法模式来准备文档内容。有许多不同类型的文档,每种类型都有自己的小修改。但是,文件准备的主要过程对所有人来说都是一样的。
答案 7 :(得分:0)
本文讨论了模板模式的6种常用用法。在ADO.NET时代,我使用模板模式的原因很多,因为我们有固定的序列,如open,executequery和close connection,但是executequery的查询与不同的表格结构。
https://www.codeproject.com/Articles/307452/common-use-of-Template-Design-pattern-Design-pat
以上文章讨论了模板模式的六种常见用法:-