设计模式之模板模式
一:概念
模板设计模式主要是可以在父类中定义逻辑的骨架流程,预留钩子方法,具体的实现由子类完成,优点是能够把公共
部分抽象到父类中,如果后续需要增加新的子类实现,直接继承即可。
二:示例
定义一个接口类IDailyService,为描述人一天的生活
public interface IDailyService { void start(); }
这个抽象父类实现了接口类中start方法,并且定义了一天中的生活流程,
吃饭、坐车、工作。其中吃饭是所有人共同的行为,坐车和工作没有具体实现,交给子类实现。
public abstract class AbstractDailyService implements IDailyService{ @Override public void start(){ eat(); transfer(); work(); } // 共同的方法,吃饭 public void eat(){ System.out.println("吃饭....."); } // 乘坐交通工具,每个方式不一样 protected abstract void transfer(); // 每个人工作种类也不一样 protected abstract void work(); }
BossDaily类:
老板会开车上班,工作行为为喝茶看报纸
public class BossDaily extends AbstractDailyService{ @Override protected void transfer() { System.out.println("开车去上班......"); } @Override protected void work() { System.out.println("喝茶看报纸......"); } }
WorkerDaily类:
工人坐公交去上班,工作行为是搬砖
public class WorkerDaily extends AbstractDailyService{ @Override protected void transfer() { System.out.println("坐公交去上班......"); } @Override protected void work() { System.out.println("开始搬砖......"); } }
测试类:
public class TestDaily { public static void main(String[] args) { IDailyService service = new WorkerDaily(); service.start(); System.out.println("-------------------"); service = new BossDaily(); service.start(); } }
这就是一个模板策略的简单应用,模板策略在spring框架中用的比较多,比如:
protected void doRegisterBeanDefinitions(Element root) { BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(getReaderContext(), root, parent); if (this.delegate.isDefaultNamespace(root)) { String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); // We cannot use Profiles.of(...) since profile expressions are not supported // in XML config. See SPR-12458 for details. if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (logger.isDebugEnabled()) { logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } } // 这里有两个钩子方法,典型的模板设计,由子类去实现 preProcessXml(root); // 具体的解析document对象,注册beanDefinition的逻辑在这里实现 parseBeanDefinitions(root, this.delegate); postProcessXml(root); this.delegate = parent; }
在解析document的root节点的前后都预留两个方法,如果子类有个性化需求,就可以在这里实现。
优点就是方便后期的灵活扩展。