设计模式是面向问题、场景而总结产生的设计思路。是解决问题的套路。23 种经典的设计模式。它们又可以分为三大类:创建型、结构型、行为型。
行为型 包含了 观察者模式、模板模式、策略模式、职责链模式、状态模式、迭代器模式、 访问者模式、备忘录模式、命令模式、解释器模式、中介模式 总共11种模式。
模板模式
模板模式(Template Design Pattern) 定义了算法骨架,具体的功能步骤的实现由子类完成。
1. Java库中模板模式的应用:
- Servlet
子类在继承HttpServlet时,只需要重写doGet()和doPost()方法,由父类的service方法来调用。
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
} catch (IllegalArgumentException iae) {
// Invalid date header - proceed as if none was set
ifModifiedSince = -1;
}
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
- Junit
子类只需要实现runTest();方法即可,由父类的模板方法确定整体的流程,先进行setUp();再运行runTest();最后tearDown();。
public void runBare()throws Throwable {
Throwable exception = null;
setUp();
try {
runTest();
} catch (Throwable running) {
exception = running;
} finally {
try {
tearDown();
} catch (Throwable tearingDown) {
if (exception == null)
exception = tearingDown;
}
}
if (exception == null) return;
throw exception;
}
- InputStream
InputStream的read方法,交由子类去实现。
public abstract int read() throws IOException;
在模板方法里,进行调用。
public int read(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || len < 0 || len > b.length - off) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
//看这里
int c = read();
if (c == -1) {
return -1;
}
b[off] = (byte)c;
int i = 1;
try {
for (; i < len ; i++) {
c = read();
if (c == -1) {
break;
}
b[off + i] = (byte)c;
}
} catch (IOException ee) {
}
return i;
}
- AbstractList
在AbstractList方法里,提供了add方法,必须由子类完成,否则报错。子类完成重写后,由模板方法调用。
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
public boolean add(E e) {
add(size(), e);
return true;
}
2.自己实现的模板模式
2.1 TemplateClass定义抽象方法和模板方法
public abstract class TemplateClass {
public abstract void open();
public abstract void put();
public abstract void close();
public final void execute(){
open();
put();
close();
}
}
2.2 子类重写抽象方法
public class ConcreteClass1 extends TemplateClass{
@Override
public void open() {
System.out.println("打开冰箱门");
}
@Override
public void put() {
System.out.println("把大象放进去");
}
@Override
public void close() {
System.out.println("关上冰箱门");
}
}
public class ConcreteClass2 extends TemplateClass{
@Override
public void open() {
System.out.println("打开柜子门");
}
@Override
public void put() {
System.out.println("把大象放进去");
}
@Override
public void close() {
System.out.println("关上柜子门");
}
}
2.3 Main调用
public class Main {
public static void main(String[] args) {
TemplateClass tpc = new ConcreteClass1();
tpc.execute();
}
}
执行结果:
打开冰箱门
把大象放进去
关上冰箱门
总结
模板模式(Template Design Pattern) 定义了算法骨架,具体的功能步骤的实现由子类完成。
注意模板方法需要定义为final类型,防止子类覆写。如果不设置为final类型,则需要像AbstractList类一样,抛出异常。
模板方法实现了流程复用、功能扩展。通过提供一个小型的框架实现了较大的灵活性。
设计模式系列在github上有一个开源项目,主要是本系列博客的demo代码。https://github.com/forestnlp/designpattern
如果您对软件开发、机器学习、深度学习有兴趣请关注本博客,将持续推出Java、软件架构、深度学习相关专栏。
您的支持是对我最大的鼓励。
1078



被折叠的 条评论
为什么被折叠?



