行为型--MVC模式

什么是模型-视图-控制(MVC)模型


在介绍模型-视图-控制(Model-View-Controller,MVC)模型之前,我们先介绍一个概念:关注点分离原则
关注点分离原则(Separation of Concerns, SoC) 是软件工程相关的设计原则之一。 SoC原则背后的思想是将一个应用切分成不同的部分,每个部分只负责解决自身问题。分层设计中的层(数据访问层、业务逻辑层和表示层等)即是关注点。

MVC模式: 又叫做 模型–视图–控制,是 SoC原则 在面向对象中的实现。MVC 也被广泛称之为架构模式;MVC 意为把组织分为三个部分:模型部分视图部分控制器

  • 模型 :是组织的核心部分,负责访问数据,管理应用状态;
  • 视图 :是 模型 的外在表现,提供展示和交互功能;不涉及到对数据的处理,例如用户的操作界面;
  • 控制器 :是 模型视图 的连接器,模型视图 通过 控制器 进行通信;每个视图应该有一个与之匹配的控制器;控制器 使得 模型视图 可以解耦;

三者之间的关系如下图所示:

在这里插入图片描述


MVC 模型的应用场景


在实际的使用过程中,Web 框架 Web2py 就是一个支持 MVC 模式的轻量级 Python 框架。Django 也是一个 MVC 框架。不过稍有不同,控制器 被称为 视图视图 被称为 模板。 Django使用名称 模型—模板—视图( Model-Template-View, MTV)来替代MVC。MVC 模型的使用适合以下场景:

  • 视图模型 的分离允许美工一心搞 UI8部分,程序员一心搞开发,不会相互干扰。
  • 由于 视图模型 之间的松耦合,每个部分可以单独修改/扩展,不会相互影响。例如,添加一个新视图的成本很小,只要为其实现一个 控制器 就可以了。

MVC 模型的优点


  1. MVC 模型最大的优点就是 松耦合视图模型松耦合,每一个部分可以单独的修改和扩展,不会相互影响。
  2. 无需修改模型,就可以实现多个视图 连接同一个 模型,因为每一个 视图 都有一个与之相应的 连接器连接器 通常被设计成规模瘦小。如下图所示:

在这里插入图片描述


使用 MVC 模型的注意事项


在从头开始实现 MVC 时,请确保创建的 模型很智能视图很傻瓜控制器很瘦

  • 模型很智能 的原则为:
    • 包含所有业务规则和逻辑;
    • 处理应用的状态;
    • 访问应用数据(包括数据库、云);
    • 不依赖 UI;
  • 视图很傻瓜 的原则为:
    • 展示数据;
    • 运行用户与其交互;
    • 仅做最小的数据处理;
    • 不存储任何数据;
    • 不能直接访问数据;
    • 不包含业务规则和逻辑;
  • 控制器很瘦 的原则为:
    • 在运行过程中,可以更新视图和模型;
    • 如果需要,在数据传递给模型和视图之前进行处理;
    • 不展示数据;
    • 不直接访问应用数据;
    • 不包含业务规则和逻辑;

MVC 模型的例子


利用 MVC 模型实现一个搜索并显示名人名言的应用。想法很简单:用户输入一个数字,然后就能看到与这个数字相关的名人名言。
在这个应用中,涉及到三个类:模型类视图类连接器类;三者的组织关系如下所示:


模拟数据库

名人名言存储在一个 quotes 元组中。这种数据通常是存储在数据库、文件或其他地方,只有模型能够直接访问它。

# 模拟数据库
quotes = ('A man is not complete until he is married. Then he is finished.',
          'As I said before, I never repeat myself.',
          'Behind a successful man is an exhausted woman.',
          'Black holes really suck...', 'Facts are stubborn things.')

模型-视图-控制器设计


- 模型极为简约,只有一个 `get_quote()` 方法,基于索引n从quotes元组中返回对应的名人名言(字符串); - 视图有三个方法,分别是 `select_quote()、show()、 error()`。 - `select_quote()` 用于读取用户的选择; - `show()` 用于在屏幕上输出一句名人名言(或者输出提示信息 `Not found`!); - `error()` 用于在屏幕上输出一条错误消息; - 控制器负责协调。 - ` __init__()` 方法初始化模型和视图。 - `run()` 方法校验用户提供的名言索引,然后从模型中获取名言,并返回给视图展示;

具体代码如下所示:

# 模型
class QuoteModel:

    # 从数据库中读取名人名言
    def get_quote(self, n):
        try:
            value = quotes[n]
        except IndexError as err:
            value = 'Not found!'
        return value

# 视图
class QuoteTerminalView:

    # 选择名人名言
    def select_quote(self):
        return input('Which quote number would you like to see?')

    # 显示名人名言
    def show(self, quote):
        print('And the quote is: "{}"'.format(quote))

    # 显示错误
    def error(self, msg):
        print('Error: {}'.format(msg))

# 控制器
class QuoteTerminalController:

    def __init__(self):
        self.model = QuoteModel() # 模型实例
        self.view = QuoteTerminalView() # 视图实例

    def run(self):
        valid_input = False

        # 调用视图模型获取用户选择
        while not valid_input:
            n = self.view.select_quote() # 提供交互
            try:
                n = int(n)
            except ValueError as err:
                self.view.error("Incorrect index '{}'".format(n))
            else:
                valid_input = True

        # 把数据传递给模型
        quote = self.model.get_quote(n)

        # 视图显示数据
        self.view.show(quote)

应用上述代码

def main():
    controller = QuoteTerminalController()
    while True:
        controller.run()

if __name__ == '__main__':
    main()

源码在这里


参考资料


  1. 《精通Python设计模式》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值