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

模型-视图-控制器(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()方法校验用户提供的名言索引,然后从模型中获取名言,并返回给视图展示,
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容