如何重构/重建以WinForms风格开发的WPF应用程序

akj*_*shi 4 .net wpf performance refactoring winforms

我正在开发一个以WinForms风格开发的Wpfapplication; 我这样说是因为申请包括 -

  • UserControls拥有超过2000行代码(没有任何区域,成员遍布全班).没有任何关注的分离.
  • UserControls有大约1000行代码和相应的ViewModel有另外1000行代码.
  • UserControls有很多事件处理程序(有些> 25).
  • UserControls具有嵌套类.
  • UserControls实现INotifyPropertyChanged并具有DP.
  • 很多未使用的类/代码(尽管在代码中引用/使用但没有做任何事情);
  • 超过30个MultiValue转换器和40个值转换器.
  • 转换器实例经常用在/ VM后面的代码中.
  • 很少有MultiValue转换器
    • 拥有数百行代码(很少有400行代码).
    • 在他们内部有业务逻辑.
    • 创建ViewModel实例.
    • 拥有嵌套类.
    • 暴露用户控件在后面的代码中使用的方法.
    • 公开用户控件在后面的代码和视图模型中使用的属性.
    • 使用静态方法返回可观察的集合/列表,由其他转换器和视图模型使用.
    • 暴露事件,由UserControl和视图模型订阅.
    • 实现IDisposable.
  • 转换器广泛用于创建/设置控件/ ListViews/DataGrids的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>
Run Code Online (Sandbox Code Playgroud)

还有这个 -

<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>
Run Code Online (Sandbox Code Playgroud)

列表继续......你们中的任何一个人是否面临过类似的情况以及你们是如何处理的?应该采用什么方法来重构这种应用程序以获得更好的性能和可维护性?


更新:

答案安德鲁的Q - "为什么我们需要重构这个":

  1. 性能 - 我们对应用程序的性能不满意,并认为应该更好(考虑功能和可用性).

  2. 更好的可扩展性:我们仍然处于产品的早期阶段,并且知道将来需要添加许多新功能; 但是看看当前的代码库,它看起来很难,可能会破坏旧的功能.

  3. 更好的可维护性:将来很难维护一个不符合标准的/棘手的/ hacky代码(因为我们看到这个产品将在未来几年内运行,因此非常有用).

Dr.*_*ABT 5

我问这个问题为什么你需要重构这个?如果答案是"所以它的标准符合","它看起来更好"或"所以我们的开发团队很高兴"然后我会认真考虑这样做.

如果答案是"因为我们无法满足因更改/更新我们的应用程序而导致的业务需求",那么您就有了正当的商业理由.

我参与了许多项目,我的第一直觉是废弃并重写它.我做过的其中许多实际上都是废弃和重写,只是为了找出原始开发人员的一半,而他们没有像我那样(或者甚至编码标准很差)这样做已经解决了很多问题我已经解决了很多问题.从未考虑过!

同样地,我已经在一两个工作,其中重写或深度重构具有强大的商业理由,结果是成功的.然而,做出这些改变总是很痛苦.

所以.总之,如果由于强大的业务需求而必须这样做,我可能会首先创建一个测试脚本(手动测试)或更好的自动化测试(UI或UNit测试,无关紧要),这些测试粗略地测试了你的申请.

然后我将依次获取Views并为它们创建ViewModel,将功能移至ViewModels.例如,将依赖项属性和INotifyPropertyChanged移动到VM.

然后,我将查看依赖注入,例如StructureMap,以将这些视图模型中所需的依赖关系或其他一些方法连接起来以保持低耦合.

这些技术和其他技术在.NET中的Brownfield Application Development一书中有所概述.

最后,我会回顾一下我的漂亮代码的荣耀,该代码执行旧应用程序所做的一半功能.玩笑!好吧,这最后一部分很有意思,我认为有很多理由说明这是一件非常好的事情(重构),但是我从痛苦的经历中学到了不轻易做出这些决定.

最好的祝福!