跳转至

Down.NET开发总结

这次从Down用C#重写,经历了很多大坑小坑,开发过程可以说是一波三折,经过了多次大面积重构,差点把项目改崩掉,下面对这次Down.NET重写做一点复盘总结

UI库选择问题

之前在写Down的时候使用是类FlunetUI的风格写的,初次用C#开发的时候,一开始还以为WPF开发个FluentUI风格还不容易吗?结果发现还真不容易,一开始是选择WPF-UI,结果遇到一些bug,包括但不限于无法折叠导航栏,没有交互动画,没有ColorPicker等,虽然有一些问题后来也能解决,但是对于刚接触WPF开发不久的人来说,资料残缺不齐,文档写的一言难尽,无法在本地将Gallery跑起来(虽然现在还是没有跑起来)等一系列问题,最终让我对这个库有些失望。

后来想着选择WinUI看看?结果发现自己的VS没有相关的工作负载,需要吭哧吭哧的重新下载VS,可后来又遇到很多依赖问题,最终还是放弃了。

再后来选择了iNKORE.UI.WPF,虽然这个库感觉也没有好到哪里,很多效果都没有办法实现,比如下载界面的横向导航栏居中显示,没有WinUI风格的ColorPicker等,文档也同样少的可怜,一开始关于调整主题色的功能在文档中都没有,demo中也没有任何一处提及,最后还是直接问作者才知道有这回事。还有在构建gallery的时候遇到了.NET 6配置问题,可以参考这里。不过好在最后还是坚持了下来,也一点点围绕这个库设计UI界面,当然现阶段的效果和之前的那一版还有一些区别,同时还因为UI库的问题砍掉了某些功能,后续也会针对这些问题再一点点优化解决

至于MaterialDesign?呵呵,官方压根没有提供WinUI风格的导航栏,否则要自己实现,还有很多设计与WinUI不一样,所以果断放弃

.NET版本选择问题

其实一开始选择的的是.NET 4.6.2,结果因为某些配置的问题(后来发现是某个nuget包出现错误导致的),导致在.NET Framework上安装iNORE.UI.WPF的时候出现了问题,只有在.NET 6上才没有问题。

可是选择.NET 6有这几个问题:

  1. 程序体积明显变大,如果选择不带Runtime的,虽然体积是小一些,但是还得单独安装.NET runtime,有些麻烦
  2. 选择自托管的话,体积明显变大,可能还不如PyQt+pyinstaller的方案

还有在测试期间发现CPU占用莫名比较高,大概在15%左右,还有一些UI会有些细微的变化等等,导致我对选择.NET 6开发有些失望。最后解决了安装包的问题后,还是选择了.NET 4.6.2,之后又升级到.NET 4.7.2(只是单纯不想让1607系统随便运行)

总结 虽然当时项目不算很大,但是这么随便的切换.NET版本,也为后续的开发埋下了一些坑,比如迁移库,项目文件的一些问题等,所以建议先提前测试清楚后再升级或降级.NET版本,以免挖坑埋雷

重构项目问题

在开发Down.NET的时候经历了多次大面积重构,比如将每个控件的UI和ViewModel抽象成单独的类,控件的UI和任务逻辑与程序主体分离等,虽然重构后可以尽可能减少类之间的耦合度,但是发现在设计的时候也遇到了一些问题:

  1. 大量的复制粘贴、删除(因为前期没有考虑清楚基类UI和ViewModel具体要有什么,导致反反复复的复制粘贴、删除,导致好多git提交有几十个文件提交,结果发现很多文件提交就是修改了一两行的代码)
  2. 随意定义事件、变量等(虽然功能隔离是好事,但是这也会导致实现一些效果会很麻烦,比如显示一个Infobar,需要在多个文件中定义相同的event传递InfoBar的相关数据等;因着设计不当,导致定义了很多非公开变量,又反反复复删改,导致每次切换一个状态都要修改大量的变换)

总结 虽然项目需要作必要的重构,但是做重构之前也需要提前做好规划,每个项目该主要实现哪些功能,如果涉及到基类和子类,也需要提前规划好基类需要实现哪些功能,哪些功能需要推给子类实现等,以尽可能减少不必要的重复代码。还有涉及到类与类之间传递一些数据的时候,虽然用了MVVM模式,但是似乎并没有用好它,一方面是对MVVM及框架了解的不多,另一方面是图省事,只是想着快点实现好功能,导致这一部分的代码也会显得ugly,对于这个问题,近期看某些Up主的视频,发现可以利用MVVM框架提供的Messenger的通知订阅来实现,这样也可以减少一些不必要的麻烦。

不断的学习

以上提到重构代码的时候一开始遇到的一个阻力是常用软件中每个控件该如何实现对象,如果一个一个实现,这样代码很冗长,而且可维护性不高;如果使用反射,事件绑定又是一个麻烦事,而且debug也比较麻烦。后来看某个视频,发现泛型的用法,发现还有泛型约束,那么就充分利用泛型约束和类的继承的特点,利用泛型约束批量创建这十几个对象,不仅干掉了大量的重复代码,同时也通过一些设计将控件和主程序的代码隔离开

还有以上提到的定义大量的事件只是为了传递某个数据,虽然知道这样的代码可维护性不高,但是现阶段似乎没有太好的解决办法,但是通过学习发现MVVM框架有提供相关解决方案,由于近期为了加速开发进度没有引入这个技术,但是后续再做重构的时候会考虑将这个技术引入到项目中

还有TextBlock绑定后的数据显示问题等等,通过学习其他人的一些技巧,让自己的代码提高了一些可读性

AI的协助问题

在开发Down.NET的时候不免遇到一些超出已学范围的技术,这个时候通过AI的帮助,要么直接提供代码,要么提供一些思路,一方面可以加快开发效率,另一方面也能学习到未知的技术

当然了,哪怕是所谓最强的GPT-4o还是Claude3.5,在处理一些问题上也容易让人血压升高,总是文不对题,花了不少精力却得不到预期的结果,这个时候只能自行搜索答案或者自己找源码参考了

所以,对于一些比较常见的场景,用AI去提供思路或提供代码,相对还算可靠,但是如果涉及到一些偏门的需求,那么想指望AI去给出答案,多半是不大可能或者需要反反复复的调试才行。包括但不限于这个问题。还有之前在XX工具上实现的xz压缩分卷的问题,最后还是让AI先提供python的实现方案,然后再尝试改写成C#代码才勉强解决。

总结 AI有用,但不要过度依赖它

总结

限于篇幅 不想码太多字,暂时只总结这些经验,至于具体的代码设计,后续可能会再展开聊聊