模型-视图-控制器模式
关注点分离(Separation of Concerns,SoC)原则是软件工程相关的设计原则之一。SoC原则背后的思想是将一个应用切分成不同的部分,每个部分解决一个单独的关注点。分层设计中的层次(数据访问层、业务逻辑层和表示层等)即是关注点的例子。使用SoC原则能简化软件应用的开发和维护(请参考网页[t.cn/RqrjewK])。
模型—视图—控制器(Model-View-Controller,MVC)模式是应用到面向对象编程的Soc原则。模式的名称来自用来切分软件应用的三个主要部分,即模型部分、视图部分和控制器部分。MVC被认为是一种架构模式而不是一种设计模式。架构模式与设计模式之间的区别在于前者比后者的范畴更广。然而,MVC太重要了,不能仅因为这个原因就跳过不说。即使我们从不需要从头实现它,也需要熟悉它,因为所有常见框架都使用了MVC或者是其略微不同的版本(之后会详述)。
模型是核心的部分,代表着应用的信息本源,包含和管理(业务)逻辑、数据、状态以及应用的规则。视图是模型的可视化表现。视图的例子有,计算机图形用户界面、计算机终端的文本输出、智能手机的应用图形界面、PDF文档、饼图和柱状图等。视图只是展示数据,并不处理数据。控制器是模型与视图之间的链接/粘附。模型与视图之间的所有通信都通过控制器进行(请参考[GOF95,第14页]、网页[t.cn/RqrjF4G]和网页[t.cn/RPrOUPr])。
对于将初始屏幕渲染给用户之后使用MVC的应用,其典型使用方式如下所示:
用户通过单击(键入、触摸等)某个按钮触发一个视图
视图把用户操作告知控制器
控制器处理用户输入,并与模型交互
模型执行所有必要的校验和状态改变,并通知控制器应该做什么
控制器按照模型给出的指令,指导视图适当地更新和显示输出
## 如下所示为来自于github的示例代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class Model(object):
def __iter__(self):
raise NotImplementedError
def get(self, item):
"""Returns an object with a .items() call method
that iterates over key,value pairs of its information."""
raise NotImplementedError
@property
def item_type(self):
raise NotImplementedError
class ProductModel(Model):
class Price(float):
"""A polymorphic way to pass a float with a particular __str__ functionality."""
def __str__(self):
first_digits_str = str(round(self,2))
try:
dot_location = first_digits_str.index('.')
except ValueError:
return (first_digits_str + '.00')
else:
return (first_digits_str +
'0'*(3 + dot_location - len(first_digits_str)))
products = {
'milk': {'price': Price(1.50), 'quantity': 10},
'eggs': {'price': Price(0.20), 'quantity': 100},
'cheese': {'price': Price(2.00), 'quantity': 10}
}
item_type = 'product'
def __iter__(self):
for item in self.products:
yield item
def get(self, product):
try:
return self.products[product]
except KeyError as e:
raise KeyError((str(e) + " not in the model's item list."))
class View(object):
def show_item_list(self, item_type, item_list):
raise NotImplementedError
def show_item_information(self, item_type, item_name, item_info):
"""Will look for item information by iterating over key,value pairs
yielded by item_info.items()"""
raise NotImplementedError
def item_not_found(self, item_type, item_name):
raise NotImplementedError
class ConsoleView(View):
def show_item_list(self, item_type, item_list):
print(item_type.upper() + ' LIST:')
for item in item_list:
print(item)
print('