Winform开发框架重构总结

简介:

最近一直致力于Winform开发框架的重构工作,因为发现要维护传统Winform开发框架、WCF开发框架、混合式开发框架,以及相关的模块,包括权限管理、字典管理模块、附件管理、人员管理等一些辅助模块,很多代码都会有重复的部分,优化的框架是想提高效率,减少冗余重复代码,本文总结Winform开发框架重构工作中的一些经验总结,以飨读者,希望能够对大家有一定的参考作用。

1、公用类库的分离处理

我的公用类库是自己开发这么多年的总结、收集和整理,对大多数的类库均进行优化整理过,公用类库的本意是对.NET内置的类库进行包装使用,提高使用效率和减少复杂性,随着开发项目的增多和不断的总结,有时候一些常用的第三方类库包装类也很常见,使用很频繁,经常在各个模块中使用,因此把框架中常用到的类库分为两类,一个是".NET内置类公用类库“,一个是第三方类库的包装类,如我经常用到的Aspose.Cell、Apose.Word、NPOI、Myxls等Office相关类库的包装类,还有Log4Net日志类、Zip压缩类库等等,如下界面是一个截图。

这样虽然在管理上增加多了一个公用类库的程序集,但是这样区分有利于我们对类库的扩展和维护。

2、Winform框架基类的封装和独立

在这次的重构工作中,很大程度上是提取所有框架和模块中用到的各种基类到一个第三方类库包装类里面,然后在框架里面统一使用这个类库,如原来数据访问里面常用到的BaseBLL、BaseDAL、IBaseDAL、AbstractBaseDAL,其中BaseDAL虽然继承了AbstractBaseDAL绝大多数的方法,但是不同的数据库还是有一些小差异的,因此把BaseDAL分为了几个不同数据库版本的BaseDAL,包括Access、MySql、Oracle、SqlServer、Sqlite等数据库的基类。

这样把它们独立出来,不用再每个数据访问的模块都复制一份,而且可以方便统一维护和升级,因为基类和接口一旦增加,所有的业务类都会同时具有增加的功能,非常利于维护扩展。除了数据访问相关的基类,还对WCF服务等相关的基类也进行了抽取,这样在WCF框架或者混合型框架中,就可以直接使用了。

3、在框架中使用封装独立的基类

1)传统Winform框架的对象

把这些框架中常用到的类库独立抽取出来后,整个框架文件就比较简洁很多了,也不用再多个模块经常使用BeyondCompare比较来比较去的,框架业务层和数据访问层的项目截图如下所示,业务层除了有一个BLLFactory类外,其他的类都是常规的业务处理对象,BLLFactory没有提取到公用类库,是因为需要当前执行类的一些信息来构造业务对象和数据访问对象;SqlServer数据访问层则没有任何多余的辅助类库。

       

其中SqlServer数据访问层的类,类定义的部分代码如下所示。

using WHC.Pager.Entity;
using WHC.WareHouseMis.Entity;
using WHC.WareHouseMis.IDAL;

using WHC.Framework.Commons;
using WHC.Framework.ControlUtil;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace WHC.WareHouseMis.DALSQL
{
    /// <summary>
    /// 备件信息数据访问类
    /// </summary>
    public class ItemDetail : BaseDALSQL<ItemDetailInfo>, IItemDetail
    {
               ......................

2)混合型框架的对象

在混合型框架对于WCF或者传统Winfrom数据访问中,我在其中定义了一个通用的接口层---Facade层,然后分两种实现方式,其中Facade层的接口项目文件如下所示,其中可以看到,除了CallerFactory类外,其他部分均为接口定义,基类接口已经抽取到独立的类库里面去了。

混合型框架的调用示例代码如下所示,其中和传统的Winform调用BLLFactory一样,这里只需要调用CallerFactory构造类即可,而传入给CallerFactory的是Facade层的接口,工厂会根据配置参数进行相应的对象构造,从而实现基于传统本地的数据库访问或者分布式的WCF数据访问方式的综合处理。

            bool exist = CallerFactory<IItemDetailService>.Instance.CheckExist(this.txtItemNo.Text, ID);
            if (exist)
            {
                MessageDxUtil.ShowTips("指定的备件编号已经存在,不能重复添加,请修改");
                return false;
            }

            ItemDetailInfo info = CallerFactory<IItemDetailService>.Instance.FindByID(ID);
            if (info != null)
            {

                 .....................................

其中Facade层的CallerFactory对象,会根据配置信息,寻找并构建相应的实现类,有可能是传统的数据访问类,也可能是WCF的数据访问类,这两种实现类的定义如下所示。

using WHC.WareHouseMis.Entity;
using WHC.WareHouseMis.BLL;
using WHC.WareHouseMis.Facade;

using WHC.Framework.ControlUtil;
using WHC.Framework.ControlUtil.Facade;

namespace WHC.WareHouseMis.WinformCaller
{
    public class ItemDetailCaller : BaseLocalService<ItemDetailInfo>, IItemDetailService
    {
        private ItemDetail bll = null;

        public ItemDetailCaller() : base(BLLFactory<ItemDetail>.Instance)
        {
            bll = baseBLL as ItemDetail;
        }

        #region IItemDetailService 成员

        public List<ItemDetailInfo> FindByBigType(string bigType)
        {
            return bll.FindByBigType(bigType);
        }
........................

而对于WCF方式的实现类方式如下所示

using WHC.WareHouseMis.Entity;
using WHC.WareHouseMis.Facade;
using WHC.Framework.Commons;
using WHC.Framework.ControlUtil.Facade;

namespace WHC.WareHouseMis.ServiceCaller
{
    public class ItemDetailCaller : BaseWCFService<ItemDetailInfo>, IItemDetailService
    {
        public ItemDetailCaller()  : base()
        {
            this.configurationPath = EndPointConfig.WcfConfig;
            this.endpointConfigurationName = EndPointConfig.ItemDetailService;
        }public List<ItemDetailInfo> FindByBigType(string bigType)
        {
            List<ItemDetailInfo> result = new List<ItemDetailInfo>();

            IItemDetailService service = CreateSubClient();
            ICommunicationObject comm = service as ICommunicationObject;
            comm.Using(client =>
            {
                result = service.FindByBigType(bigType);
            });

            return result;
        }
..............

4 、使用引用文件方式代替复制文件方式

在一个框架里面,为了减少程序集的数量和多个引用,可能会有多处需要使用同一个文件,这样就可以使用文件引用的方式,在VS里面添加现有文件的时候,选择

如由于我的某一个框架里面,为了减少程序集的数量,我把很多相关的类库集成在一起,形成一个单一的程序集就具有很多功能,但这样的代码虽然有很多个影子,但是肉身只有一个,方便维护。

这样对于某个文件的多处使用,但是统一维护很方便。

5、代码生成工具Database2Sharp的支持

以上的一些对象继承关系和框架的整体代码,项目工程之间程序集的引用,这些手工操作的话,肯定效率大打折扣,因此代码生成工具的支持是非常必要的工作,本框架系列的最新继承关系,全部能够使用Database2Sharp的完美支持,从而使得我们在日常开发过程中,享受快速、高效、统一的代码生成带来的乐趣。

 

 以上就是我在框架重构中的一些总结,希望能给大家有所启发,有所帮助。最后附上Winform开发框架的一个功能总结图形,Winform开发框架的主要功能概览如下图所示。

 本文转自博客园伍华聪的博客,原文链接:Winform开发框架重构总结,如需转载请自行联系原博主。



目录
相关文章
|
设计模式 算法 Java
设计模式第十五讲:重构 - 改善既有代码的设计(下)
设计模式第十五讲:重构 - 改善既有代码的设计
286 0
|
1月前
|
算法 测试技术
模块化设计具体应该怎么做呢
【10月更文挑战第22天】模块化设计具体应该怎么做呢
|
4月前
|
前端开发 Java UED
JSF 面向组件开发究竟藏着何种奥秘?带你探寻可复用 UI 组件设计的神秘之路
【8月更文挑战第31天】在现代软件开发中,高效与可维护性至关重要。JavaServer Faces(JSF)框架通过其面向组件的开发模式,提供了构建复杂用户界面的强大工具,特别适用于设计可复用的 UI 组件。通过合理设计组件的功能与外观,可以显著提高开发效率并降低维护成本。本文以一个具体的 `MessageComponent` 示例展示了如何创建可复用的 JSF 组件,并介绍了如何在 JSF 页面中使用这些组件。结合其他技术如 PrimeFaces 和 Bootstrap,可以进一步丰富组件库,提升用户体验。
56 0
|
4月前
|
前端开发 C# 设计模式
“深度剖析WPF开发中的设计模式应用:以MVVM为核心,手把手教你重构代码结构,实现软件工程的最佳实践与高效协作”
【8月更文挑战第31天】设计模式是在软件工程中解决常见问题的成熟方案。在WPF开发中,合理应用如MVC、MVVM及工厂模式等能显著提升代码质量和可维护性。本文通过具体案例,详细解析了这些模式的实际应用,特别是MVVM模式如何通过分离UI逻辑与业务逻辑,实现视图与模型的松耦合,从而优化代码结构并提高开发效率。通过示例代码展示了从模型定义、视图模型管理到视图展示的全过程,帮助读者更好地理解并应用这些模式。
102 0
|
5月前
|
开发框架 前端开发 关系型数据库
Winform开发的快速、健壮、解耦的几点建议
Winform开发的快速、健壮、解耦的几点建议
|
设计模式 Java 测试技术
设计模式第十五讲:重构 - 改善既有代码的设计(上)
设计模式第十五讲:重构 - 改善既有代码的设计
330 0
|
设计模式 IDE Java
【Java设计模式 规范与重构】 四 小型重构的手段:规范的十五条军规
【Java设计模式 规范与重构】 四 小型重构的手段:规范的十五条军规
134 0
|
程序员 测试技术
《重构2》第十章-简化条件逻辑
《重构2》第十章-简化条件逻辑
340 0
|
数据处理
《重构2》第六章-重构基础
《重构2》第六章-重构基础
308 0
|
数据格式 索引
日常开发之重构
作为开发人员,应该让重构贯穿于你的开发日常的每一刻。
351 0