目前的局限性
目前状态下的应用有两个基本问题。 如果你观察应用的组织方式,你会注意到有几个不同的子系统可以被识别,但支持它们的代码都混合在了一起,没有任何明确的界限。 我们来回顾一下这些子系统是什么:
- 用户认证子系统,包括 app/routes.py 中的一些视图函数, app/forms.py 中的一些表单, app/templates 中的一些模板以及*app/email.py 中的电子邮件支持。
- 错误子系统,它在 app/errors.py 中定义了错误处理程序并在 app/templates 中定义了模板。
- 核心应用功能,包括显示和撰写用户动态,用户个人主页和关注以及用户动态的实时翻译,这些功能遍布大多数应用模块和模板。
思考这三个子系统以及它们组织的方式,你可能会注意到这样一个模式。 到目前为止,我一直遵循的组织逻辑是不同的应用功能归属到其专属的模块。 这些模块之中,一个用于视图函数,一个用于 Web 表单,一个用于错误,一个用于电子邮件,一个目录用于存放 HTML 模板等等。 虽然这是一个对小项目有意义的组织结构,但是一旦项目开始增长,它往往会使其中的一些模块变得非常大而且杂乱无章。
要想清晰地看到问题的一种方法,是思考如何通过尽可能多地重复使用这一项目来开始第二个项目。 例如,用户身份验证部分应该在其他应用中也能运行良好,但如果你想按原样使用该代码,则必须进入多个模块并将相关部分复制/粘贴到新项目的新文件中。 看到这是多么不方便了吗? 如果这个项目将所有与认证相关的文件从应用的其余部分中分离出来,会不会更好? Flask 的 blueprints 功能有助于实现更实用的组织结构,从而更轻松地重用代码。
还有第二个问题,虽然它不太明显。 Flask 应用实例在 app/__init__.py
中被创建为一个全局变量,然后又被很多应用模块导入。 虽然这本身并不是问题,但将应用实例作为全局变量可能会使某些情况复杂化,特别是与测试相关的情景。 想象一下你想要在不同的配置下测试这个应用。 由于应用被定义为全局变量,实际上没有办法使用不同配置变量来实例化的两个应用实例。 另一种糟心的情况是,所有测试都使用相同的应用,因此测试可能会对应用进行更改,就会影响稍后运行的其他测试。 理想情况下,你希望所有测试都在原始应用实例上运行的。
你可以在 tests.py 模块中看到我正在使用的应用实例化之后修改配置的技巧,以指示测试时使用内存数据库而不是默认的 SQLite 数据库。我真的没有其他办法来更改已配置的数据库,因为在测试开始时已经创建和配置了应用。 对于这种特殊情况,对已配置的应用实例修改配置似乎可以运行,但在其他情况下可能不会,并且在任何情况下,这是一种不推荐的做法,因为这么做可能会导致提示晦涩并且难以找到 BUG。
更好的解决方案是不将应用设置为全局变量,而是使用 应用工厂 函数在运行时创建它。 这将是一个接受配置对象作为参数的函数,并返回一个配置完毕的 Flask 应用实例。 如果我能够通过应用工厂函数来修改应用,那么编写需要特殊配置的测试会变得很容易,因为每个测试都可以创建它各自的应用。
在本章中,我将通过为上面提到的三个子系统重构应用来介绍 blueprints。 展示更改的详细列表有些不切实际,因为几乎应用中每个文件都有少许变化,所以我将讨论重构的步骤,然后你可以 下载 更改后的应用。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论