Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >创建可维护和可测试的 Windows 窗体应用程序的 10 种方法(译)

创建可维护和可测试的 Windows 窗体应用程序的 10 种方法(译)

作者头像
沙漠尽头的狼
发布于 2021-12-15 08:14:18
发布于 2021-12-15 08:14:18
1.4K00
代码可运行
举报
文章被收录于专栏:Dotnet9Dotnet9
运行总次数:0
代码可运行

我遇到的大多数 Windows 窗体应用程序都不存在或单元测试覆盖率极低。而且它们通常也很难维护,项目中各种 Form 类的代码背后有数百甚至数千行代码,但它不必是这样。仅仅因为 Windows 窗体是一项“遗留”技术,并不意味着你注定会造成无法维护的混乱。下面是创建可维护和可测试的 Windows 窗体应用程序的十个技巧。

1. 用用户控件隔离你的用户界面

首先,避免在一个表单上放置太多控件。通常,你的应用程序的主要形式可以分解为逻辑区域(我们可以称之为“视图”)。如果将这些区域中的每个区域的控件放入它们自己的容器中,那么你自己的生活就会变得更加轻松,而在 Windows 窗体中,最简单的方法是使用用户控件。因此,如果你有一个资源管理器样式的应用程序,左侧是树视图,右侧是详细信息视图,则将 TreeView 放入其自己的 UserControl,并为每个可能的右侧视图创建一个 UserControl。同样,如果你有选项卡控件,请为选项卡控件中的每个页面创建一个单独的 UserControl。

这样做不仅可以防止你的类变得难以管理,而且还可以调整大小和设置Tab 键顺序等,使任务变得更加简单。它还允许你在必要时轻松地一次性禁用用户界面的整个部分。你还会发现,当你将用户界面分解为包含逻辑分组控件的较小 UserControl 时,重新设计应用程序的 UI 布局会变得更加容易。

2. 将非 UI 代码排除在后面的代码之外

在 Windows 窗体应用程序中,你总是会在窗体背后的代码中找到访问网络、数据库文件系统的代码。这严重违反了“单一责任原则”。你的 Form 或 UserControl 类的重点应该只是用户界面。因此,当你检测到背后的代码中存在与 UI 无关的代码时,请将其重构为具有单一职责的类。因此,你可以创建一个 PreferencesManager 类,或者一个负责调用特定 Web 服务的类。然后可以将这些类作为依赖项注入到你的 UI 组件中(尽管这只是第一步——我们可以进一步扩展这个想法,我们很快就会看到)。

3. 用接口创建被动视图

一种特别有用的技术是使你创建的每个窗体和用户控件都实现一个视图接口。此接口应包含允许设置和检索视图中控件的状态和内容的属性。它还可能包括报告用户交互的事件,例如单击按钮或移动滑块。目标是这些视图接口的实现是完全被动的。理想情况下,你的 Forms 和 UserControls 背后的代码中不应该有任何条件逻辑。

下面是一个用于新用户条目视图的视图接口示例。这个视图的实现应该是微不足道的。任何业务逻辑都不属于后面的代码(我们接下来将讨论它属于哪里)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
interface INewUserView
{
    string FirstName { get; set; }
    string LastName { get; set; }
    event EventHandler SaveClicked;
}

通过确保你的视图实现尽可能简单,你将能够最大程度地迁移到替代 UI 框架(如 WPF),因为你唯一需要做的就是在新技术中重新创建视图。所有其他代码都可以重复使用。

4.使用presenters控制视图

因此,如果你已将所有视图设为被动并实现接口,则你需要一些能够实现应用程序业务逻辑并控制视图的东西。我们可以称这些为“presenter”类。这是称为“模型视图演示者”或 MVP 的模式。

在模型视图展示器中,你的视图是完全被动的,展示器会指示视图显示哪些数据。还允许视图与演示者通信。在我上面的示例中,它通过引发事件来实现,但通常使用这种模式,你的视图可以直接调用演示者。

绝对不允许视图开始直接操作模型(包括你的业务实体、数据库层等)。如果你遵循 MVP 模式,你的应用程序中的所有业务逻辑都可以轻松测试,因为它位于 Presenter 或其他非 UI 类中。

5. 为错误报告创建服务

通常,你的演示者类需要显示错误消息。但不要只是将 MessageBox.Show 放入非 UI 类中。你将使该方法无法进行单元测试。而是创建一个服务(比如 IErrorDisplayService),你的演示者可以在需要报告问题时调用该服务。这使你的演示者单元保持可测试性,并且还提供了更改将来向用户呈现错误的方式的灵活性。

6. 使用命令模式

如果你的应用程序包含一个带有大量按钮供用户单击的工具栏,则命令模式可能非常适合。命令模式规定你为每个命令创建一个类。这有很大的好处,可以将你的代码分成小类,每个小类都有一个责任。它还允许你集中处理与特定命令有关的所有事情。是否应该启用该命令?它应该是可见的吗?它的工具提示和快捷键是什么?它是否需要特定的特权或许可才能执行?命令运行时抛出的异常应该如何处理?

命令模式允许你标准化处理应用程序中所有命令所共有的每个问题的方式。你的命令对象将有一个 Execute 方法,该方法实际上包含为该命令执行所需行为的代码。在许多情况下,这将涉及调用其他对象和业务服务,因此你需要将它们作为依赖项注入到命令对象中。你的命令对象本身应该可以(并且直接)进行单元测试。

7. 使用 IoC 容器管理依赖项

如果你正在使用 Presenter 类和 Command 类,那么你可能会发现它们所依赖的类的数量随着时间的推移而增长。这是Unity或StructureMap等控制反转容器真正可以帮助你的地方。无论它们具有多少级别的依赖关系,它们都允许你轻松构建视图和演示器。

8. 使用事件聚合器模式

另一种在 Windows 窗体应用程序中非常有用的设计模式是事件聚合器模式(有时也称为“信使”或“事件总线”)。这是一种模式,其中事件的引发者和事件的处理者根本不需要相互耦合。当你的代码中发生需要在其他地方处理的“事件”时,只需向事件聚合器发布一条消息即可。然后需要响应该消息的代码可以订阅和处理它,而无需担心是谁提出的。

例如,你发送一条“请求帮助”消息,其中包含用户当前在 UI 中的位置的详细信息。然后另一个服务处理该消息并确保在 Web 浏览器中启动帮助文档中的正确页面。另一个例子是导航。如果你的应用程序有多个屏幕,则可以将“导航”消息发布到事件聚合器,然后订阅者可以通过确保新屏幕显示在用户界面中来响应该消息。

除了从根本上分离事件的发布者和订阅者之外,事件聚合器还具有创建极易进行单元测试的代码的巨大好处。

9. 使用 Async 和 Await 进行线程处理

如果你的目标是 .NET 4 及更高版本并使用 Visual Studio 12 或更高版本,请不要忘记你可以使用新的 async 和 await 关键字,这将大大简化应用程序中的任何线程代码,并自动处理回送后台任务完成后进入 UI 线程。它们还极大地简化了跨多个链式后台任务的异常处理。它们非常适合 Windows 窗体应用程序,如果你还没有的话,非常值得一试。

10.不要太晚

可以将我上面描述的所有模式和技术改造为现有的 Windows 窗体应用程序,但我可以从痛苦的经验告诉你,这可能需要大量工作,尤其是当窗体背后的代码达到数千行时。如果你开始使用 MVP、事件聚合器和命令模式等模式构建应用程序,你会发现随着它们变得越来越大,维护起来会少很多痛苦。你还可以对所有业务逻辑进行单元测试,这对于持续的可维护性至关重要。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Dotnet9 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
2021年假期怎么放?都给你安排得明明白白!
来源 | Java面试那些事儿 2020年的假期莫得了, 但是2021年的给你安排得明明白白! 有休假和出行安排的看仔细了哦! Holidays 经国务院批准,现将2021年元旦、春节、清明节、劳动节、端午节、中秋节和国庆节放假调休日期的具体安排通知及请假指南如下。 一、元旦: 2021年1月1日至3日放假,共3天。 二、春节: 2月11日至17日放假调休,共7天。2月7日(星期日)、2月20日(星期六)上班。 请假指南: 2月7-10日请假4天,可连休12天; 2月18-20日请假3天,可连休11天; 三
程序猿DD
2023/04/04
4430
2021年假期怎么放?都给你安排得明明白白!
HarmonyOS NEXT 头像制作项目系列教程之 --- 数据结构设计
在开发HarmonyOS头像编辑器应用时,合理的数据结构设计是应用稳定运行的基础。本文将详细介绍头像编辑器中的数据模型设计,包括节日分类、背景图片和头像装饰图片的数据结构,以及它们之间的关联关系。通过本教程,您将了解如何构建类似的数据模型,为开发类似应用提供参考。
全栈若城
2025/05/11
520
基于百度万年历定制化 1
某门户项目需要在右上角添置一个日期(yyyy-MM-dd)的显示,同时点击此时间可以弹出一个窗体,窗体内容为万年历。 万年历需求: 1、日志显示24节气,且24节气内容可配置 2、对法定节假日可进行配置管理
happlyfox
2018/10/31
1.9K1
Python统计节假日剩余天数
Python统计节假日剩余天数 目录 1、前言 2、倒计时脚本 1、前言 如何快速的想了解距离节假日还有多少天? 接下来使用Python脚本来解决这个问题。 2、倒计时脚本 脚本代码: #!/usr/bin/env python # -*- coding: utf-8 -*- # 公众号:AllTests软件测试 from colorama import init, Fore from zhdate import ZhDate import datetime def get_week_day(date)
wangmcn
2022/07/26
6150
Python统计节假日剩余天数
『自己构建节假日API』
之前梳理了一些内置库的学习,收到了一些评论,绝大多数评论都在直指一个问题:为什么梳理这些无关痛痒的内置库?
谢伟
2018/12/19
4.4K1
手把手教你使用Python打造一款摸鱼倒计界面
你好,摸鱼人,工作再累,一定不要忘记摸鱼哦 ! 有事没事起身去茶水间去廊道去天台走走,别老在工位上坐着。多喝点水,钱是老板的,但命是自己的 !
Python进阶者
2021/12/30
7390
手把手教你使用Python打造一款摸鱼倒计界面
手把手教你开展mofish库(摸鱼库)的打包发布
前几天吴老板给我推荐了一个摸鱼库,竟然是Python库,给我惊了一下,感觉应缺斯汀。
Python进阶者
2022/03/10
4260
手把手教你开展mofish库(摸鱼库)的打包发布
从撸串说起,中国地域消费差异
我们使用 银联智惠信息服务(上海)有限公司 提供的2016年线下城市消费力大数据,对中国的地域差异进行了一个小小的研究。
IT阅读排行榜
2018/08/16
5970
从撸串说起,中国地域消费差异
iOS 工作日——过滤法定节假日日历提醒的实现
笔者五一之前补班的时候,闹钟没响,早上差点迟到了。笔者闹钟设置的是周一到周五,iPhone没有法定节假日的设置,也没有补休的设置。。。。笔者就想要解决这个痛点,梦想着,要是做出来了,发布到商店,从此走上人生巅峰,赢取白。。。。
莫空9081
2021/06/15
7K0
时间序列建模的时间戳与时序特征衍生思路
时间序列模型在我们日常工作中应用的场景还是会很多的,比如我们去预测未来的销售单量、预测股票价格、预测期货走势、预测酒店入住等等,这也是我们必须要掌握时序建模的原因。而关于时间戳以及时序值的特征衍生,在建模过程中起到的作用是十分巨大的!之前写过一篇关于日期特征操作的文章——《关于日期特征,你想知道操作都在这儿~》,可以先回顾下,里面有关于日期特征的基础操作手法。
Sam Gor
2022/02/25
1.7K0
时间序列建模的时间戳与时序特征衍生思路
春节还怕抢不到票?Github上11k star开源神器助你一臂之力
  光阴似箭,不知不觉春节将至,你准备好抢票了吗?每年的抢票大战都让人精神疲惫,手速不够只能求助黄牛。作为一名技术人员,我们也许能有更多、更好的方式去抢到票,今天博主就给大家安利一个Github上免费开源的抢票软件,助力大家春节归途!
IT学习日记
2022/09/13
8630
春节还怕抢不到票?Github上11k star开源神器助你一臂之力
用JavaScript+layui实现一个日期计算的工具
日历是我们生活中必不可少的一个东西,不管是电脑自带的日历,还是手机里面自带的,或者是家里桌面上摆放的,其实都是为了看日期,算日子,但是所有这些其实都是不具备计算日期的功能的,只是告诉你哪一天是什么节日,但是到底还有多少天可以到我们还要自己算,那么这个问题也困扰到我了,所以我决定写一个小工具,将常见的节日剩余天数计算出来,同时可以根据自己要求的日期,计算一下还有多少天,或者是一个特殊的日期已经过去了多少天,我们今天就简单的写一个这个工具!
何处锦绣不灰堆
2020/05/29
6500
java开发_中国的公历转农历_源代码
注:第二条输出记录,我们有做处理,所以输出的是当前的日期,你也可以自己写一个方法,如:oneDay(int year,int month,int day)
Hongten
2018/09/13
2.9K0
清明节,疫情下的半导体工艺行业
清明节与春节、端午节、中秋节并称为中国四大传统节日。除了中国世界上还有一些国家和地区也过清明节。
用户2760455
2022/06/06
2540
清明节,疫情下的半导体工艺行业
php获取农历日期节日
$c = new DayService(); $today=$c->convertSolarToLunar(date('Y'),date('m'),date('d')); $time ="农
IT工作者
2022/03/01
8.4K0
如何制作传统节日网站(纯HTML代码)
✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 🥇 关于作者: 💬历任研发工程师,技术组长,教学总监;曾于2016年、2020年两度荣获CSDN年度十大博客之星。 十载寒冰,难凉热血;多年过去,历经变迁,物是人非。 然而,对于技术的探索和追求从未停歇。 💪坚持原创,热衷分享,初心未改,继往开来! 一、👨‍🎓网站题目 🏮传统春节网页设计、🎅圣诞节节日发展、🥮中秋、端午传统节日习俗庆祝、🎏地区特色,网站模板 、等网站的设计与制作。 二、✍️网站描述 🏷️ 大学生传统节日网页作业成品采用DIV
IT司马青衫
2022/08/21
2.6K0
如何制作传统节日网站(纯HTML代码)
超实用!2021运营日历发布,社区活跃就靠它!
节假日到来之前,其他岗位的同事: 运营的同事: 节假日对运营人来说,正是要做活动、搞气氛、追热点、促活跃的时候,也正是最忙碌的时候。 为了在新的一年里能成为一个优雅的运营,乐乐专门整理出了2021运营日历,让腾讯乐享的社区管理员和运营者提前把握全年运营节奏,轻松策划更多精彩活动,让社区更活跃! January 2021.01 忙碌指数: 1月初,开门红 元旦刚过,迈入2021年,对很多行业来说,正是进行开门红项目的时候,也是春节前最后的业务冲刺期。通过腾讯乐享,可以助力打造氛围、赋能销售前
腾讯乐享
2021/01/15
9790
连续四年服务腾讯,点滴关怀提供有温度的员工福利数字化解决方案 | 腾讯SaaS加速器·案例库
继2016至2018年成功服务腾讯长辈关怀节后,点滴关怀2019年将继续为腾讯提供这个鹅厂全年最重要员工福利项目的全案服务。双方携手共建的一站式全案定制的节庆福利数字化解决方案,不仅持续助力腾讯的员工福利场景创新,还更将HR行政等部门人员的精力从项目执行与繁琐细节的管理,释放到增强企业雇主形象和价值观文化的场景策划上,并通过技术能力为企业福利管理进行数据赋能,和一站式、全流程、数字化的运营。 企业福利正迈向4.0时代(通常所指的1.0为线下礼品集采,2.0为发购物卡,3.0为弹性福利平台),传统方式正
腾讯SaaS加速器
2020/06/09
4.5K0
基于HTML节日主题网页项目的设计与实现——圣诞节日介绍(HTML+CSS)
✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (1000套) 】 🧡 程序员有趣的告白方式:【💌HTML七夕情人节表白网页制作 (110套) 】 🌎超炫酷的Echarts大屏可视化源码:【🔰 echarts大屏展示大数据平台可视化(150套) 】 🎁 免费且实用的WEB前端学习指南: 【📂web前端零基础到高级学习视频教程 120G干货分享】 🥇 关于作者: 💬历任研发工程师
IT司马青衫
2022/08/17
9560
基于HTML节日主题网页项目的设计与实现——圣诞节日介绍(HTML+CSS)
金融数据分析与挖掘具体实现方法 -1
关于投资的几个类别,一般我们将天使、VC、PE三个部分统称为私募(Private Equity),指的是没有在证券交易所公开上市交易的资产。
汪凡
2019/03/01
1.5K0
金融数据分析与挖掘具体实现方法 -1
推荐阅读
相关推荐
2021年假期怎么放?都给你安排得明明白白!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验