Python 接近重构

Python 接近重构,python,unit-testing,qt,refactoring,separation-of-concerns,Python,Unit Testing,Qt,Refactoring,Separation Of Concerns,我有一个非常以数据为中心的应用程序,用Python/PyQt编写。我正在计划 进行重构以真正将UI从核心中分离出来,主要是因为 目前还没有任何真正的测试,这显然必须改变 已经有了一些分离,我想我已经用正确的方式做了很多事情,但这还远远不够完美。举两个例子,告诉你什么样的事情困扰着我: 当用户右键单击数据对象的表示形式时,关联菜单 弹出窗口是由数据对象创建的,尽管此数据对象(基本上是 数据库行的ORM表示形式)显然与UI无关 当某些内容写入数据库,但写入失败时(例如,因为数据库记录被删除) 由其

我有一个非常以数据为中心的应用程序,用Python/PyQt编写。我正在计划 进行重构以真正将UI从核心中分离出来,主要是因为 目前还没有任何真正的测试,这显然必须改变

已经有了一些分离,我想我已经用正确的方式做了很多事情,但这还远远不够完美。举两个例子,告诉你什么样的事情困扰着我:

  • 当用户右键单击数据对象的表示形式时,关联菜单 弹出窗口是由数据对象创建的,尽管此数据对象(基本上是 数据库行的ORM表示形式)显然与UI无关

  • 当某些内容写入数据库,但写入失败时(例如,因为数据库记录被删除) 由其他用户锁定),向用户显示经典的“重试/中止”消息框。这 对话框是由数据提供程序*创建的,尽管该提供程序显然不应具有任何UI功能。 显然,提供程序可以引发异常或以其他方式指示失败,UI可以捕获 这样做并据此采取行动

    *我用这个词来表示对象,它基本上表示一个数据库表并进行调解 在其数据对象和数据库引擎之间;我不确定这是否是通常所说的 “提供者”

我没有测试方面的经验,所以我不容易“感觉”到可测试性问题或类似的问题,但在我开始之前,必须进行一些重组

没有涉及复杂的业务逻辑(主要是CRUD,是的,即使没有D),这将比重写更复杂,因此我并不真正关心引入中讨论的回归bug

我的计划是开始重构时要记住,用户界面部分可以很容易地被拆掉,然后重新组装 用web前端或基于文本的界面代替Qt界面。另一方面 Qt本身仍然会被内核使用,因为很多地方都使用了信号/插槽机制, e、 g.数据对象发出一个
changed
信号来表示,你知道的


所以,我的问题是:这是提高可测试性和可维护性的可行方法吗?还有其他评论,特别是关于Python的吗?

如果您还没有这样做,请阅读Michael Feathers的“有效地使用遗留代码”—它正好处理这种情况,并提供了大量处理这种情况的技术


他提出的一个关键点是在重构之前尝试进行一些测试。因为它不适合单元测试,所以尝试进行一些端到端测试。我相信Qt有自己的测试框架来驱动GUI,所以添加测试,根据已知数据库操作GUI并验证结果。清理代码时,可以使用单元测试替换或增加端到端测试。

如果要从所有其他部分提取应用程序的所有GUI部分以测试所有应用程序,应该使用模型视图演示器:您可以找到一些解释和说明

使用此模型,应用程序的所有服务都使用演示者,而只有用户可以直接与视图(GUI部分)交互。演示者正在管理应用程序中的视图。在需要修改GUI框架的情况下,您将拥有一个独立于应用程序的GUI部件。您只需修改演示者和视图本身

对于您想要的GUI测试,您只需为演示者编写。如果您想测试GUI的使用,您需要创建


希望有帮助

以前,我曾针对UI/后端分离对大型遗留代码进行过重构。这既有趣又有意义

/赞扬;)

无论我们称之为什么模式,或者是MVC的一部分,拥有一个非常清晰的API层是非常宝贵的。如果可能,您可以通过调度器路由所有UI请求,该调度器将为您提供对UILogic通信的更大控制,例如实现缓存、身份验证等

要可视化:

[QT Frontend]
[CLIs]             <=======> [Dispatcher] <=> [API] <==> [Core/Model]
[SOAP/XMPRPC/Json]
[API Test Suite]
[QT前端]
[CLIs][Dispatcher][API][Core/Model]
[SOAP/XMPRPC/Json]
[API测试套件]
这边

  • 添加测试套件来测试API更容易
  • 此外,它还使添加UI的方式更加统一和简单
  • API文档:如果您想通过一些RPC接口来记录和公开API,那么生成API文档就更容易了。 如果有人不同意API文档的重要性,可以随时查看Twitter API,看看它是否成功
  • 您可以快速地将API层导入python shell并使用它
API设计可以在开始为API层编码之前进行。根据应用程序的不同,您可能需要zinterfaces等软件包的帮助。 这是我在编写非常小的应用程序时采取的一般方法,对我来说从未失败过

看看

这种方法的一个明显优点是,在拥有API层和新UI之后,现在可以返回到遗留代码,并用可能更小的步骤修复/重构它


其他建议是准备好测试套件。请参见interstar的建议。

一点,到目前为止还没有提到,也没有真正回答这个问题,但非常重要的一点是:只要有可能,您应该在开始重构之前立即进行测试。测试的要点是检测你是否弄坏了什么东西

重构是一种非常有价值的方法,可以准确地看到某些操作的效果在哪里发生了变化,以及相同的调用在哪里产生了不同的结果。这就是所有这些测试的目的:你想看看你是否破坏了某些东西,你想看到所有无意的改变

因此,现在对所有在refa后仍应产生相同结果的部件进行测试