番禺网站开发多少钱,有哪些企业可以做招聘的网站有哪些内容,北京做网站推广一个月多少钱,各网站封面尺寸设计模式之模板方法模式#xff1a;
定义一个操作中的算法的骨架#xff0c;而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
简而言之就是#xff1a;父类定义了骨架#xff08;调用哪些方法及其顺序#xff09;…设计模式之模板方法模式
定义一个操作中的算法的骨架而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
简而言之就是父类定义了骨架调用哪些方法及其顺序某些特定的方法由具体的子类来实现。 所以呢在父类模板方法中是有两类方法的
共同的方法所有子类都必须用到的方法类似于定义了一个框架通常不用abstract而是final来修饰防止子类重写像下面的play方法不同的方法子类需要重写或者覆盖的方法这种方法也分为两种 1). 抽象方法父类是抽象方法子类必须实现的如下面的startGameendGame方法 2). 钩子方法父类中是一个空方法子类继承的时候默认也是空的这个方法有什么用呢子类可以通过这个方法来自定义自己的其他一些步骤和过程从而达到控制父类的目的。
我们将创建一个定义操作的 Game 抽象类其中模板方法设置为 final这样它就不会被重写。BasketballGame和 FootballGame 是扩展了 Game 的实体类它们重写了抽象类的方法。
1. 创建抽象类Game
public abstract class Game {abstract void startGame();abstract void endGame();abstract void init();final void play(){init();startGame();endGame();}
}2. 创建扩展了上述类的实体类
public class FootballGame extends Game {Overridevoid startGame() {System.out.println(start football);}Overridevoid endGame() {System.out.println(end football);}Overridevoid init() {System.out.println(init football);}
}public class BasketballGame extends Game {Overridevoid startGame() {System.out.println(start basketball);}Overridevoid endGame() {System.out.println(end basketball);}Overridevoid init() {System.out.println(init basketball);}
}3. 使用测试类测试
public class TemplMain {public static void main(String[] args) {Game game new FootballGame();//这样如果你想要改变其他球类只需要换成下面这种形式其他不用改变//Game game new BasketballGame();game.play();}
}再升级一下举另一个例子 接口描述的是一种共性一种动作action 抽象类描述的是一个模板一个特定的过程 而子类则是可以根据自己的需要定制自己的过程。
不过这样做的好处又是什么呢
将族群进行隔离像上面的图一样我们可以将不同种类的人美洲人亚洲人进行隔离而不互相影响可以将一些日志和共性的动作很好的分离规范子类的动作。
其实我们在一些框架如springmybatis等都可以看到模板方法模式的影子下面简单举一下例子 像mybatis的Executor接口 你就可以很明显的看到这种模式
spring中的模板方法模式 spring模板方法我来摘抄一些重点给大家看看 下面的代码展示了Spring IOC容器初始化时运用到的模板方法模式。截取部分关键代码 1、首先定义一个接口ConfigurableApplicationContext声明模板方法refresh
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {/**声明了一个模板方法*/void refresh() throws BeansException, IllegalStateException;
}2、抽象类AbstractApplicationContext实现了接口主要实现了模板方法refresh这个方法很重要是各种IOC容器初始化的入口的逻辑:
public abstract class AbstractApplicationContext extends DefaultResourceLoaderimplements ConfigurableApplicationContext, DisposableBean {/**模板方法的具体实现*/public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();//注意这个方法是里面调用了两个抽象方法refreshBeanFactory、getBeanFactory// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory obtainFreshBeanFactory();// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {//注意这个方法是钩子方法,点进去父类看可以发现是空的// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);// Initialize message source for this context.initMessageSource();// Initialize event multicaster for this context.initApplicationEventMulticaster();//注意这个方法是钩子方法// Initialize other special beans in specific context subclasses.onRefresh();// Check for listener beans and register them.registerListeners();// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();}catch (BeansException ex) {// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset active flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}}}
}这里最主要有一个抽象方法obtainFreshBeanFactory、两个钩子方法postProcessBeanFactory和onRefresh看看他们在类中的定义 看看获取Spring容器的抽象方法
/**其实他内部只调用了两个抽象方法**/ protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();ConfigurableListableBeanFactory beanFactory getBeanFactory();if (logger.isDebugEnabled()) {logger.debug(Bean factory for getDisplayName() : beanFactory);}return beanFactory;}//上面两个方法就是下面这两个方法可以看到他们都是抽象方法等待具体的子类去实现protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;3、具体实现的子类实现了抽象方法getBeanFactory的子类有
AbstractRefreshableApplicationContext
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {Overridepublic final ConfigurableListableBeanFactory getBeanFactory() {synchronized (this.beanFactoryMonitor) {if (this.beanFactory null) {throw new IllegalStateException(BeanFactory not initialized or already closed - call refresh before accessing beans via the ApplicationContext);}//这里的this.beanFactory在另一个抽象方法refreshBeanFactory的设置的return this.beanFactory;}}
}GenericApplicationContext:
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {Overridepublic final ConfigurableListableBeanFactory getBeanFactory() {//同样这里的this.beanFactory在另一个抽象方法中设置 return this.beanFactory;}
}大家有空可以自己进去看看里面的源码里面真是高深莫测