在Winform开发领域开发过十多年的项目中,见证着形形色色的架构和官方技术的应用,从最早类似Winform模式的WebForm技术,到接着的JQuery+界面组件,再到Asp.net Core的技术应用,以及后来的纯前端技术出现,Angular、React、Vue等前端技术和语言的广泛应用,Web应用越来越多,也越来越精细化,从最初的单服务,到单服务+分布式缓存,再到微服务集群的各种服务架构,Web开发的体系越来越庞大和复杂化,虽然引入更多先进技术、更多优秀架构,但同时也意味着更高的技术门槛,以及全栈式的开发需求或要求,Winform开发依旧占领一席之地。本篇随笔针对Winform开发的技术特点,针对自己多年的开发经验,对Winform开发的快速、健壮、解耦的一些领域提出几点微薄建议,抛砖引玉,希望大家多加指正。
1、Winform的技术概括
另一方面,作为Winform的替代者,Silverlight的盛行以及没落,WPF的逐步应用并重用,以及统一的通用 Windows 平台 (UWP),都充当着Winform的终结者的大任,不过即使应用范围缩减,Winform依旧很顽强,即使.netcore的大环境下,也依旧保留在Visual Studio 2022中,可见Winform开发的生命力之顽强。
Winform开发对比其他有不少优点,主要的特点还是开发方便,基于一定的框架,可以快速开发特定的业务管理系统。下面就WInform这个技术应用做一个个人的概括。
1)用户体验
在Winform应用里面,和其他Web系统比起来,它的用户体验是最好的,而且界面响应速度也比Web界面来的快捷一些,由于很多情况下,用户考虑使用方便性,如一些报表的展示、打印、导入导出文件的处理等常规的操作,都还是习惯使用Winform这种定制型非常好的界面来处理,毕竟大多数情况下,单位都有一套业务和数据的管理系统来处理这些业务。
2)数据敏感
另外很多情况下,如一些事业单位、机构什么,他们的数据是比较敏感的,不希望对外公开,网络的引入会提供数据外泄的可能,另外它们也是经常处于内网的环境下,因此一个单机版的程序就可以搞定他们的日常业务处理了,这种特别的业务环境,注定了使用Winform来处理会更胜一筹。
3)开发便利
Winform开发的程序,发布共享比较容易,直接安装就可以使用,可以不需要部署在云端(虽然我的混合框架方式可以访问Web API、WCF等服务获取数据,透明的数据处理);而且Winform的界面开发起来非常方便,结合界面套件,可以做出非常棒的界面效果。另外从开发角度上讲,Web前端的技术淘汰非常快,Winform的技术积累反而是在逐步加固的过程,因此对于一些开发人员来说,迭代Winform开发的应用会更加方便,也更加熟练,因此只要客户在用,系统兼容,这种Winform的程序会一直保留下去。
4)应用广泛
Winform开发的程序,其应用领域真的是覆盖方方面面,包括常规的数据库应用,以及Socket套接字的处理,底层硬件串口或者Modbus协议对接,基础打印、读卡器、射频开发、USB、摄像头的控制处理等,可以说Web能做的Winform基本都能做,而Winform能做的Web不一定能做到。
2、如何实现Winform的模块化开发?
对于如何实现Winform应用的模块化开发,其实本身Winform来源于早期Delphi、VB时代,它们已经是在控件的拖动处理、事件驱动方面都已经完善至极,对一些简单的应用,拖动一些控件,再增加一些事件响应处理即可完成主要的功能,这个也是很多早期共享软件盛行的重要原因。
随着程序功能的日益复杂化,Winform程序呈现模块化,把一些功能处理、UI界面等按照横向或者竖向划分,进行界面性、功能性的不同程度的分离,如出现了很多界面组件,如ActiveSkin/Skin++、DotNetBar、DevExpress等等,它们负责界面的渲染和简单的功能响应,对于业务性的界面则只能由开发者完成处理,但是已经实现一定程度的横向功能分离了。
通过利用这些UI组件,使得我们的Winform界面更加丰富,就像穿上了很高贵的服饰,面目一新,不过它还是不能解决程序复杂度的问题,有时候因为界面特性的原因,可能引入更多的复杂性难题,提供更多更精细难懂的事件来处理。
在我们开发一个应用的时候,往往需要集成一些应用场景,如基础的用户、角色、机构、权限、日志等权限管理系统,以及字典参考,附件管理等内容,以及一些封装好的分页处理控件,公用类库等支持类库等。
因此我们在这个基础上开发Winform项目,会更加高效快速。
Winform开发的相关业务逻辑(包括界面UI),都可以封装在一个简单的DLL文件中,需要的时候进行引用和调用即可,使用起来非常方便,这种方便也使得Winform程序的模块化更加简单和高效。
通过在解决方案中引入相关开发好的模块,直接调用使用即可,非常快速简单。
开发程序模块,除了一些业务模块外,大多数都是类似拼积木的方式,把它们在主界面中引入即可。
而Winform模块的调用,只需要简单的调用或者带入相关参数即可。
我们Winform框架通过多年积累,也提供了很多基础的模块来给我们新业务开发提供便利,如公用类库、分页控件、字典管理、权限管理系统、自动升级、附件管理、人员管理、工作流管理等可以反复重用的模块。
有了这些模块的加持,我们开发项目很多基础的处理就不用所有的东西都从头来过。
软件和建筑工程很类似,都是需要构建一个庞大而功能完整的一个系统,而工程化也意味着需要多人协作,那么就需要把一个庞大的系统横向或者纵向划分为各个可以独立施工完成的模块,虽然各个模块之间有所衔接或者交互,但是基本上可以以模块化的方式来构建,这个也是工程化开发的精髓所在。
以一个软件管理系统为例,我们尽可能把精力焦点放在客户的业务需求上,而对于常规的如权限控制、字典管理等一些常用的内容,由于它们的处理逻辑在特定领域上基本上比较固定一些,可以尽可能独立并重复使用。
3、如何实现Winform应用的解耦开发?
随着应用模块的复杂化,独立化,这个解耦的问题就是所有场景开发的共同问题,因此三板斧的操作大多数类似,虽然Winform特点又有所不同。
以数据库应用支持为例,对于不同模块的应用,可能需要同时支持不同数据库,通过配置实现切换不同数据库的调用。
因此在开发模块的时候,我们需要先定义统一的数据库处理接口,然后为不同类型的数据库访问做一个独立的实现处理。
在实际需求中,你往往不能决定客户需要用什么数据库,那么需要根据实际需求或者环境进行数据库类型的选型,如果是单机版为了方便可以使用SQLite,如果是已有业务系统或者需要响应速度快一些的,那么考虑使用SQLServer或者Mysql、有些历史原因的可能会用PostgreSQL或者Oracle等等。那么框架的弹性就需要支持多种数据库的了,这种支持不能导致太大的工作量最好,否则会弄得焦头烂额的。
框架底层数据库访问采用了微软企业库实现,因此在处理多种数据库访问的时候,能够提供统一的访问处理操作,同时对不同的数据库支持操作也是非常不错的。下图是框架底层数据库的支持情况。
采用不同的数据库,我们需要为不同数据库的访问层进行生成处理,如为SQLServer数据的表生成相关的数据访问层DALSQL,里面放置各个表对象的内容,不过由于采用了相关的继承类处理和基于数据库的代码生成,需要调整的代码很少。
而对于更高一级的应用数据来源,有可能来源于Web API,也有可能来源于数据库,也可能来源于WCF服务等方式的综合处理,那么可以再次利用接口,实现分离的方式,再次将实现解耦,标准的三板斧处理操作即可。
混合框架的分层架构图
4、如何实现Winform开发的简单化开发
由于Winform开发业务的日益复杂化,我们往往需要花费很多精力来做一些基础性的东西,虽然逻辑很简单,但是一些繁琐性的工作却很难避免,那么我们平时进行Winform开发的时候,如何才能实现Winform开发中的简化处理呢?
首先我们通过模块化来切分大项目的复杂度,然后再次进行类继承的方式减少类级别的代码,重用基类特性。
前面我们介绍采用了一些模块化的方式来组装项目,可以简单的理解为积木组合的方式。如权限管理模块、字典管理模块、自动更新模块、人员管理模块、通讯录管理模块、分页控件、公用类库等方面,这些可以在项目中根据情况采用对应的模块,非常高效,整个主体框架也有对应接入这些模块的案例代码供参考,因此可以更加直观明了。
而另一方面,我们在对类的重用方面,也是精益求精,尽量做到精简重复代码,提高开发效率的目的。
界面类提供封装继承,减少界面的一些繁琐设置。
界面通过基类的封装处理,我们可以把大多数通用的处理或者逻辑调用顺序进行封装,子类实现一些特殊的函数即可,同时可以统一调用基类的处理操作。
我们以常规业务模块界面来分析,主要有明细查看或编辑界面、列表界面,那么这些界面为了方便使用,我们可以抽象一部分界面处理逻辑或者共有部分内容,放在界面基类BaseEdit或者BaseDock等基类里面,如下界面所示。
基础业务类,我们同样也是采用重用基类方式,实现接口函数的封装处理。
以及业务类继承关系,当然还有其他更多的,基本上都提供一些基类来处理,简化代码。
Web API的控制器设计对象继承关系,如下所示:
除了这些基础性的代码级别的简化外,我们更高层次的简化,可以通过数据库=》代码生成的方式简化处理,通过数据库信息,我们可以进一步生成我们应用业务的相关类或者界面部分,从而可以快速提高开发效率。
如对于普通的Winform界面项目,利用代码生成工具Database2Sharp,我们生成后的项目结构视图如下所示。
而对于混合框架方案的项目,我们生成的界面项目结构视图如下所示。
对于Winform开发,可以根据Winform框架或者混合框架的窗体界面类,生成标准的界面代码,列表界面默认具有分页查询、导入导出、高级查询、编辑、删除事件绑定,编辑界面则具有获取数据并显示在控件,保存后执行更新或者写入的操作。
如在代码生成工具里面,设置主从表的界面生成如下所示。
生成的标准的主从表界面如下界面所示。
通过框架项目定制化的代码生成工具,可以快速的生成我们所需要的相关分层的代码,并继承好相关的类关系,以及标准调用代码,可以极大提高我们应用模块的开发速度,而且由于利用通过检验的标准件,开发出来的模块,除了快速外,也是健壮的。
另外们把常规的列表界面,新增、编辑、查看、导入等界面放在一起,除了列表页面,其他内容以弹出层对话框的方式进行处理,如下界面示意所示。