架构之模板方法等模式的使用

目录

一、程序编写背景

二、编程思路讲解

- 类图

- 实现逻辑

- 工厂模式

- 模板方法模式

  1. 接口类(代码)
  2. 抽象类(代码)
  3. 具体实现类(代码)
  4. 工厂类(代码)
  5. 注册类(代码)
  6. 系统启动加载(代码)
  7. 系统启动加载 - 初始化方法(代码)

总结

  1. 类图绘制
  2. UML图型使用
  3. 设计模式理解
  4. 推荐书籍

一、背景

1. 业务需要使用ocr场景对图片进行识别。但由于前期使用的TesserOcr识别率不是特别高。故又需要新的识别方式。
2. 在确定使用paddleocr后,对程序进行修改。为了兼容两种ocr使用方式。
3. 通过配置yml文件的方式可以在使用时对两种ocr识别方式进行切换使用。(也可配置入数据库进行动态配置)

具体的Ocr识别教程可参照其他文章

TesseractOcr(开源ocr)

  • 安装及使用此部分内容后期待补充

PaddleOcr (开源ocr)

  • paddleocr的安装及使用此部分内容后期待补充
  • 使用pyinstall打包 >> 👀
  • paddleocr模型的训练 此部分内容后期待补充

二、编程思路讲解

首先上类图。可以较直观表现了调用关系

在这里插入图片描述

1. 实现逻辑

简单描述了程序调用顺序

1. 手动配置yml中ocr类型(可配置入数据库进行动态配置)。
2. 程序启动时将两种ocr服务对象加载入缓存。
3. 业务进行时,程序识别会通过传入参数获取对应类型的orc服务对象进行识别服务。
2. 工厂模式

创建TesseractOcr与PaddleOcr使用

import service.ocrservice.recognize.OcrMultiParamRecognize;
import service.ocrservice.recognize.OcrNomralRecognize;
import service.ocrservice.recognize.PaddleOcrRecognize;
import com.msun.cloud.dcm.util.Direct;import java.io.File;public class RecognizeFactory {/*** TesseractOcr识别*/public static Recognize getRecognize(String dataPath, File pendingFile, Direct patientDirect, Direct accnumDirect, String formateName, String dpi) {return new OcrNomralRecognize(dataPath, pendingFile, patientDirect, accnumDirect, formateName, dpi);}/*** paddleOcr识别*/public static Recognize getPaddleOcrRecognize(String filePath, Direct patientDirect, Direct accnumDirect, String formateName) {return new PaddleOcrRecognize(filePath, formateName, patientDirect, accnumDirect);}
}
3. 模板方法模式

粘贴内容还包括使用工厂模式创建对象

  • 接口类
    提供了业务在调用Ocr服务类对象时的统一接口,表现了面向接口编程的思想
    package service.ocrservice;import entity.PO.Patient;
    import PO.RecognizeTemplate;import java.io.File;/*** 通过ocr识别获取患者信息*/
    public interface OcrPatientService {Patient getRecognizedPatient(File pendingFile, String aeTitle, String spFilePath, String formateName, RecognizeTemplate recognizeTemplate);Recognize getRecognize(File pendingFile, RecognizeTemplate template, String formatName);}
  • 抽象类
    封装了公共方法,子类实现抽象类中的抽象方法。公共方法对抽象方法进行调用
    package service.ocrservice;import com.alibaba.fastjson.JSON;
    import entity.BO.OcrRecognizeLog;
    import entity.PO.Patient;
    import entity.PO.RecognizeTemplate;
    import entity.common.Const;
    import mapper.PatientMapper;
    import mapper.RecognizeTemplateMapper;
    import service.SystemConfigService;
    import service.ocrservice.entity.RecognizeEntity;
    import service.ocrservice.service.AsyncOcrRecognizeLogService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;import javax.annotation.Resource;
    import java.io.File;
    import java.util.List;@Slf4j
    public abstract class AbstractOcrPatientServiceImpl implements OcrPatientService{@Resourceprivate RecognizeTemplateMapper recognizeTemplateMapper;@Resourceprivate SystemConfigService systemConfigService;@Autowiredprivate AsyncOcrRecognizeLogService asyncOcrRecognizeLogService;@Resourceprivate PatientMapper patientMapper;/*** 获取识别的人员信息* @return*/public Patient getRecognizedPatient(File pendingFile, String aeTitle, String spFilePath, String formateName, RecognizeTemplate recognizeTemplate) {Patient patient = null;try{# 抽象方法调用patient = recognize(dataPath, pendingFile, template, formateName);} finally {...}return patient;}public abstract Patient recognize(String dataPath, File pendingFile, RecognizeTemplate template, String formatName);private void insertExOcrRecord(Patient patient, String aeTitle, String spFilePath) {... 插入日志}protected Patient queryPatient(RecognizeEntity entity) {... 查询人员信息}}
  • 具体实现类
    package com.msun.cloud.dcm.service.ocrservice.impl;import com.msun.cloud.dcm.entity.PO.Patient;
    import com.msun.cloud.dcm.entity.PO.RecognizeTemplate;
    import com.msun.cloud.dcm.service.ocrservice.AbstractOcrPatientServiceImpl;
    import com.msun.cloud.dcm.service.ocrservice.OcrPatientService;
    import com.msun.cloud.dcm.service.ocrservice.Recognize;
    import com.msun.cloud.dcm.service.ocrservice.RecognizeFactory;
    import com.msun.cloud.dcm.util.Direct;
    import org.springframework.stereotype.Service;import java.io.File;
    import java.util.function.Consumer;@Service
    public class PaddleOcrPatientServiceImpl extends AbstractOcrPatientServiceImpl {@Overridepublic Patient recognize(String dataPath, File pendingFile, RecognizeTemplate template, String formatName) {Direct patientDirect = new Direct(template.getPatientRecognizeX(), template.getPatientRecognizeY(), template.getPatientRecognizeW(), template.getPatientRecognizeH());Direct accNumDirect = new Direct(template.getAccnumRecognizeX(), template.getAccnumRecognizeY(), template.getAccnumRecognizeW(), template.getAccnumRecognizeH());Recognize recognize = RecognizeFactory.getPaddleOcrRecognize(pendingFile.getAbsolutePath(), patientDirect, accNumDirect, formatName);if("1".equals(template.getIsReBuild())){return queryPatient3D(recognize.recognize());}return queryPatient(recognize.recognize());}public Recognize getRecognize(File pendingFile, RecognizeTemplate template, String formatName) {Direct patientDirect = new Direct(template.getPatientRecognizeX(), template.getPatientRecognizeY(), template.getPatientRecognizeW(), template.getPatientRecognizeH());Direct accNumDirect = new Direct(template.getAccnumRecognizeX(), template.getAccnumRecognizeY(), template.getAccnumRecognizeW(), template.getAccnumRecognizeH());Recognize recognize = RecognizeFactory.getPaddleOcrRecognize(pendingFile.getAbsolutePath(), patientDirect, accNumDirect, formatName);return recognize;}
    }
    
  • 工厂类
    import ocrservice.recognize.OcrMultiParamRecognize;
    import ocrservice.recognize.OcrNomralRecognize;
    import ocrservice.recognize.PaddleOcrRecognize;
    import util.Direct;import java.io.File;public class RecognizeFactory {/*** 范围识别* @param dataPath* @param pendingFile* @param patientDirect* @param formateName* @param dpi* @return*/public static Recognize getRecognize(String dataPath, File pendingFile, Direct patientDirect, String formateName, String dpi) {return new OcrMultiParamRecognize(dataPath, pendingFile, patientDirect, formateName, dpi);}/*** 精确识别* @param dataPath* @param pendingFile* @param patientDirect* @param formateName* @param dpi* @return*/public static Recognize getRecognize(String dataPath, File pendingFile, Direct patientDirect, Direct accnumDirect, String formateName, String dpi) {return new OcrNomralRecognize(dataPath, pendingFile, patientDirect, accnumDirect, formateName, dpi);}public static Recognize getPaddleOcrRecognize(String filePath, Direct patientDirect, Direct accnumDirect, String formateName) {return new PaddleOcrRecognize(filePath, formateName, patientDirect, accnumDirect);}
    }
    
  • 注册类(包含枚举类)
    package service.ocrservice;import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Map;/*** 收集 ocr 服务类*/
    @Component
    public class OcrServiceRegistry {public static Map<OcrType, OcrPatientService> registryMap = new HashMap();public static OcrPatientService ocrPatientServiceCache;...public enum OcrType {TesserOcr("1"),PaddleOcr("2");private String code;OcrType(String code) {this.code = code;}public static OcrType getOcrTypeByCode(String code) {for (int i = 0; i < OcrType.values().length; i++) {OcrType ocrType = OcrType.values()[i];if(ocrType.code.equals(code)) return ocrType;}return TesserOcr;}}public static OcrPatientService getOcrService(String ocrTypeCode) {if(ocrPatientServiceCache == null) {ocrPatientServiceCache = registryMap.get(OcrType.getOcrTypeByCode(ocrTypeCode));}return ocrPatientServiceCache;}
    }
    
  • 系统启动加载
    import lombok.Data;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.ApplicationArguments;
    import org.springframework.boot.ApplicationRunner;
    import org.springframework.data.redis.listener.RedisMessageListenerContainer;
    import org.springframework.stereotype.Component;import javax.annotation.Resource;/*** 初始化工具类*/
    @Slf4j
    @Data
    @Component
    public class PostApplicationRunner implements ApplicationRunner {@Resourceprivate ProjectConfig projectConfig;@Overridepublic void run(ApplicationArguments args) throws Exception {PrintDcmOcrRecognizeService.init();}
    }
  • 系统启动加载 - 初始化方法
    public class PrintDcmOcrRecognizeService {public static void init() {OcrServiceRegistry.registryMap.put(OcrServiceRegistry.OcrType.TesserOcr, SpringUtils.getBean(TessOcrPatientServiceImpl.class));OcrServiceRegistry.registryMap.put(OcrServiceRegistry.OcrType.PaddleOcr, SpringUtils.getBean(PaddleOcrPatientServiceImpl.class));}
    }
    

三、总结

  1. 类图绘制。
    类图绘制为后期加入的。前期没有做类图中框架的设计,模式的使用是可以是根据业务的需要而做的。在编程中对业务架构中每一个部分做了设计。最后的总结才有了这个样子。类图参照《大话设计模式》一书
    在这里插入图片描述

  2. UML图型使用。
    UML类图中图型的使用是参照《大话设计模式》中UML类讲解 >> | 使用的。

  3. 设计模式理解。
    目前经常用到的设计模式种类不多。基本为工厂、模板、享元、静态代理。设计模式虽多,但不宜滥用,过度设计,因为设计的初衷是根据业务的需要,使得代码更加容易阅读和拓展。

  4. 推荐书籍。
    -《大话设计模式》使用讲Demo的方式有趣介绍了模式的使用,其中的UML类图使用较多
    -《设计模式之美》根据实际业务场景讲解了何时要用到设计模式。内容易懂,对工作帮助比较大 可以在有了设计模式基础后去读一读

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2776960.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3 常用的10个组合式 API

2024-01-025,917阅读6分钟 Vue.js是一个用于开发Web应用程序的强大JavaScript框架。Vue 2 于 2023 年 12 月 31 日停止维护。而通过Vue 3&#xff0c;组合式API增强了我们利用Vue的能力&#xff0c;使我们的代码更具模块性和可读性。下面分享10个常用的Vue3组合式API&#xff…

[office] excel如何计算毛重和皮重的时间间隔 excel计算毛重和皮重时间间隔方法 #笔记#学习方法

excel如何计算毛重和皮重的时间间隔 excel计算毛重和皮重时间间隔方法 在日常工作中经常会到用excel&#xff0c;有时需要计算毛重和皮重的时间间隔&#xff0c;具体的计算方式是什么&#xff0c;一起来了解一下吧 在日常工作中经常会到用excel&#xff0c;在整理编辑过磅数据…

美创科技与河南金融信创生态实验室签署战略合作协议

2024年1月31日&#xff0c;由普惠通科技与河南省科学院物理所、北京交通大学、中国金融电子化集团重庆金融认证中心联合发起成立中部地区第一家金融信创生态实验室运营公司&#xff08;即河南豫科普惠通信创科技有限公司&#xff09;与杭州美创科技股份有限公司战略合作签约仪式…

【python】学习笔记02-判断语句

2.1 布尔类型和比较运算符 1. 在Python中&#xff0c;可以表示真假的数据类型是&#xff1a; 布尔类型&#xff0c;字面量True表示真&#xff0c;字面量False表示假 2. 除了可以定义布尔类型外&#xff0c;还可以通过____计算得到布尔类型&#xff1f; 通过<比较运算符>…

精雕细琢的文档体验:Spring Boot 与 Knife4j 完美交汇

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 精雕细琢的文档体验&#xff1a;Spring Boot 与 Knife4j 完美交汇 前言Knife4j 与 Swagger 的区别1. 特性与优劣势对比&#xff1a;Knife4j&#xff1a;Swagger&#xff1a; 2. 选择 Knife4j 的理由&a…

STL之stack+queue的使用及其实现

STL之stackqueue的使用及其实现 1. stack&#xff0c;queue的介绍与使用1.1stack的介绍1.2stack的使用1.3queue的介绍1.4queue的使用 2.stack&#xff0c;queue的模拟实现2.1stack的模拟是实现2.2queue的模拟实现 3.总结 所属专栏&#xff1a;C“嘎嘎" 系统学习❤️ &…

话题:IT行业有哪些证书含金量高?

IT行业有哪些证书含金量高? 1. 以下是一些在IT行业中我认为具有高含金量的证书&#xff1a; 思科认证&#xff08;Cisco Certifications&#xff09;&#xff1a;思科认证是由网络领域的著名厂商——Cisco公司推出的&#xff0c;是互联网领域的国际权威认证。这个认证体系包含…

如何像工程师一样阅读 - 快速阅读技术书籍的9个技巧

0. 目的 在看了 Read Like an Engineer: 9 Tips for Reading Technical Books Fast 之后&#xff0c; 记录一些个人的看法&#xff0c;并在这篇英文文章上作为实验&#xff0c; 记录一下正确的阅读方法。 1. 第一次阅读 1.1 生词表 parcel of the job: 工作中必不可少的部分…

使用cocos2d-console初始化一个项目

先下载好cocos2d-x的源码包 地址 https://www.cocos.com/cocos2dx-download 这里使用的版本是 自己的电脑要先装好python27 用python安装cocos2d-console 看到项目中有个setup.py的一个文件 python setup.py 用上面的命令执行一下。 如果执行正常的话回出现上面的图 然后…

Vue事件中如何使用 event 对象

在Vue中&#xff0c;事件处理函数常常需要获取事件触发时的相关信息&#xff0c;比如鼠标位置、按键信息等。而要获取这些信息&#xff0c;就需要使用event对象。那么在Vue的事件中如何正确使用event对象呢&#xff1f;接下来就来详细介绍一下。 首先&#xff0c;在Vue的事件中…

通过遵循最佳做法来提高 EDA 和 HPC 应用程序的 Azure NetApp 文件性能

介绍 Azure NetApp 文件是一项托管存储解决方案&#xff0c;适用于各种方案&#xff0c;包括高性能计算 (HPC) 基础结构。 低延迟和每秒高 I/O 操作数 (IOPS) 对于大规模企业而言是一种很好的组合。 假设你就职于一家半导体公司。 你的任务是设计公司的集成电路芯片&#xff…

P59---第二阶段B C 相电流

P59---第二阶段B C 相电流

curl8.6.0 - CURLE_PEER_FAILED_VERIFICATION

文章目录 curl8.6.0 - CURLE_PEER_FAILED_VERIFICATION概述笔记END curl8.6.0 - CURLE_PEER_FAILED_VERIFICATION 概述 在看一个开源工程, 里面用到了curl和openssl, 但是工程使用vcpkg来管理的包, 用CMake来编译 依赖太多了, win10 编译选项为 vs2019 x64/Win32(或者Ninja)…

STM32F1 - 标准外设库_规范

STM32F10x_StdPeriph_Lib_V3.6.0 1> 头文件包含关系2> .c文件内部结构3> 宏定义位置4> 位掩码bit mask5> .c文件中定义私有变量 1> 头文件包含关系 1个头文件stm32f10x.h 就把整个MCU以及标准外设库&#xff0c;就管理了&#xff1b; 2> .c文件内部结构 …

【服务器数据恢复】服务器RAID模块硬件损坏的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 某品牌服务器中有一组由数块SAS硬盘组建的RAID5磁盘阵列&#xff0c;服务器操作系统是WINDOWS SERVER&#xff0c;服务器中存放企业数据&#xff0c;无数据库文件。 服务器出故障之前出现过几次意外断电的情况&#xff0c;服务器断电…

C++ 中的模型预测控制(01/2)

目录 一、说明二、MPC原理说明三、分解算法的来源并显示关键特征&#xff0c;四、C 实现说明五、平衡 Q 和 R六、资源下载地址 一、说明 以下文章介绍了应用模型预测控制器的简单控制系统方法。本文讨论了这种控制的基本机制&#xff0c;该机制适用于各种工程领域。 MPC 涉及对…

4.5 特效规范与拆分实现及程序的调用原理

一、特效基础流程 落地方案 连入游戏 需求 策划需求,美术需求 需要的SHADER,功能 测试/反馈/修改 效果迭代 满足功能的特效 概念设计 参考图,设计图 二、规范的设计原理与目的 节约沟通成本 保持项目的一致性 工作交接可以更加便捷 降低出错的概率 提升工作效率…

【数据结构】前缀树的模拟实现

目录 1、什么是前缀树&#xff1f; 2、模拟实现 2.1、前缀树节点结构 2.2、字符串的添加 2.3、字符串的查寻 2.3.1、查询树中有多少个以字符串"pre"作为前缀的字符串 2.3.2、查询某个字符串被添加过多少次 2.4、字符串的删除 3、完整代码 1、什么是前缀树&…

Vue-Vue3 集成编辑器功能

1、安装依赖 编辑器插件需要安装 wangeditor/editor 和 wangeditor/editor-for-vue 两个插件 npm install wangeditor/editor --savevue3运行如下命令安装 npm install wangeditor/editor-for-vuenext --savevue2运行如下命令安装 npm install wangeditor/editor-for-vue -…

设计模式3-责任链模式

责任链模式是一种行为设计模式&#xff0c;它允许你创建一个对象链。请求沿着这条链传递&#xff0c;直到有一个对象处理它为止。这种模式通常用于需要以某种方式动态地决定处理请求的顺序或方式的情况。 类图&#xff1a; 从图中可见最大的特点是AbstractHandler它自己聚合了自…