美文网首页
设计模式(python实现)--模型视图控制器模式(MVC)

设计模式(python实现)--模型视图控制器模式(MVC)

作者: 远行_2a22 | 来源:发表于2020-01-31 17:24 被阅读0次

    模型-视图-控制器(Model-View-Controller,MVC)

    动机(Motivation)

    • MVC是应用到面向对象编程的Soc原则。Soc: 关注点分离(Separation of Concerns)原则思想是将一个应用切分成不同的部分,每个部分解决一个单独的关注点。

    模式定义

    模型—视图—控制器(Model-View-Controller,MVC)模式是应用到面向对象编程的Soc原则。 模式的名称来自用来切分软件应用的三个主要部分,即模型部分、视图部分和控制器部分。

    要点总结

    • MVC 被认为是一种架构模式而不是一种设计模式。架构模式与设计模式之间的区别在于前者比后者的 范畴更广。
    • MVC各部分作用为:
      (1)模型是核心的部分,代表着应用的信息本源,包含和管理(业务)逻辑、数据、状态以及应用的规则。
      (2)视图是模型的可视化表现。视图只是展示数据,并不处理数据。
      (3)控制器是模型与视图之间的链接/粘附。模型与视图之间的所有通信都通过控制器进行
    • 为什么控制器是必要的?我们能跳过它吗?能,但那样我们将失去MVC 提供的一大优势:无需修改模型就能使用多个视图的能力(甚至可以根据需要同时使用多个视图)。为了实现模型与其表现之间的解耦,每个视图通常都需要属于它的控制器。如果模型直接 与特定视图通信,我们将无法对同一个模型使用多个视图(或者至少无法以简洁模块化的方式实现)。

    MVC优点

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

    实现细节

    MVC实现基本准则

    1. 模型很智能
    • 包含所有的校验/业务规则/逻辑
    • 处理应用的状态
    • 访问应用数据(数据库、云或其他)
    • 不依赖UI
    1. 控制器很瘦
    • 在用户与视图交互时,更新模型
    • 在模型改变时,更新视图
    • 如果需要,在数据传递给模型/视图之前进行处理
    • 不展示数据
    • 不直接访问应用数据
    • 不包含校验/业务规则/逻辑
    1. 视图很傻瓜
    • 展示数据
    • 允许用户与其交互
    • 仅做最小的数据处理,通常由一种模板语言提供处理能力(例如,使用简单的变量和循环控制)
    • 不存储任何数据
    • 不直接访问应用数据
    • 不包含校验/业务规则/逻辑

    MVC检验准则

    MVC实现的对不对,好不好,检验准则为:

    • 如果应用有GUI,那它可以换肤吗?易于改变它的皮肤/外观以及给人的感受吗?可以为用户提供运行期间改变应用皮肤的能力吗?如果这做起来并不简单,那就意味着你的MVC实现在某些地方存在问题
    • 如果你的应用没有GUI(例如,是一个终端应用),为其添加GUI支持有多难?或者,如果添加GUI没什么用,那么是否易于添加视图从而以图表(饼图、柱状图等)或文档(PDF、 电子表格等)形式展示结果?如果因此而作出的变更不小(小的变更是,在不变更模型的情况下,创建控制器并绑定到视图),那你的MVC实现就需要改进。

    例子

    # -*- coding:utf-8 -*-
    
    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.')
    
    
    class QuoteModel:
        def get_quote(self, n):
            try:
                value = quotes[n]
            except IndexError as err:
                value = 'Not found!'
            return value
    
    
    class QuoteTerminalView(object):
        def show(self, quote):
            print('And the quote is: "{}"'.format(quote))
    
        def error(self, msg):
            print('Error: {}'.format(msg))
    
        def select_quote(self):
            return input('Which quote number would you like to see? ')
    
    
    class QuoteTerminalController:
        def __init__(self):
            self.model = QuoteModel()
            self.view = QuoteTerminalView()
    
        def run(self):
            valid_input = False
            while not valid_input:
                try:
                    n = self.view.select_quote()
                    n = int(n)
                    vaild_input = True
                except ValueError as err:
                    self.view.error("Incorrect index '{}'".format(n))
    
                quote = self.model.get_quote(n)
                self.view.show(quote)
    
    def main():
        controller = QuoteTerminalController()
        while True:
            controller.run()
    
    if __name__ == '__main__':
        main()
    

    输出:

    Which quote number would you like to see? 1
    And the quote is: "As I said before, I never repeat myself."
    Which quote number would you like to see? 2
    And the quote is: "Behind a successful man is an exhausted woman."
    Which quote number would you like to see? 
    
    • 模型极为简约,只有一个get_quote()方法,从quotes元组中返回对应的名人 名言(字符串)。
    • 视图有三个方法,分别是show()error()select_quote()show()用于在屏幕上输出一句名人名言;error()用于在屏幕上输出一条错误消息; select_quote()用于读取用户的选择.
    • 控制器负责协调。__init__()方法初始化模型和视图。run()方法校验用户提供的名言索引,然后从模型中获取名言,并返回给视图展示,

    相关文章

      网友评论

          本文标题:设计模式(python实现)--模型视图控制器模式(MVC)

          本文链接:https://www.haomeiwen.com/subject/lawgthtx.html