当前位置: 首页 > news >正文

四川省城乡住房和建设厅网站建站工具箱

四川省城乡住房和建设厅网站,建站工具箱,搜索seo优化托管,电子项目外包平台文章目录 一、定义#xff1a;观察者模式二、模拟场景#xff1a;观察者模式2.1 观察者模式2.2 引入依赖2.3 工程结构2.4 模拟摇号2.4.1 摇号服务接口2.4.2 摇号返回结果类 三、违背方案#xff1a;观察者模式3.0 引入依赖3.1 工程结构3.2 添加摇号接口和实现3.2.1 摇号服务… 文章目录 一、定义观察者模式二、模拟场景观察者模式2.1 观察者模式2.2 引入依赖2.3 工程结构2.4 模拟摇号2.4.1 摇号服务接口2.4.2 摇号返回结果类 三、违背方案观察者模式3.0 引入依赖3.1 工程结构3.2 添加摇号接口和实现3.2.1 摇号服务接口3.2.2 摇号服务接口实现类 3.3 单元测试 四、改善代码观察者模式4.0 引入依赖4.1 工程结构4.2 观察者模式结构图4.3 添加事件监听和管理器4.3.1 定义事件监听接口4.3.2 短信息事件监听接口实现4.3.3 MQ发送事件监听接口实现4.3.4 事件处理器 4.4 摇号抽象类及其实现4.4.1 业务抽象类4.4.2 业务接口实现类 4.5 单元测试 五、总结观察者模式 一、定义观察者模式 **观察者模式**当一个行为发生时传递信息给另外一个用户接收做出相应的处理两者之间没有直接的耦合关联。除了生活中的场景外在我们编程开发中也会常用到一些观察者的模式或者组件。例如 经常使用的 MQ 服务虽然 MQ 服务是有一个通知中心并不是每一个类服务进行通知但整体上也可以算作是观察者模式的思路设计。类似事件监听总线让主线服务与其他辅线业务分离为了使系统降低耦合和增强扩展性也会使用观察者模式进行处理。 二、模拟场景观察者模式 2.1 观察者模式 模拟每次小客车指标摇号事件通知场景可能大部分人看到这个案例一定会想到自己每次摇号都不中的场景收到一个遗憾的短信通知。当然目前的摇号系统不会给你发短信而是由百度或者一些其他插件发的短信。那么假如这个类似的摇号功能由你来开发并且需要对外部的用户做一些事件通知以及需要在主流外再添加一些额外的辅助流程时该如何处理呢 基本很多人对于这样的通知事件类的实现往往比较粗犷直接在类里面添加就可以了。 ①考虑这可能不会怎么扩展②是压根就没考虑过扩展。 但如果你有仔细思考过你的核心类功能会发现这里面有一些核心主链路还有一部分是辅助功能。 比如完成了某个行为后需要触发 MQ 给外部以及做一些消息 PUSH 给用户等。这些都不算做是核心流程链路是可以通过事件通知的方式进行处理。 2.2 引入依赖 pom.xml dependenciesdependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.12/versionscopetest/scope/dependency!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --dependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion1.2.62/version/dependency!-- LOGGING begin --dependencygroupIdorg.slf4j/groupIdartifactIdslf4j-api/artifactIdversion1.7.5/version/dependencydependencygroupIdorg.slf4j/groupIdartifactIdjcl-over-slf4j/artifactIdversion1.7.5/version/dependencydependencygroupIdch.qos.logback/groupIdartifactIdlogback-classic/artifactIdversion1.0.9/versionexclusionsexclusionartifactIdslf4j-api/artifactIdgroupIdorg.slf4j/groupId/exclusion/exclusions/dependency /dependencies2.3 工程结构 design-19.0-0 |——src|——main|--java|--com.lino.design|-LotteryResult.java|-MinibusTargetService.java2.4 模拟摇号 2.4.1 摇号服务接口 MinibusTargetService.java package com.lino.design;/*** description: 小客车指标调控服务*/ public class MinibusTargetService {/*** 模拟摇号** param uId 用户编号* return 结果*/public String lottery(String uId) {return Math.abs(uId.hashCode()) % 2 0 ?恭喜你编码.concat(uId).concat(在本次摇号中签): 很遗憾编码.concat(uId).concat(在本次摇号未中签或摇号资格已过期);} }2.4.2 摇号返回结果类 LotteryResult.java package com.lino.design;import java.util.Date;/*** description: 摇号结果类*/ public class LotteryResult {/*** 用户ID*/private String uId;/*** 摇号信息*/private String msg;/*** 业务时间*/private Date dateTime;public LotteryResult(String uId, String msg, Date dateTime) {this.uId uId;this.msg msg;this.dateTime dateTime;}public String getuId() {return uId;}public void setuId(String uId) {this.uId uId;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg msg;}public Date getDateTime() {return dateTime;}public void setDateTime(Date dateTime) {this.dateTime dateTime;} }三、违背方案观察者模式 按照需求需要在原有的摇号接口中添加 MQ 消息发送以及短信息通知功能。 如果是最直接的方式那么可以直接在方法中补充功能即可。 3.0 引入依赖 dependenciesdependencygroupIdcom.lino/groupIdartifactIddesign-19.0-0/artifactIdversion1.0-SNAPSHOT/version/dependency /dependencies3.1 工程结构 design-19.0-1 |——src|——main|--java|--com.lino.design|-LotteryService.java|-LotteryServiceImpl.java|--test|--com.lino.design.test|-ApiTest.java3.2 添加摇号接口和实现 3.2.1 摇号服务接口 LotteryService.java package com.lino.design;/*** description: 摇号接口*/ public interface LotteryService {/*** 摇号** param uId 用户编号* return 摇号结果*/LotteryResult doDraw(String uId); }3.2.2 摇号服务接口实现类 LotteryServiceImpl.java package com.lino.design;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date;/*** description: 摇号接口实现类*/ public class LotteryServiceImpl implements LotteryService {private Logger logger LoggerFactory.getLogger(LotteryServiceImpl.class);private MinibusTargetService minibusTargetService new MinibusTargetService();Overridepublic LotteryResult doDraw(String uId) {// 摇号String lottery minibusTargetService.lottery(uId);// 发短信logger.info(给用户 {} 发送短信通知(短信){}, uId, lottery);// 发MQ信息logger.info(记录用户 {} 摇号结果(MQ){}, uId, lottery);return new LotteryResult(uId, lottery, new Date());} }从上面的方法实现中可以看到整体过程包括三部分摇号、发短信、发 MQ 消息而这部分都是顺序调用的。除了 摇号 接口调用外后面的两部分都是非核心主链路功能而且会随着后续的业务需求发展而不断的调整和扩充在这样的开发方式下就非常不利于维护。 3.3 单元测试 ApiTest.java package com.lino.design.test;import com.alibaba.fastjson.JSON; import com.lino.design.LotteryResult; import com.lino.design.LotteryService; import com.lino.design.LotteryServiceImpl; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory;/*** description: 单元测试*/ public class ApiTest {private Logger logger LoggerFactory.getLogger(ApiTest.class);Testpublic void test() {LotteryService lotteryService new LotteryServiceImpl();LotteryResult result lotteryService.doDraw(2765789109876);logger.info(测试结果{}, JSON.toJSONString(result));} }测试过程中提供对摇号服务接口的调用 测试结果 17:06:14.931 [main] INFO com.lino.design.LotteryServiceImpl - 给用户 2765789109876 发送短信通知(短信)很遗憾编码2765789109876在本次摇号未中签或摇号资格已过期 17:06:14.931 [main] INFO com.lino.design.LotteryServiceImpl - 记录用户 2765789109876 摇号结果(MQ)很遗憾编码2765789109876在本次摇号未中签或摇号资格已过期 17:06:15.122 [main] INFO com.lino.design.test.ApiTest - 测试结果{dateTime:1675760774946,msg:很遗憾编码2765789109876在本次摇号未中签或摇号资格已过期,uId:2765789109876}四、改善代码观察者模式 4.0 引入依赖 dependenciesdependencygroupIdcom.lino/groupIdartifactIddesign-19.0-0/artifactIdversion1.0-SNAPSHOT/version/dependency /dependencies4.1 工程结构 design-19.0-2 |——src|——main|--java|--com.lino.design|--event| |--listener| | |--EventListener.java| | |--MessageEventListener.java| | |--MQEventListener.java| |--EventManager.java|-LotteryService.java|-LotteryServiceImpl.java|--test|--com.lino.design.test|-ApiTest.java4.2 观察者模式结构图 从上图可以分为三大块事件监听、事件处理、具体的业务流程。 另外在业务流程中 LotteryService 定义的是抽象类因为这样可以通过抽象类将事件功能屏蔽外部业务流程开发者不需要知道具体的通知操作。 右下角圆圈图表示的是核心流程与非核心流程的结构。 一般在开发中会把主线流程开发完成后再使用通知的方式处理辅助流程。他们可以是异步的在 MQ 以及定时任务的处理下保证最终一致性。 4.3 添加事件监听和管理器 4.3.1 定义事件监听接口 EventListener.java package com.lino.design.event.listener;import com.lino.design.LotteryResult;/*** description: 事件监听接口*/ public interface EventListener {/*** 监听事件** param result 摇号结果*/void doEvent(LotteryResult result); }接口定义了基本的事件类这里如果方法的入参信息类型是变化的可以使用泛型 T 。 4.3.2 短信息事件监听接口实现 MessageEventListener.java package com.lino.design.event.listener;import com.lino.design.LotteryResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory;/*** description: 短消息事件监听实现*/ public class MessageEventListener implements EventListener {private Logger logger LoggerFactory.getLogger(MessageEventListener.class);Overridepublic void doEvent(LotteryResult result) {logger.info(给用户 {} 发送短信通知(短信){}, result.getuId(), result.getMsg());} }4.3.3 MQ发送事件监听接口实现 MQEventListener.java package com.lino.design.event.listener;import com.lino.design.LotteryResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory;/*** description: MQ事件监听实现*/ public class MQEventListener implements EventListener {private Logger logger LoggerFactory.getLogger(MQEventListener.class);Overridepublic void doEvent(LotteryResult result) {logger.info(记录用户 {} 摇号结果(MQ){}, result.getuId(), result.getMsg());} }4.3.4 事件处理器 EventManager.java package com.lino.design.event;import com.lino.design.LotteryResult; import com.lino.design.event.listener.EventListener; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;/*** description: 事件处理器*/ public class EventManager {MapEnumEventType, ListEventListener listeners new HashMap();public EventManager(EnumEventType... operations) {for (EnumEventType operation : operations) {this.listeners.put(operation, new ArrayList());}}public enum EventType {/*** 事件类型*/MQ, Message}/*** 订阅** param eventType 事件类型* param listener 监听*/public void subscribe(EnumEventType eventType, EventListener listener) {ListEventListener users listeners.get(eventType);users.add(listener);}/*** 取消订阅** param eventType 事件类型* param listener 监听*/public void unsubscribe(EnumEventType eventType, EventListener listener) {ListEventListener users listeners.get(eventType);users.remove(listener);}/*** 通知** param eventType 事件类型* param result 结果*/public void notify(EnumEventType eventType, LotteryResult result) {ListEventListener users listeners.get(eventType);for (EventListener listener : users) {listener.doEvent(result);}} }整个处理的实现上提供了三个主要方法订阅 subscribe 、取消订阅 unsubscribe 、通知 notify 。这三个方法分别用于对监听事件的添加和使用。另外因为事件有不同的类型这里使用率枚举的方式进行处理也方便让外部在规定下使用事件而不至于乱传信息。 枚举EventType.MQ 、EventType.Message 4.4 摇号抽象类及其实现 4.4.1 业务抽象类 LotteryService.java package com.lino.design;import com.lino.design.event.EventManager; import com.lino.design.event.listener.MQEventListener; import com.lino.design.event.listener.MessageEventListener;/*** description: 摇号抽象类*/ public abstract class LotteryService {private EventManager eventManager;public LotteryService() {eventManager new EventManager(EventManager.EventType.MQ, EventManager.EventType.Message);eventManager.subscribe(EventManager.EventType.MQ, new MQEventListener());eventManager.subscribe(EventManager.EventType.Message, new MessageEventListener());}public LotteryResult draw(String uId) {LotteryResult lotteryResult doDraw(uId);eventManager.notify(EventManager.EventType.MQ, lotteryResult);eventManager.notify(EventManager.EventType.Message, lotteryResult);return lotteryResult;}/*** 执行摇号** param uId 用户编号* return 结果*/protected abstract LotteryResult doDraw(String uId); }使用抽象类的方式定义实现方法可以在方法中扩展需要的额外调用。 并提供抽象类 abstract LotteryResult doDraw(String uId) 让类的继承者实现。同时方法的定义使用的是 protected 也就是保证将来外部的调用方不会调用到此方法只有调用到 draw(String uId) 才能完成事件通知。 此种方式到实现是在抽象类中写好一个基本的方法在方法中完成新增逻辑到同时再增加抽象类的使用而这个抽象的定义会由继承者实现。另外在构造函数中提供了对事件的定义 eventManager.subscribe(EventManager.EventType.MQ, new MQEventListener()) 。在使用时也采用枚举的方式通知使用者传了哪些类型 eventManager.EventType.Message就执行哪些事件通知按需添加。 4.4.2 业务接口实现类 LotteryServiceImpl.java package com.lino.design;import java.util.Date;/*** description: 摇号服务实现* author: lingjian* createDate: 2023/2/6 17:02*/ public class LotteryServiceImpl extends LotteryService {private MinibusTargetService minibusTargetService new MinibusTargetService();Overrideprotected LotteryResult doDraw(String uId) {// 摇号String lottery minibusTargetService.lottery(uId);// 结果return new LotteryResult(uId, lottery, new Date());} }业务流程的实现没有额外的辅助流程只有核心流程的处理。 4.5 单元测试 ApiTest.java package com.lino.design.test;import com.alibaba.fastjson.JSON; import com.lino.design.LotteryResult; import com.lino.design.LotteryService; import com.lino.design.LotteryServiceImpl; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory;/*** description: 单元测试*/ public class ApiTest {private Logger logger LoggerFactory.getLogger(ApiTest.class);Testpublic void test_draw() {LotteryService lotteryService new LotteryServiceImpl();LotteryResult result lotteryService.draw(1000000101010019);logger.info(测试结果{}, JSON.toJSONString(result));} }测试结果 19:45:45.314 [main] INFO c.l.d.event.listener.MQEventListener - 记录用户 1000000101010019 摇号结果(MQ)恭喜你编码1000000101010019在本次摇号中签 19:45:45.319 [main] INFO c.l.d.e.l.MessageEventListener - 给用户 1000000101010019 发送短信通知(短信)恭喜你编码1000000101010019在本次摇号中签 19:45:45.398 [main] INFO com.lino.design.test.ApiTest - 测试结果{dateTime:1675770345311,msg:恭喜你编码1000000101010019在本次摇号中签,uId:1000000101010019}五、总结观察者模式 从基本的过程式开发到使用观察者模式面向对象开发可以看到使用设计模式改造后拆分出来核心流程与辅助流程的代码。 代码中的核心流程一般不会发生经常变化辅助流程会随着业务的变化而变化包括营销、裂变和促活等。因此使用设计模式编码就显得非常有必要。 观察者模式从结构上满足开闭原则当需要新增其他的监听事件或修改监听逻辑时不需要改动事件处理类。观察者模式可能不能控制调用顺序以及需要做一些事件结果的返回操作所以在使用的过程时需要考虑场景的适用性。
http://www.tj-hxxt.cn/news/139556.html

相关文章:

  • 广西建设执业资格注册中心网站东莞网站建设对比
  • 动漫网站首页设计公司名字大全最新
  • 网络最火的销售平台廊坊关键词优化排名
  • 广西美丽乡村建设网站网站稳定期的推广
  • 12380网站建设意见室内装饰设计师
  • wordpress php 链接地址重庆seo网站排名优化
  • 网站黑链 工具猪八戒网站开发
  • 英文 wap网站网站素材
  • 网站开发价格哪个网站可以做司考题
  • 合肥哪里有做网站重庆市门户网站制作
  • 佛山顺德网站制作公司企业网站建设的目的和意义
  • 林州网站建设策划莞城营销型网站建设
  • 做网站排名有用吗软件开发流程以及简要描述
  • 大连市城市建设投资集团网站网站seo检测工具
  • 网站视频放优酷里面怎么做泰安新闻头条最新消息
  • 网站哪里买外链东莞网站建设(推荐乐云践新)
  • 网站开发博客网页版微信客户端
  • 随州北京网站建设wordpress 侧栏
  • 哪里有服务好的网站建设wordpress无法自动更新
  • 丹东新区建设发展集团网站软文范文大全
  • 静态网站seo怎么做上高县城乡规划建设局网站
  • 室内设计师找图片的网站五种关键词优化工具
  • 做网站的实训报告如何转换page到wordpress
  • 烟台小学网站建设做百度网站还是安居客网站
  • 科技公司网站设计react网站开发介绍
  • 宿迁城乡建设监督网站商城网站做推广有什么好处
  • 如何做公司网站的wordpress书
  • 惠州网站建设科技有限公司静态网站html
  • wordpress点赞排行百度竞价和优化的区别
  • 卖衣服的网站排名连云港建设企业网站