模板方法模式仅仅使用了Java的继承机制,但它是一个应用非常广泛的模式。
它定义一个操作中的算法的框架,而将一些步骤延迟到了子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些步骤。简单点来说,就是,在父类定义一个抽象方法,然后不同的子类实现不同的业务逻辑。
// 公共接口
public interface DoService {
void doSomething();
}
// 公共接口实现类,模板方法定义在其中
public abstract class DoServiceImpl implements DoService {
@Override
public void doSomething() {
System.out.println("所有Demo公共逻辑---1-------");
// 各个demo不同逻辑
doSomethingDemo();
System.out.println("所有Demo公共逻辑---2-------");
}
// 模板方法
abstract void doSomethingDemo();
}
// 具体的业务实现类
@Service("doServiceDemoA")
public class DoServiceDemoA extends DoServiceImpl {
@Override
void doSomethingDemo() {
System.out.println("我是doServiceDemoA的业务代码几百行");
}
}
@Service("doServiceDemoB")
public class DoServiceDemoB extends DoServiceImpl {
@Override
void doSomethingDemo() {
System.out.println("我是DoServiceDemoB的业务代码几百行");
}
}
//测试
@Controller
public class Test {
/**
* @Autowired 结合Map使用
* Spring会扫描DoService的所有实现类
* key为DoService实现类的beanName,value为具体实现类的实例;
* 获取DoService具体实现类也可以使用Spring上下文工具类去获取
*/
@Autowired
private Map<String, DoService> doServiceMap;
private static Map<String, String> demoMap = new HashMap<String, String>();
static {
demoMap.put("A", "doServiceDemoA");
demoMap.put("B", "doServiceDemoB");
}
@RequestMapping(value ="/test/doSomethingByDemo/{demoParam}",method = RequestMethod.GET)
public void doSomethingByDemo(@PathVariable("demoParam") String demoParam){
// 入参demoParam决定了具体走哪个demo的业务逻辑;demoParam 值为A或B,其他情况不考虑
DoService doService = doServiceMap.get(demoMap.get(demoParam));
doService.doSomething();
}
}
AQS代码内部提供了一系列模板方法:
tryAcquire(int):
独占方式获取锁。成功则返回true,失败则返回false。tryRelease(int):
独占方式释放锁。成功则返回true,失败则返回false。
像ReentrantLock就是实现了自定义的tryAcquire-tryRelease,从而操作state的值来实现同步效果。
JdbcTemplate ,RedisTemplate 都是使用的模板方法设计模式