我正在开发一个以 WinForms 风格开发的 Wpf 应用程序;我这样说是因为应用程序包括 -
- UserControls 具有超过 2000 行代码(没有任何区域,成员分散在类中)。没有任何关注点分离。
- UserControls 有大约 1000 行代码,相应的 ViewModel 有另外 1000 行代码。
- UserControls 具有大量事件处理程序(有些超过 25 个)。
- 具有嵌套类的用户控件。
- 实现 INotifyPropertyChanged 并具有 DP 的用户控件。
- 大量未使用的类/代码(虽然在代码中引用/使用但没有执行任何操作);
- 超过 30 个多值转换器和 40 个值转换器。
- 转换器实例在代码隐藏/VM 中经常使用。
- 很少有多值转换器
- 拥有数百行代码(很少有多达 400 行代码)。
- 内部有业务逻辑。
- 创建 ViewModel 实例。
- 具有嵌套类。
- 在隐藏代码中公开用户控件使用的方法。
- 公开代码隐藏和 View 模型中用户控件使用的属性。
- 具有返回可观察集合/列表的静态方法,供其他转换器和 View 模型使用。
- 公开由 UserControl 和 View 模型订阅的事件。
- 实现 IDisposable。
- 转换器广泛用于创建/设置控件/ListViews/DataGrid 的 DataContext 和 ItemSource:
像这样-
<Editor:EditorControl.DataContext>
<MultiBinding Converter="{StaticResource EditorControlModelConverter}">
<Binding
ElementName="UserControl"
Path="RefId" />
<Binding
ElementName="UserControl"
Path="CollectionView.SelectedScenario" />
<Binding
ElementName="UserControl"
Path="ParentComponentName" />
</MultiBinding>
</Editor:EditorControl.DataContext>
还有这个 -
<ListView.ItemsSource>
<MultiBinding Converter="{StaticResource ItemsSourceInsertConverter}">
<Binding
ElementName="EditorControl"
Path="EditorControl.ContextListEnabled" />
<Binding
ElementName="EditorControl"
Path="EditorContainer.ParentComponent.Model.ModelList" />
<Binding
ElementName="EditorControl"
Path="EditorContainer.ParentComponent.Model.CategoryModelList" />
<Binding
ElementName="EditorControl"
Path="EditorContainer.ParentComponent.Model.ItemSortOrder" />
<Binding
ElementName="EditorControl"
Path="IsItemSourceMatrixInsertConverterSuspended" />
<Binding
ElementName="EditorControl"
Path="EditorControlModel.IsUpdating" />
<Binding
ElementName="EditorControl"
Path="EditorControlModel.ContextListEnabledInitialized" />
<Binding
BindsDirectlyToSource="true"
ElementName="listView" />
<Binding
ElementName="EditorControl"
Path="EditorControlModel" />
<Binding
ElementName="EditorControl"
Path="EditorContainer.Plugin.FeatureManager.EditorCategoryFeatureEnabled" />
<Binding
ElementName="EditorControl"
Path="EditorContainer.Plugin.FeatureManager.EditorMatrixFeaturesEnabled" />
</MultiBinding>
名单还在继续...你们中有人遇到过类似的情况吗?您是如何处理的?应采取什么方法来重构此类应用程序以获得更好的性能和可维护性?
<小时/>更新:
安德鲁问题的答案 - “为什么我们需要重构这个”:
性能 - 我们对应用程序的性能不满意,认为它应该更好(考虑到功能和可用性)。
更好的可扩展性:我们的产品仍处于早期阶段,并且知道将来需要添加很多新功能;但看看当前的代码库,它看起来很困难,并且可能会破坏旧功能。
更好的可维护性:将来维护不符合标准/棘手/hacky 的代码将很困难(这非常重要,因为我们看到该产品将在未来几年运行)。
<
最佳答案
我会问一个问题为什么你需要重构这个?如果答案是“所以它符合标准”、“它看起来更好”或“所以我们的开发团队很高兴”那么我会认真地重新考虑这样做。
如果答案是“因为我们无法满足业务需求,因为更改/更新我们的应用程序很困难”,那么您就有正当的业务理由。
我参与过许多项目,我的第一 react 就是废弃并重写它。我所做的许多内容实际上是废弃和重写的,只是到了一半才发现原来的开发人员,虽然他们没有按照我的方式去做(甚至编码标准很差),但他们已经解决了很多我想要的问题从来没有考虑过!
类似地,我也曾从事过一两个项目,其中重写或深度重构具有很强的商业原因,并且结果是成功的。然而,做出这些改变总是很痛苦的。
所以。总之,如果由于强烈的业务需求而必须这样做,我可能会首先创建一个测试脚本(手动测试)或更佳的自动化测试(UI 或 UNIt 测试,无所谓),粗略地测试以下功能:你的申请。
然后我会依次获取 View 并为它们创建 ViewModel,将功能移至 ViewModel。例如,将依赖项属性和 INotifyPropertyChanged 移动到 VM。
然后我会看看依赖注入(inject),例如StructureMap 将所需的依赖关系连接到这些 View 模型中或使用其他一些方法来保持低耦合。
书中概述了这些技术和其他技术,Brownfield Application Development in .NET 。
最后,我会自豪地回顾我漂亮的代码,它完成了旧应用程序一半的功能。玩笑!好吧,最后一部分很有趣,我确实认为有很多原因可以解释为什么这是一件非常好的事情(重构),但是我从痛苦的经验中学到了不要轻易做出这些决定。
最诚挚的问候!
关于.net - 如何重构/重建以 WinForms 风格开发的 WPF 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8645841/