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

一、区别:

  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.")

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

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


http://www.niftyadmin.cn/n/5034240.html

相关文章

入栏需看——英语

编码篇 英语——编码篇——单词——字母编码 英语——编码篇——单词——字母编码 方法篇 英语——方法篇——单词——右脑记忆单词——字源法编码法拼音法熟词法谐音法 英语——方法篇——单词——谐音法拼音法 英语——方法篇——单词—— 第一爪:找拼音 第二爪…

WPF中DataGrid控件绑定数据源

步骤 创建数据源:首先,我们需要创建一个数据源,可以是一个集合(如List、ObservableCollection等),也可以是一个DataTable对象。数据源中的每个元素代表一行数据。 设置DataGrid的ItemsSource属性&#xff…

分布式协议与算法——Raft算法

目录 Raft算法领导者选举有哪些成员身份?领导者选举流程选举细节节点之间如何通信什么是任期选举有哪写规则随机超时时间是什么 小结 日志复制如何理解日志如何复制日志如何实现日志的一致小结 节点成员变更成员变更的问题如何通过单节点变更解决成员变更的问题小结…

9.18 QT作业

mainwindow.h QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACEclass MainWindow : public QMainWindow {Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();signals:void jump(); //自定义跳转信号函数private slots:vo…

postman如何设置才能SwitchHosts切换host无缓存请求到指定ip服务

开发测试中,遇到多版本同域名的服务使用postman进行测试,一般会搭配SwitchHosts切换host类似工具进行请求,postman缓存比较重,如何做到无缓存请求呢,下面简单记录一下如何实现 首先要知道如何当前请求服务的ip是哪个 打开postman 依次点击/menu/view/show postman console 就…

算法|图论 6 并查集

并查集基本模板&#xff1a; int n 10; vector UFSets(n,0);//若将初值全设置为-1&#xff0c;那就不用再有初始化操作了。//初始化 void Initial(vector<int> S[]){for(int i0;i<n;i){S[i] -1;} }//查操作 int Find(vector<int> &S,int x){int root x;…

《计算机网络》——应用层

2.1 应用层协议原理&#xff08;P54&#xff09; 研发网络应用的核心是写出能够运行在不同端系统和通过网络彼此交流的程序。 2.1.1 网络应用程序体系结构 两种主流的应用体系结构&#xff1a;客户-服务器体系结构、对等体系结构。 客户-服务器体系&#xff1a;服务器是一个…

郑州大学图书馆许少辉《乡村振兴战略下传统村落文化旅游设计》中文文献——2023学生开学季辉少许

郑州大学图书馆许少辉《乡村振兴战略下传统村落文化旅游设计》中文文献——2023学生开学季辉少许