模式介绍
模板模式也是很常见的一种模式, 尤其是在框架中使用;
在模板类中, 实现功能的通用完整流程, 然后把一些特殊的定制化功能放到子类中; 父类+具体的子类, 就是一个具体的完整实现;
这样可以把公共代码抽取到父类, 可以减少代码的冗余; 其次, 整个功能集的实现从整体上比较统一, 把不同的部分放到相应的子类中实现, 每个子类的实现过程类似于填空, 通过用类来对实现进行区分, 便于管理, 理解, 扩展
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public abstract class AbstractBiz {
/**
* 完整的业务的逻辑
*/
public void completeBiz() {
// step1
// common logic
specialBiz();
// stepX
}
public abstract void specialBiz();
}
1
2
3
4
5
6
7
8
9
public class ConcreteBiz extends AbstractBiz {
/**
* 每个具体的业务类里实现自己特殊的业务逻辑
*/
public void specialBiz() {
}
}
典型应用
- JDK集合框架里有很Abstract*的例子, 在此
AbstractQueue
为例说明下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
public E remove() {
E x = poll();
if (x != null)
return x;
else
throw new NoSuchElementException();
}
可以看到add
与remove
方法的实现都是基于更原子的方法offer
与poll
offer
与poll
的实现则跟具体的子类相关, 而add
与remove
可以做到与子类无关, 所以抽象到父类里
这里可能更多体现的是多个小方法组合来完成更高级的功能
- AbstractQueuedSynchronizer
整个Java并发包的基石AQS, ReentrantLock, Semaphore, CountDownLatch, ThreadPoolExecutor这些重要的并发类都是基于AQS实现
其中acquire
方法就是获取共享资源的
1
2
3
4
5
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
tryAcquire
是接口方法, 由各自子类实现, 标准的模板模式实现