面试官:聊一下你项目中的设计模式吧。

这个问题我做面试官的时候也经常喜欢问,考察一下候选人的代码能力和设计思维,在我校招的年代,一般来说面试官只是问一问说出几种常见的设计模式八股文就算过关了。就像当时我面试最怕别人问我说一下你项目中用到了哪些设计模式,一问一个不吱声,根本说不出来。。。。因为我都是背的概念,哪知道代码里面怎么实现的。

Java内卷到现在的已经并不是背背八股文就可以的时代了,不光要问你概念是啥,还要问你代码里怎么用的,为什么这么用,解决了什么问题。这时候如果你只回答出Spring中的那两个设计模式,beanFactory工厂设计模式aop代理模式。这俩显然大家都能答出来,那为什么面试官选择你而不选择其他人呢。

今天给大家介绍一种设计模式,学会之后让你平滑的吹到自己的经历上。

模版设计模式与钩子函数

什么是模版设计模式和钩子函数,允许子类对父类的一个或多个步骤进行重写 。用父类实现通用的逻辑,由子类实现不同的交互逻辑。举个例子,看过Spring源码的同学或者熟读背诵Spring八股文的肯定都对Refresh方法不陌生

scss 复制代码
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			// Prepare this context for refreshing.
			prepareRefresh();

			// 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);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				// 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) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

这个方法是SpringBean生命周期里最重要的一环,包含了加载bean的各种前置器、后置器以及完成beanDefinition的加载。这块的八股没背熟的可以再背一背。

我们这里只是借助refersh来抛砖引玉一下,refresh方法是在Spring启动时调用,单单分析这个方法,refersh方法只是定义了一个bean加载的流程。具体的实现方法由子类去实现。也就是相当于这里定义了一个模板方法+钩子函数。

代码应用

应用在我们的代码设计中如何实现呢,假设要你设计一套数据流转系统,功能是负责异构数据源之间的稳定同步,比如每天定时从爬虫组的MySQL1库中同步到数仓组的MySQL2库中做清洗计算。

那么任务执行如何去定义?首先一个任务我们首先可以想到的是两种状态,任务开始、任务结束,那么先定义出两个方法

  1. begin();
  2. end();

这样我们可以通过调用begin来开始任务,调用end来结束任务,任务不是空手得来的吧,在begin之前是不是要做一些前置操作,获取任务详情之类的。所以增加一个beforeExec();那么结束之后是不是要对任务做一下结果判断,再加一个afterExec()。

  1. begin();
  2. end();
  3. beforeExec();
  4. afterExec();

那么任务进行中耗费了太多资源了,想取消终端掉是不是也要有个方法呢。再加一个cancel()。

  1. begin();
  2. end();
  3. beforeExec();
  4. afterExec();
  5. cancel();

这样一个任务的生命周期钩子函数就定义好了,熟悉vue的可能不陌生,vue里的生命周期函数跟这个差不多意思。定义好了钩子函数再定义好模板方法。

所谓模版方法就是在一定义好一套流程,我在父类的一个方法中把任务触发的流程指定好,具体怎么执行让子类去具体实现。

scss 复制代码
public abstract class JobAction {
	
	public void execute() {
	  // 获取任务详情
	  Job job = beforeExec();
	  while (// 监控任务状态) {
	  		try {
			  // 开始任务
				begin(job);
	  		} catch(Exception e) {
			  // 任务触发后钩子
	  			afterExec(job);
	  		}
	  		if (// 取消任务) {
				cancel(job);
	  		}
	  }
	  // 任务结束
	  end();
	}
}

具体的实现逻辑由子类去具体实现。完整的项目代码在Gitee:

<math xmlns="http://www.w3.org/1998/Math/MathML"> h t t p s : / / g i t e e . c o m / a t u p t o w n / d a t a l i n k x https://gitee.com/atuptown/datalinkx </math> https://gitee.com/atuptown/datalinkx

这是作者搬了近四年砖头积累的下来的经验开源的项目,基于flink的异构数据源流转服务,过一遍代码绝对不会让你失望。拯救简历上只有商城、外卖的JavaBoy!

相关推荐
睡觉谁叫~~~38 分钟前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
捕鲸叉2 小时前
MVC(Model-View-Controller)模式概述
开发语言·c++·设计模式
wrx繁星点点2 小时前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式
凉辰2 小时前
设计模式 策略模式 场景Vue (技术提升)
vue.js·设计模式·策略模式
菜菜-plus3 小时前
java设计模式之策略模式
java·设计模式·策略模式
暗黑起源喵3 小时前
设计模式-迭代器
设计模式
2401_865854883 小时前
iOS应用想要下载到手机上只能苹果签名吗?
后端·ios·iphone
AskHarries3 小时前
Spring Boot集成Access DB实现数据导入和解析
java·spring boot·后端
2401_857622663 小时前
SpringBoot健身房管理:敏捷与自动化
spring boot·后端·自动化
程序员阿龙3 小时前
基于SpringBoot的医疗陪护系统设计与实现(源码+定制+开发)
java·spring boot·后端·医疗陪护管理平台·患者护理服务平台·医疗信息管理系统·患者陪护服务平台