【大型软件开发】浅谈大型Qt软件开发(二)面向未来开发——来自未来的技术:COM组件。我如何做到让我们的教学模块像插件一样即插即用,以及为什么这么做。
前言
最近我们项目部的核心产品正在进行重构,然后又是年底了,除了开发工作之外项目并不紧急,加上加班时间混不够了....所以就忙里偷闲把整个项目的开发思路聊一下,以供参考。
鉴于接下来的一年我要进行这个主框架的开发,本着精益求精的态度,加上之前维护前辈的产品代码确实给我这个刚毕业的社畜带来了不小的震撼,我决定在这个模块的开发中优化之前的开发模式,提升整个产品的健壮性和独立性。
开发一个大型软件最重要的问题有三个,一是如何保证每个模块开发的独立性 二是如何保证数据结构的一致性 三是如何保证程序的可维护性和健壮性。这几个文章的内容我会在几篇文章中分开聊聊我的做法,做个记录。
本篇文章聊聊如何保证各个模块开发的独立性——怎么让功能模块、教学模块的开发独立于主框架本身。让不同的模块之间尽量通过接口的形式进行交互,而抛弃传统的中转消息码->调用模块的模式,让实际功能以接口形式暴露。
这一期简单聊聊开发准备,下一期浅谈怎么在开发中我们项目如何保证模块开发的独立性。
技术背景
请在阅读以下两篇文章之后观看本文以获得更佳的体验,以免你不知道我在说什么。
Qt开发Active控件:如何使用ActiveQt Server开发大型软件的主框架
【大型软件开发】浅谈大型Qt软件开发(一)开发前的准备——在着手开发之前,我们要做些什么?
为什么?
我们谈到为什么要这样开发的之前,要先聊聊之前我们的框架。
我们的软件之前没有框架,就是一个大的C#程序,然后里面想到什么就塞什么,然后教学模块、主框架、功能模块之间就通过一个C#事件委托向上传递。教学模块中没有办法直接引用所有的功能模块,而是通过一个函数里面传参,再转移到主程序中去。

这个模式本身是没有任何问题的,但是也可能是开发人员当时在开发的时候没有考虑过这个项目要维护十多年,导致整个程序在后面变成了一个几乎不可维护的庞然大物。
这里功能模块是几乎嵌死在主框架内的,这个是可以的,因为功能模块一般是调用外部的DLL或者对外部exe的管理,一般会和这些模块之间有深度的交互。而且一般我们也很少更新新的功能模块,光是现有的功能模块就几乎够了,之后的更新哪怕是直接嵌入在主框架内也是没有关系的。
当然了,功能模块也是一个个DLL,但是原先的调用是在使用的时候去尝试实例化一个功能类,然后再调用其中的方法。这样就涉及到调用、事件绑定等问题。
最严重的问题还是来自教学模块的信息向上传递。这个是由于引用导致的:
1.我们不可能让每个教学模块去引用各个功能模块,这样主框架完全脱离了教学模块的掌控,那相当于是每个教学模块重新开发了。而且每个功能模块并不能直接这样使用,需要的很多参数和消息都必须在主框架中获取或者初始化。比如座位信息,我们这个产品有一套很复杂的座位信息数据。还有一些比如MAC地址等。如果独立获取会极大的提升整个产品开发的维护难度和开发难度。
2.只能由框架去调用教学模块,这也就导致消息没法直接向上传递,只能通过类似回调函数的事件委托将事件以类似 key-value键值对的形式向上发送。这样我的主框架就要写一大堆if else去根据每个key去判断教学模块发这个消息想表达什么了。
我这里展示其中一部分就知道有多逆天了:


当然就像我说的,这是由于早期设计的时候完全没有考虑程序的拓展性开发所用的妥协性开发策略。在一开始确实方便而且好用。在后面这样一大坨if else让整个代码维护起来简直异常困难,更别提在接到消息之后这里还需要小小处理一下。
3.教学模块没法独立开发,必须依托于教师端。怎么说呢,就是教学模块几乎完全没法脱离教师端进行开发,因为要教学模块也需要暴露一大堆方法和接口供主框架去交互。模块设计操作起来就非常恶心了。
甚至!我们之前有过用exe的应用程序,所有的信息交互都是通过SendMessage进行的!你知道那对我幼小的心灵造成了多么大的伤害吗!这样的教学模块几乎是完完全全嵌在主框架内的专用exe,几乎不存在什么扩展性和维护性,因为除了问题除了开发者本人,别人根本没法改,也不知道怎么改。
或者我们换一种说法:教学模块这样设计就只能让主框架开发人员开发,且很难多个模块之间平行开发。
怎么做?
这就不得不提到面向未来的技术:COM组件
COM组件可以让主框架提供接口,然后各个教学模块就可以直接去调用主框架提供的接口。这样就直接替换掉了我上面说的if else判定这种僵硬的开发方式。
这个是ActiveQt Server向外公布的接口文档

这里提供的Public slots 就是主框架提供的方法。这样我们就可以通过直接调用接口的方式调用主框架内部的服务了。
也就是说框架实际上和之前的那个if else也差不多,区别就是主框架不需要在接收到消息之后进行检索,可以直接调用接口了。也就是说不需要维护那么长一条if else 链,而是暴露接口,管理接口即可~
就这样?当然不止,在这里我还提供了一个新的教学模块开发的范式。原来的教学模块 就像静态调用的DLL,而现在我们希望这个教学模块能像插槽一样即插即用。
该怎么做?既然是即插即用,那么就得请出我们的动态调用DLL 方法,接下来我将给出我的框架设计。
框架设计?
框架设计分为教学模块设计和主框架接口设计,这两部分实际上都是对主框架的设计,不过涉及的内容不一样。
教学模块框架
教学模块框架的涉及我需要给出一张图来做表示:

这个部分看图吧,我懒得解释太多了,这个图我觉得写的相当清楚了。
流程如下:
1.通过读取配置文件确定有哪些模块是可以尝试去调用的
2.在本地文件夹中检索可以调用的模块是否存在
3.调用教学模块约定好的方法来确定当前模块是否可用。
4.读取本地锁控,确定指定模块是否有锁控权限。
注1:因为是动态加载的DLL,那么DLL就必须提供类C接口,也就是extern "c" __del什么的,我忘了,反正就这么回事,自己百度查一下吧。
主框架的接口设计:

如图所示,我们在Interface_Kernel中提供了整个主程序中挂载的所有功能模块的单例调用接口,并在Interface_Kernel的单例中进行管理,然后再通过单例的方式直接向功能模块申请功能。这样既避免了大量重复啰嗦的消息码发来发去,也可以减少很多重复开发的工作量。
这样操作,主框架就不需要提供一个单独的类来管理教学模块和与教学模块进行交互了,而是可以只需要关心教学模块的启动、关闭、显示、隐藏 即可,其他的功能都由Interface_kernel单独交互即可。
这里我写了一个完整的工程,但由于代码是公司的财产,在此我不能开源所有的代码,如果你是将来维护开发的人员,你应该可以根据这篇博客了解到为什么主框架代码中会有接口类还有一个Interface_Kernel,原因也很简单,因为每次外部绑定主程序的时候,都会实例化一个新的接口,需要一个核心来管理所有的接口类实例。
至于说教学模块DLL的管理,也是类似的,但是这里就不展开细聊了。
总结
COM组件为功能模块的集中管理提供了可能,同时也为教学模块的独立开发提供了可能。
整个新框架和旧框架的核心思想区别就是:就框架把所有的教学模块都当成了主程序的一部分。
而新的框架中主程序其实只是为所有的教学模块提供各种各样的服务,比如语音、视频等服务,教学模块只需要调用指定的COM接口就可以直接调到主程序中的工具,而不需要再进行模块间的交互。而教学模块本身也只需要提供开启、关闭、显示、隐藏、认证五个接口,不需要再像之前一样写一大坨东西管理教学模块了。
这样既为后续模块化开发提供了更多的便利,也让主程序更加简洁,减少了很多不必要的重复开发。
如果有什么讲的不够详细的地方欢迎站内私信,我会尽量解答。
【大型软件开发】浅谈大型Qt软件开发(二)面向未来开发——来自未来的技术:COM组件。我如何做到让我们的教学模块像插件一样即插即用,以及为什么这么做。的更多相关文章
- [IC]浅谈嵌入式MCU软件开发之中断优先级与中断嵌套
转自:https://mp.weixin.qq.com/s?__biz=MzI0MDk0ODcxMw==&mid=2247483680&idx=1&sn=c5fd069ab3f ...
- 浅谈大型web系统架构
动态应用,是相对于网站静态内容而言,是指以c/c++.php.Java.perl..net等服务器端语言开发的网络应用软件,比如论坛.网络相册.交友.BLOG等常见应用.动态应用系统通常与数据库系统. ...
- 转:浅谈大型web系统架构
浅谈大型web系统架构 动态应用,是相对于网站静态内容而言,是指以c/c++.php.Java.perl..net等服务器端语言开发的网络应用软件,比如论坛.网络相册.交友.BLOG等常见应用.动态应 ...
- 浅谈OA办公软件市场行情
3.原文:http://www.jiusi.net/detail/472__776__3999__1.html 关键词:oa系统,OA办公软件 浅谈OA办公软件市场行情 中国的OA办公软件市场历经20 ...
- 【ZZ】浅谈大型web系统架构 | 菜鸟教程
浅谈大型web系统架构 http://www.runoob.com/w3cnote/large-scale-web-system-architecture.html
- 浅谈关于QT中Webkit内核浏览器
关于QT中Webkit内核浏览器是本文要介绍的内容,主要是来学习QT中webkit中浏览器的使用.提起WebKit,大家自然而然地想到浏览器.作为浏览器内部的主要构件,WebKit的主要工作是渲染.给 ...
- springboot开发浅谈 2021/05/11
学习了这么久,本人希望有时间能分享一下,这才写下这篇浅谈,谈谈软件,散散心情. 这是本人的博客园账号,欢迎关注,一起学习. 一开始学习springboot,看了好多网站,搜了好多课程.零零落落学了一些 ...
- Android开发-浅谈架构(二)
写在前面的话 我记得有一期罗胖的<罗辑思维>中他提到 我们在这个碎片化 充满焦虑的时代该怎么学习--用30%的时间 了解70%该领域的知识然后迅速转移芳草鲜美的地方 像游牧民族那样.原话应 ...
- Python测试开发-浅谈如何自动化生成测试脚本
Python测试开发-浅谈如何自动化生成测试脚本 原创: fin 测试开发社区 前天 阅读文本大概需要 6.66 分钟. 一 .接口列表展示,并选择 在右边,点击选择要关联的接口,区分是否要登录, ...
- Android蓝牙开发浅谈(转)
http://www.eoeandroid.com/thread-18993-1-1.html 对于一般的软件开发人员来说,蓝牙是很少用到的,尤其是Android的蓝牙开发,国内的例子很少 A ...
随机推荐
- `<jsp:getProperty>`动作和`<jsp:setProperty>`动作的使用在一个静态页面填写图书的基本信息,页面信息提交给其他页面,并且在其页面显示。要去将表单元素的值赋值给Java
<jsp:getProperty>动作和<jsp:setProperty>动作的使用 1.<jsp:getProperty>动作 语法格式: <jsp:get ...
- 齐博x1标签实例:标签的嵌套用法,调用聚合数据
齐博标签非常强大,可以让不懂程序的你,轻松就能实现所见即所得. 下面跟大家讲解一下,最复杂的运用, 同时使用了union 动态变量参数 与 分页处理标签 比如下面这张图,不仅仅想调用圈子,还想同时调用 ...
- 从0搭建vue3组件库:自动化发布、管理版本号、生成 changelog、tag
今天看到一篇文章中提到了一个好用的工具release-it.刚好可以用在我正在开发的vue3组件库.纸上得来终觉浅,绝知此事要躬行,说干就干,下面就介绍如何将release-it应用到实际项目中,让组 ...
- vue3+element-plus+登录逻辑token+环境搭建
vue3+element-plus+登录逻辑token环境搭建 安装脚手架工具 1 npm i @vue/cli@4.5.13 -g 验证是否安装成功 1 vue -V # 输出 @vue/cli 4 ...
- 从 Wepy 到 UniApp 变形记
作者:vivo 互联网前端团队-Wan Anwen.Hu Feng.Feng Wei.Xie Tao 进入互联网"下半场",靠"人海战术"的研发模式已经不再具备 ...
- Redis系列8:Bitmap实现亿万级数据计算
Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...
- idea如何生成jar包
最近在研究RMI反序列化命令执行的漏洞,让我这个java新手吃尽了苦头,能多学习一些是一些吧. 记录一下写好的java文件生成jar包的过程. 环境: Win10,jdk1.7, idea2016.2 ...
- [Pyhton] SimPy 离散事件模拟框架详解 —— 以一个简单的汽车充电排队模拟为例
目录 一.背景知识 二.SimPy 讲解 2.1 SimPy 概述 2.2 基本概念 2.3 一个汽车开开停停的例子 2.4 在走走停停过程中增加充电过程(过程交互) 2.5 共享资源 三.后续 参考 ...
- ThreadLocal的介绍与运用
ThreadLocal全面解析 学习目标 了解ThreadLocal的介绍 掌握ThreadLocal的运用场景 了解ThreadLocal的内部结构 了解ThreadLocal的核心方法源码 了解T ...
- Archlinux配置fcitx5
fcitx5--Linux中最好用的中文输入法 ArchLinux配置fcitx5 输入法 本文基于archlinux + dwm.其他的桌面环境以及窗口管理器,配置选项差不多. 安装基础包 fcit ...