前言
通用职责分配软件模式 GRASP(General Responsibility Assignment Software Principles)是一组用于在面向对象设计中分配职责的模式。它提供了一系列关于如何在对象之间分配职责的建议,以实现高内聚和低耦合的设计。GRASP模式包括:
- 信息专家(Information Expert):将职责分配给拥有完成该职责所需信息的类。
- 创建者(Creator):将创建对象的职责分配给与该对象存在某种关系的类。
- 控制器(Controller):将处理系统事件的职责分配给表示用例场景的类或表示系统中协调者的类。
- 低耦合(Low Coupling):尽量减少类与类之间的依赖关系。
- 高内聚(High Cohesion):尽量将相关的职责分配给同一个类。
- 多态(Polymorphism):通过接口或抽象基类来定义通用行为,让子类实现具体行为。
- 纯虚构(Pure Fabrication):创建一些没有直接映射到问题域的类,以更好地实现低耦合和高内聚。
- 间接性(Indirection):通过引入间接层来降低类之间的直接依赖。
- 隔离变化(Protected Variation):设计系统时,尽量减少对变化的部分的依赖。
一、控制器模式
控制器模式
- 名称:控制器 Controller
- 应用场景:确定谁负责接收、处理和分发系统的输入事件。
- 解决方案:系统输入事件处理的职责分给控制器对象
- 一个控制器对象实现业务系统的所有输入事件处理和业务逻辑分发,这一类控制器对象称为前端控制器(Front Controller,FC)
- 不同的业务用例页面分别由不同的控制器对象实现输入事件处理和业务逻辑分发,这种类型控制器称为页面控制器(Page Controller,PC)
- 优点:降低耦合,提高复用
- 缺陷:有可能生成浮肿控制器
控制器模式补充说明
-
MVC(Model-View-Controller)是一种软件架构,用于将系统代码分为三层结构,每个层次只与相邻的层次交互:
-
Model(模型):负责管理和操作数据逻辑的部分。在Django中,模型通常是通过Python类来实现的,这些类继承自Django的
models.Model
。模型负责与数据库进行交互。 -
View(视图):负责展示给用户的数据,通常是指用户界面。在传统的MVC中,视图是负责展示模型数据的组件,并且通常不包含业务逻辑。
-
Controller(控制器):负责接收用户的输入并调用模型和视图来进行相应的更新。在MVC中,控制器是连接模型和视图的桥梁。
-
示例
Django 是一个高级的 Python Web 框架,采用了MTV分层模式。MTV(Model-Template-View)是对MVC的一种变体,本质上与MVC类似。
### models.py 对应模型层
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField("date published")
### index.html 对应视图层
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
### views.py 对应控制器层
from django.http import HttpResponse
from django.shortcuts import render
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by("-pub_date")[:5]
context = {"latest_question_list": latest_question_list}
return render(request, "polls/index.html", context)
Django的urls.py 将页面URL映射到控制器层,实现页面级别的控制器
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
]
二、多态模式
多态模式
- 名称:多态 Polymorphism
- 应用场景:如何处理依据类型不同而有不同行为的一类需求?
- 解决方案:
- 多态是指利用面向对象编程语言中的多态性模式来分配职责,以便在不同的上下文中以统一的方式处理不同类型的对象。
- 使用一个接口来表示多个不同类的行为,这样可以在不改变接口的情况下,增加新的类来扩展系统的功能。
- 优点:
- 接口一致性:多态性要求所有相关的类都实现相同的接口或继承自同一个基类,这样它们就可以在需要时相互替换。
- 封装变化:通过多态性,可以封装不同类之间的差异,使得客户端代码不必知道这些差异,从而更容易适应变化。
- 代码复用:多态性允许使用相同的代码来处理不同类型的对象,这提高了代码的复用性。
- 易于维护:由于客户端代码不需要知道具体类的细节,因此在增加新的子类时,不需要修改客户端代码。
示例
一个支付系统,原来只支持现金支付方式,现在需要扩展支付宝、微信等支付方式。即同样一项功能,原来一种处理方法就可以,现在需要适应多种处理方法,怎样的设计方案更好。
设计方案:不同的类实现了相同的接口。
Python代码实现
class Payment:
def pay(self, amount):
"""This method should be overridden by subclasses."""
raise NotImplementedError
class CashPayment(Payment):
def pay(self, amount):
print(f"Paid {amount} using cash.")
class AlipayPayment(Payment):
def pay(self, amount):
print(f"Paid {amount} using Alipay.")
class WechatPayment(Payment):
def pay(self, amount):
print(f"Paid {amount} using Wechat.")
class PaymentSystem:
"""支付系统"""
def process_pay(self, payment_method: Payment, amount):
payment_method.pay(amount)
if __name__ == "__main__":
# 创建支付系统实例
pay_sys = PaymentSystem()
# 创建不同的支付方式实例
cash_pay = CashPayment()
alipay_pay = AlipayPayment()
wechat_pay = WechatPayment()
# 处理支付
pay_sys.process_pay(wechat_pay, 100.5)
pay_sys.process_pay(alipay_pay, 50)
pay_sys.process_pay(cash_pay, 200)
### 输出结果
Paid 100.5 using Wechat.
Paid 50 using Alipay.
Paid 200 using cash.
您正在阅读的是《面向对象分析与设计Python版》专栏!关注不迷路~