行为型模式-策略模式和责任链模式对比

2023-09-18 14:53:36

一、区别:

  1. 目的和问题解决方式

    • 策略模式的主要目的是将一组算法或行为封装成独立的策略对象,并使客户端能够在运行时选择其中一个策略来执行。这种模式通常用于实现相同操作的不同算法或策略之间的切换和替换。
    • 责任链模式的主要目的是将请求的发送者和接收者解耦,允许多个对象依次处理请求,直到其中一个对象能够处理请求为止。责任链模式通常用于创建一个处理请求的对象链,每个对象都尝试处理请求,如果它不能处理,则将请求传递给下一个对象,以此类推,直到找到一个合适的处理者。
  2. 参与者

    • 策略模式通常涉及两个主要参与者:上下文(Context)和策略(Strategy)。上下文是客户端与策略对象交互的接口,策略是实际执行的算法或行为的接口。
    • 责任链模式涉及多个处理器或处理者对象,它们组成一个链。每个处理器都有一个处理请求的方法,并且知道下一个处理者是谁。请求从链的开头传递到链的末尾,直到有一个处理者处理它或者请求到达链的末尾。
  3. 关注点

    • 策略模式关注于选择不同的算法或策略来完成特定的任务,强调了替代性。
    • 责任链模式关注于将请求沿着链传递,并由适当的处理者处理,强调了请求的传递和处理。
  4. 适用场景

    • 策略模式适用于需要在运行时动态选择算法或策略的情况,以及避免使用大量的条件语句来实现不同行为的情况。
    • 责任链模式适用于具有多个对象处理请求的情况,每个对象可以决定是否处理请求,以及如何传递请求,例如日志记录、异常处理等场景。

总的来说,策略模式用于选择不同的策略或算法,而责任链模式用于将请求传递给一系列对象,直到找到一个合适的处理者。它们解决不同类型的问题,根据具体情况选择合适的模式来实现更清晰和可维护的代码。
 

我们通过具体的示例来说明策略模式和责任链模式的区别。

二、策略模式示例

假设你正在开发一个电商网站,需要计算商品的折扣价格。不同类型的商品可以有不同的折扣策略,例如普通商品按原价销售,VIP用户享受9折优惠,促销商品打7折,以及其他可能的折扣策略。

策略模式代码示例:
# 抽象策略接口
class DiscountStrategy:
    def apply_discount(self, original_price):
        pass

# 具体策略类
class RegularCustomerDiscount(DiscountStrategy):
    def apply_discount(self, original_price):
        return original_price

class VipCustomerDiscount(DiscountStrategy):
    def apply_discount(self, original_price):
        return original_price * 0.9

class SaleDiscount(DiscountStrategy):
    def apply_discount(self, original_price):
        return original_price * 0.7

# 上下文类
class ShoppingCart:
    def __init__(self, discount_strategy):
        self.discount_strategy = discount_strategy

    def checkout(self, cart_total):
        return self.discount_strategy.apply_discount(cart_total)

# 客户端代码
cart_total = 100.0
regular_customer = ShoppingCart(RegularCustomerDiscount())
vip_customer = ShoppingCart(VipCustomerDiscount())
sale = ShoppingCart(SaleDiscount())

print("Regular customer total:", regular_customer.checkout(cart_total))
print("VIP customer total:", vip_customer.checkout(cart_total))
print("Sale total:", sale.checkout(cart_total))

在这个例子中,策略模式允许你在运行时选择不同的折扣策略,而不需要修改购物车类。

三、责任链模式示例

现在,假设你的电商网站需要一个日志记录系统,可以根据不同的日志级别将日志消息传递给不同的日志处理器。日志级别包括DEBUG、INFO、WARNING和ERROR,每个级别都有不同的处理方式,例如将DEBUG级别的日志保存到文件,将ERROR级别的日志发送给管理员。

责任链模式代码示例:
# 抽象处理器接口
class Logger:
    def set_next(self, next_logger):
        pass

    def log_message(self, level, message):
        pass

# 具体处理器类
class DebugLogger(Logger):
    def set_next(self, next_logger):
        self.next_logger = next_logger

    def log_message(self, level, message):
        if level == "DEBUG":
            print(f"Debug Log: {message}")
        elif self.next_logger:
            self.next_logger.log_message(level, message)

class InfoLogger(Logger):
    def set_next(self, next_logger):
        self.next_logger = next_logger

    def log_message(self, level, message):
        if level == "INFO":
            print(f"Info Log: {message}")
        elif self.next_logger:
            self.next_logger.log_message(level, message)

class ErrorLogger(Logger):
    def set_next(self, next_logger):
        self.next_logger = next_logger

    def log_message(self, level, message):
        if level == "ERROR":
            print(f"Error Log: {message}")
        elif self.next_logger:
            self.next_logger.log_message(level, message)

# 客户端代码
debug_logger = DebugLogger()
info_logger = InfoLogger()
error_logger = ErrorLogger()

debug_logger.set_next(info_logger)
info_logger.set_next(error_logger)

debug_logger.log_message("DEBUG", "This is a debug message.")
debug_logger.log_message("INFO", "This is an info message.")
debug_logger.log_message("ERROR", "This is an error message.")

在这个例子中,责任链模式允许你将日志消息传递给一系列不同的日志处理器,每个处理器决定是否处理消息,以及如何处理。如果某个处理器无法处理消息,它将消息传递给下一个处理器,直到找到合适的处理者。这种方式可以实现灵活的日志记录系统,而不需要修改已有的代码。

总结:策略模式用于选择不同的策略来处理不同的情况,而责任链模式用于将请求传递给一系列处理器,直到找到一个合适的处理者,有点像击鼓传花。

更多推荐

新款 锐科达 SV-2402VP SIP广播音频模块 支持RTP流音频广播

新款锐科达SV-2402VPSIP广播音频模块支持RTP流音频广播SV-2402VP网络音频模块是一款通用的独立SIP音频功能模块,可以轻松地嵌入到OEM产品中。该模块对来自网络的SIP协议及RTP音频流进行编解码。该模块支持多种网络协议和音频编解码协议,可用于VoIP和IP寻呼以及高质量音乐流媒体播放等应用。同时,S

数字孪生在灌区信息中的应用

灌区信息是智慧水利的组成部分,对灌区现代化改造的支撑作用和地位尤为重要,对促进水利可持续发展有重要意义。灌区信息化系统主要对对灌区的水情、雨情、土壤墒情、气象等信息进行监测,对重点区域进行视频监控,同时对泵站、闸门进行远程控制,实现了信息的测量、统计、分析、控制、调度等功能。为灌区管理部门科学决策提供了依据,提升灌区的

TCP并发服务器的多进程实现与多线程实现

TCP并发服务器的多进程实现与多线程实现一、TCP并发服务器的多进程实现代码#include<my_head.h>#defineSERVER_IP"192.168.125.11"//服务器IP#defineSERVER_PORT6666//服务器端口//子进程处理客户端信息函数intdeal_client_messag

小插曲 -- 使用Linux编写 判断程序是否在运行的小程序

编写思路首先,在执行“ps-elf|grepxxx”时,如果xxx存在,通常会有两条结果,一个是xxx对应的PID,一个则是grep对应的PID,但是如果我希望执行命令后,xxx存在就只有xxx对应的PID,不存在就什么都不显示的话,可以将指令修改成:“ps-elf|grepXXX|grep-vgrep”,这样就可以屏

雷电9模拟器抓包

背景本人一开始使用fiddler,然后使用wireshark。然后一直没能成功对雷电9完成JDapp的抓包任务,后来发现一款新产品Reqable,实现了JD请求抓包。思路经过查找资料,我发现核心思路都相差不大,基本使用模拟器wifi代理+证书的形式,把同一局域网下的请求由本地端口代理,再通过工具进行抓包。实战本文以Re

有多条业务线,mysql建多库多表比较好还是一个库多个表比较好呢?

这个问题的答案取决于您的具体需求。以下是一些需要考虑的因素:数据独立性:如果您的业务线之间的数据是独立的,并且不太可能需要进行跨业务线的查询,那么将它们分成多个数据库可能是有意义的。这样可以使每个业务线的数据更加独立,减少潜在的冲突和竞态条件。查询性能:在某些情况下,将数据分为多个表可能会提高查询性能。例如,如果您的数

Qt(day5)

思维导图将登录操作和数据库绑定mywnd.h#ifndefMYWND_H#defineMYWND_H#include<QMainWindow>#include<QLabel>#include<QLineEdit>#include<QPushButton>#include<QDebug>#include<QMessage

程序人生,中秋共享

程序人生,中秋共享随着科技的迅速发展,中秋节也悄然发生了变化。在这个传统的团圆节日里,程序人生与中秋共享形成了新的气象。在本文中,我将结合自己的职业经历,探讨程序人生与中秋共享之间的联系与意义。【中秋与程序人生的交融】作为程序员,我们每天都在和代码打交道,通过一行行指令来构建世界。然而,在这个机械化的过程中,我们也不忘

LLM预训练之RLHF(一):RLHF及其变种

在ChatGPT引领的大型语言模型时代,国内外的大模型呈现爆发式发展,尤其是以年初的LLaMA模型为首的开源大模型和最近百川智能的baichuan模型,但无一例外,都使用了「基于人类反馈的强化学习」(RLHF)来提升语言模型的性能,并在模型重注入了人类的偏好,以提高模型的有用性和安全性。不过RLHF也早已更新换代,我们

【Spring Boot】操作Redis数据结构

🌿欢迎来到@衍生星球的CSDN博文🌿🍁本文主要学习【SpringBoot】操作Redis数据结构🍁🌱我是衍生星球,一个从事集成开发的打工人🌱⭐️喜欢的朋友可以关注一下🫰🫰🫰,下次更新不迷路⭐️💠作为一名热衷于分享知识的程序员,我乐于在CSDN上与广大开发者交流学习。💠我希望通过每一次学习,让更多读

【MySql】1- 基础篇(上)

文章目录1.1前言1.2基础架构1.2.1MySql基本架构示意图1.2.2SQL语句执行顺序1.3日志系统:一条SQL更新语句如何执行1.3.1两阶段提交1.4事务隔离1.4.1隔离性与隔离级别1.4.2事务隔离的实现-展开说明“可重复读”1.4.3事务的启动方式1.5深入浅出索引1.5.1索引常见模型1.5.1In

热文推荐