软件执行程序UI框架

本文讨论了在Python和C++编程中,如何通过引入Command模式和API接口,实现业务逻辑与用户界面的解耦,创建了一个通用的UI与后台服务交互框架,包括模块化设计、中间件如日志和数据存储、以及不同版本的代码仓库链接。
摘要由CSDN通过智能技术生成

软件执行程序UI框架

背景

我经常写一些小程序,为了方便,基本都是使用Python来写的,基本都是从业务逻辑开始写起,在main函数里调用一下业务代码,当功能逐渐走向完善时,main函数中的内容就会变得相当臃肿,有设置一些全局状态的代码,还有读取和写出配置的一些代码,还有一些是用来判定业务规则的代码。从熵增角度来说,代码写的越多,混乱程度越大,由于缺乏架构框架方面的思考,代码虽然能够正常跑起来,但对于测试和后续的维护、移植带来诸多的不便。

在阅读《敏捷软件开发》时,看到Command模式,以及书中提出了图形界面和后台业务逻辑的解耦,这才使我在程序初始架构这一方面做出一些思考。

需要考虑的问题

  • 用户接口和后台程序耦合问题。正常情况下,刚开始我们会直接写出业务代码,在main函数中调用,功能增加以后或者程序给别人使用时,我们会增加一个用户界面,有时是文本形式,有时是图形界面,这个时候如果还是像main函数中一样调用后台程序,那么就会造成用户界面高度依赖后台模块,甚至要是GUI有某些状态值需要动态修改,还会照成后台程序依赖前端界面。
  • 为了解决问题,我们有需要让后台程序提供对外的api接口,让外界来调用这样的api接口,这样,我们就可以将前后端严格的区分开。
  • 调用api的的方式也可以分为两种,一种是提供api表,让外界直接调用,这也会造成api接口需要相对的稳定性,还有一种是通过指令查找法,做一个指令映射表,外界提供指令名和参数,调用查找指令的api接口,返回对应的指令,这样就使得调用方和api实现方得到一定的解耦,当然这个解耦也至少表面上的,真实的指令表还是需要和外界调用方是一个耦合关系,至少这个耦合变得不上那么直接。
  • 外界通过指令名,来获得实际api指令,那么这个api的形式就需要一个统一的形式,最合适的当时就是Command模式。最简单的Command模式,里面只有一个execute成员函数,当然在python中,最简单的Command模式意义不是很大,完全可以使用普通函数作为Command对象,python的普通函数其实也算对象,属于class Function。当然在我设计的指令中,不仅是指令调用,还需要承担完成help信息的职责,所以简单函数变得有些乏力,还是选用的是command模式的对象版来完成。
  • 我想要完成一款通用的UI与后台api的调用框架,那么用户如何调用api就成为需要考虑的方面,将调用api的方式进行抽象化,也就是需要有个模块来不断地提供指令,也可以称为指令源的类,那么指令源就可以有TUI(文本界面,如shell),GUI(图形界面),还有可以是脚本文件,脚本文件其实就是TUI中的文本指令通过文件预设的方式来给程序发送指令。当然除此之外,也提供了一种不走UI方式调用方式,也就是命令行调用,直接给出相应的参数,运行完就退出程序。
  • 将前后端解耦之后,甚至前后端可以分属不同的服务,可以在一台设备部署,可以进行分布式部署。
  • 单元测试问题,通过command模式,实现了后台程序api,也就是有了一个指令表,对于单元测试来说,也相当友好,可以将前端和后端通过一些mock对象来进行测试,反而比完整一块的代码更容易区分功能和目的。
  • 中间件-日志模块,程序的日志其实也算比较重要的一个方面,有时我们有些信息可以不会程序在用户界面,但是可以在后台日志进行输出,各种开发语言也都有很多日志第三方模块,但是我还是建议使用一个抽象的接口来管理这个三方日志模块,这样更为方便的去替换一些三方模块。
  • 中间件-持久化数据存储模块,在数据的持久化方面,比较简洁的像Json、Yaml、ini、xml等,或者就干脆就是纯文本或者是二进制文件,要不就是使用数据库,不过不是使用哪种方式,留出一个抽象接口总是好的,有些决定,最好不要提前就做出选择,比如数据库的使用,能尽量晚做决定就晚做决定,也许,到了后面,可能发现一个json也就满足要求,而不用考虑更为复杂的数据库。
  • 初始化配置问题,有时我们在进入程序需要使用初始化配置,这个其实和上一条的持久化存储是一种问题,但是初始化配置是需要进入程序就需要读取的东西,所以可以看作持久化数据存储的一个特例,还有如果缺失了配置文件,是使用默认配置,还是说直接抛出一个异常,都是由具体程序来决定的。

程序框架设计

在这里插入图片描述

整个框架的核心部分其实是在于右半部分,以UserInterface、InstructionSrc和Instruction为主要基类,其余的都是从这三个基类中衍生。UserInterface是用户界面的基类,可以衍生出GUI和TUI之类的用户操作界面,InstructionSrc是指令源的基类,可以有命令指令源、或者脚本指令源、甚至gui产生的指令源,而Instruction就是业务对api的基类,体现了Command模式,最终程序后端的业务代码对外指令都要实现这样的Instruction指令。

左侧的是一些中间件,如持久化存储模块,还有日志模块,最左侧表面这些中间件会使用一些三方库的组件。

最终实现的框架有python和C++两个版本。

Python版本的代码仓位于:UIFramework_python: Python tools template (gitee.com)

  • Python版本日志使用标准库的logging
  • 单元测试使用标准库的unittest
  • 持续化存储使用PyYAML

C++版本的代码仓位于:UI_Framework_CPP: UI Framework CPP version (gitee.com)

  • C++版本日志工具未使用三方组件,仅使用标准输出实现基础日志功能
  • 单元测试使用googletest
  • 持续化存储使用yaml-cpp
    功能
  • 46
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值