Python高级编程模式和设计模式

news2024/11/20 17:40:49

一 装饰器模式

order_sources:
  source1:
    on_agreement: "reduce_receivable"
    on_completion: "reduce_receivable"
    on_rejection: "none"
  source2:
    on_agreement: "none"
    on_completion: "reduce_receivable"
    on_rejection: "none"
  source3:
    on_agreement: "none"
    on_completion: "none"
    on_rejection: "none"
import yaml

"""
不同来源执行不同的操作的时候,动态判断进行相应的操作
"""
# 读取配置文件
def load_config(file_path):
    with open(file_path, 'r') as file:
        config = yaml.safe_load(file)
    return config


"""装饰器:装饰器是一种用于修改或增强函数行为的工具。
在这个例子中,register_handler 是一个装饰器工厂,它返回一个装饰器。
装饰器工厂:装饰器工厂可以根据传入的参数动态生成装饰器。
这里,register_handler 接受一个 action 参数,并返回一个装饰器,
该装饰器将 action 属性添加到被装饰的函数上
"""
def register_handler(action):
    def decorator(func):
        func.action = action
        return func

    return decorator


# 定义处理函数
@register_handler("reduce_receivable")
def reduce_receivable(order_id):
    print(f"reduce_receivable receivable for order {order_id}.")


@register_handler("none")
def no_action(order_id):
    print(f"No action11111111 for order {order_id}.")


# 处理类
class AfterSalesHandler:
    def __init__(self, config_file):
        self.config = load_config(config_file)
        self.handlers = self._register_handlers()

    """
    动态注册:_register_handlers 方法遍历全局命名空间中的所有对象,
    查找带有 action 属性的可调用对象,并将它们注册到 handlers 字典中。
    反射:使用 globals() 获取全局命名空间中的所有对象,
    并通过 hasattr 和 callable 进行检查,这是 Python 中的一种反射机制
    """
    def _register_handlers(self):
        handlers = {}
        for name, func in globals().items():
            if callable(func) and hasattr(func, 'action'):
                handlers[func.action] = func
        print("handlers---------", handlers)
        return handlers
    """
    actions:从配置文件中获取指定订单来源的所有操作映射。
    action:从操作映射中获取指定操作对应的动作。
    handler:从注册的处理函数中获取指定动作对应的处理函数。
    handler(order_id):调用处理函数,并传递订单 ID 作为参数
    """
    def handle_after_sales(self, order_id, order_source, operation):
        actions = self.config['order_sources'].get(order_source, {})
        action = actions.get(operation, 'none')
        handler = self.handlers.get(action, self.nofind_action)
        print("handler-----------------", handler)
        handler(order_id)

    def nofind_action(self, order_id):
        print(f"No action for order {order_id}.")


# 示例调用
if __name__ == "__main__":
    handler = AfterSalesHandler('../data/OrderAfter.yaml')
    handler.handle_after_sales('12345-1', 'source1', 'on_agreement')
    handler.handle_after_sales('12345-2', 'source1', 'on_completion')
    handler.handle_after_sales('12345-3', 'source1', 'on_rejection')
    handler.handle_after_sales('12345-4', 'source2', 'on_agreement')
    handler.handle_after_sales('12345-5', 'source2', 'on_completion')
    handler.handle_after_sales('12345-6', 'source2', 'on_rejection')
    handler.handle_after_sales('12345-7', 'source3', 'on_agreement')
    handler.handle_after_sales('12345-8', 'source3', 'on_completion')
    handler.handle_after_sales('12345-9', 'source3', 'on_rejection')

二 工厂模式

[DynamicMethod]
strategy=CreateJieSuanDan
SignJunWang_pre_strategy=QianShouChaXuanJunWang
HeYanPassJunWang_pre_strategy=SignJunWang
CreateJieSuanDan_pre_strategy=HeYanPassJunWang
from abc import ABC, abstractmethod
import configparser
from inspect import signature


class Strategy(ABC):
    @abstractmethod
    def execute(self, appoint_order_source):
        pass


class QianShouChaXuanJunWangStrategy(Strategy):
    def __init__(self, pre_strategy: Strategy = None):
        self.pre_strategy = pre_strategy

    def execute(self, appoint_order_source):
        if self.pre_strategy:
            self.pre_strategy.execute(appoint_order_source)
        else:
            print('QianShouChaXuanJunWangStrategy没有前置策略')
        print('QianShouChaXuanJunWangStrategy被调用')


class SignJunWangStrategy(Strategy):
    def __init__(self, pre_strategy: Strategy = None):
        self.pre_strategy = pre_strategy

    def execute(self, appoint_order_source):
        if self.pre_strategy:
            self.pre_strategy.execute(appoint_order_source)
        else:
            print('SignJunWangStrategy灭有前置策略')
        print('SignJunWangStrategy被调用')


class HeYanPassJunWangStrategy(Strategy):
    def __init__(self, pre_strategy: Strategy = None):
        self.pre_strategy = pre_strategy

    def execute(self, appoint_order_source):
        if self.pre_strategy:
            self.pre_strategy.execute(appoint_order_source)
        else:
            print('HeYanPassJunWangStrategy没有前置策略')
        print('HeYanPassJunWangStrategy被调用')


class CreateJieSuanDanStrategy(Strategy):
    def __init__(self, pre_strategy: Strategy = None):
        self.pre_strategy = pre_strategy

    def execute(self, appoint_order_source):
        if self.pre_strategy:
            self.pre_strategy.execute(appoint_order_source)
        else:
            print('CreateJieSuanDanStrategy没有前置策略')
        print('CreateJieSuanDanStrategy被调用')


"""
最终返回的策略对象链是:
CreateJieSuanDanStrategy(
    HeYanPassJunWangStrategy(
        SignJunWangStrategy(
            QianShouChaXuanJunWangStrategy(None)
        )
    )
)
"""


class StrategyFactory:
    _strategies = {
        'QianShouChaXuanJunWang': QianShouChaXuanJunWangStrategy,
        'SignJunWang': SignJunWangStrategy,
        'HeYanPassJunWang': HeYanPassJunWangStrategy,
        'CreateJieSuanDan': CreateJieSuanDanStrategy
    }

    @staticmethod
    def create_strategy(strategy_name: str, config: configparser.ConfigParser) -> Strategy:
        if strategy_name not in StrategyFactory._strategies:
            raise ValueError(f"Unknown strategy: {strategy_name}")
        strategy_class = StrategyFactory._strategies[strategy_name]
        pre_strategy_name = config.get('DynamicMethod', f'{strategy_name}_pre_strategy', fallback=None)
        if pre_strategy_name:
            pre_strategy = StrategyFactory.create_strategy(pre_strategy_name, config)
            return strategy_class(pre_strategy)
        else:
            return strategy_class()


class Context:
    def __init__(self, strategy: Strategy):
        self._strategy = strategy

    def set_strategy(self, strategy: Strategy):
        self._strategy = strategy

    def execute_strategy(self, appoint_order_source):
        self._strategy.execute(appoint_order_source)


def dynamic_method_call(appoint_order_source, config_file='../data/DongtaiConfig.ini'):
    # 读取配置文件
    config = configparser.ConfigParser()
    config.read(config_file)

    # 获取当前需要调用的策略名称
    strategy_name = config.get('DynamicMethod', 'strategy')

    # 创建策略对象
    strategy = StrategyFactory.create_strategy(strategy_name, config)
    # 创建上下文并设置策略
    context = Context(strategy)

    # 执行策略
    context.execute_strategy(appoint_order_source)


if __name__ == "__main__":
    appoint_order_source = "some_value"

    # 动态调用方法
    dynamic_method_call(appoint_order_source)

from abc import ABC, abstractmethod
from dataclasses import dataclass
from enum import Enum
import logging

logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)


@dataclass
class OrderInfo:
    product: str
    quantity: int


class OrderSource(Enum):
    ONLINE = 'online'
    OFFLINE = 'offline'


class OrderCreator(ABC):
    """基类用于创建订单"""

    @abstractmethod
    def create_order_instance(self, order_info: OrderInfo) -> str:
        """子类必须实现此方法以创建具体的订单实例"""
        pass


class OnlineOrderCreator(OrderCreator):
    """用于创建线上订单的类"""

    def create_order_instance(self, order_info: OrderInfo) -> str:
        """实现线上订单的创建逻辑"""
        logger.info(f"Creating online order: {order_info}")
        return "OnlineOrder123"


class OfflineOrderCreator(OrderCreator):
    """用于创建线下订单的类"""

    def create_order_instance(self, order_info: OrderInfo) -> str:
        """实现线下订单的创建逻辑"""
        logger.info(f"Creating offline order: {order_info}")
        return "OfflineOrder456"


class OrderFactory:
    """工厂类用于创建不同的订单创建者"""

    @staticmethod
    def get_creator(source: OrderSource) -> OrderCreator:
        """根据来源获取相应的订单创建者实例"""
        if source == OrderSource.ONLINE:
            return OnlineOrderCreator()
        elif source == OrderSource.OFFLINE:
            return OfflineOrderCreator()
        else:
            raise ValueError(f"Invalid order source: '{source.value}'")


def create_order_instance(order_info: OrderInfo, source: OrderSource) -> str:
    """根据指定的来源创建订单实例"""
    creator = OrderFactory.get_creator(source)
    return creator.create_order_instance(order_info)


# 使用示例
order_info = OrderInfo(product="Widget", quantity=10)
source = OrderSource.ONLINE
order_id = create_order_instance(order_info, source)
print(f"Order ID: {order_id}")

三 观察者模式

class OrderSubject:
    def __init__(self):
        self._observers = []
        self._orders = {}

    def attach(self, observer):
        self._observers.append(observer)

    def detach(self, observer):
        self._observers.remove(observer)

    def notify(self, order_id, status):
        for observer in self._observers:
            observer.update(order_id, status)

    def create_order(self, order_id, initial_status):
        self._orders[order_id] = initial_status
        self.notify(order_id, initial_status)

    def change_order_status(self, order_id, new_status):
        if order_id in self._orders:
            self._orders[order_id] = new_status
            self.notify(order_id, new_status)
        else:
            print(f"Order {order_id} does not exist.")


class LogisticsObserver:
    def update(self, order_id, status):
        print(f"Logistics: Order {order_id} status changed to {status}")
        if status == "Shipped":
            self.ship_order(order_id)

    def ship_order(self, order_id):
        print(f"Logistics: Shipping order {order_id}")


class FinanceObserver:
    def update(self, order_id, status):
        print(f"Finance: Order {order_id} status changed to {status}")
        if status == "Paid":
            self.process_payment(order_id)

    def process_payment(self, order_id):
        print(f"Finance: Processing payment for order {order_id}")


class CustomerNotificationObserver:
    def update(self, order_id, status):
        print(f"Customer: Order {order_id} status changed to {status}")
        if status == "Delivered":
            self.notify_customer(order_id)

    def notify_customer(self, order_id):
        print(f"Customer: Notifying customer about delivery of order {order_id}")


# 创建订单主体
order_subject = OrderSubject()

# 创建观察者
logistics_observer = LogisticsObserver()
finance_observer = FinanceObserver()
customer_notification_observer = CustomerNotificationObserver()

# 注册观察者
order_subject.attach(logistics_observer)
order_subject.attach(finance_observer)
order_subject.attach(customer_notification_observer)

# 创建订单
order_subject.create_order("12345", "Created")

# 改变订单状态
order_subject.change_order_status("12345", "Paid")
order_subject.change_order_status("12345", "Shipped")
order_subject.change_order_status("12345", "Delivered")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2244165.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++:指针和引用

指针的基础 数据在内存当中是怎么样被存储的 数据在内存中的存储方式取决于数据的类型和计算机的体系结构 基本数据类型 整数类型:整数在内存中以二进制补码的形式存储。对于有符号整数,最高位为符号位,0 表示正数,1 表示负数。…

MySQL更换瀚高语法更换

MySQL更换瀚高语法更换 一、前言二、语句 一、前言 水一篇,mysql更换瀚高之后,一些需要更换的语法介绍 > 二、语句 MySQL瀚高MySQL用法瀚高用法说明ifnull(x,y)coalesce(x,y)相同相同用于检查两个表达式并返回第一个非空表达式。如果第一个表达式不是 NULL&…

亚马逊云服务器(AWS):功能、优势与使用指南

亚马逊云服务器(AWS)概述 亚马逊云服务器(Amazon Web Services,简称AWS)是全球领先的云计算平台,提供一系列强大且灵活的云服务,帮助企业和开发者通过云基础设施实现数据存储、计算、分析和机器…

国产三维CAD 2025新动向:推进MBD模式,联通企业设计-制造数据

本文为CAD芯智库原创整理,未经允许请勿复制、转载! 上一篇文章阿芯分享了影响企业数字化转型的「MBD」是什么、对企业优化产品设计流程有何价值——这也是国产三维CAD软件中望3D 2024发布会上,胡其登先生(中望软件产品规划与GTM中…

小试牛刀-Anchor安装和基础测试

目录 一、编写目的 二、安装步骤 2.1 安装Rust 设置rustup镜像 安装Rust 2.2 安装node.js 2.3 安装Solana-CLI 2.4 安装Anchor CLI 三、Program测试 四、可能出现的问题 Welcome to Code Blocks blog 本篇文章主要介绍了 [Anchor安装和基础测试] 博主广交技术好友&…

如何在 Ubuntu 上安装 Emby 媒体服务器

Emby 是一个开源的媒体服务器解决方案,它能让你整理、流媒体播放和分享你的个人媒体收藏,包括电影、音乐、电视节目和照片。Emby 帮你集中多媒体内容,让你无论在家还是在外都能轻松访问。它还支持转码,让你能够播放各种格式的内容…

php交友源码交友系统源码相亲交友系统源码php社交系统php婚恋源码php社区交友源码vue 仿交友社交语聊技术栈

关于PHP交友、相亲、婚恋、社区交友系统的源码以及Vue仿交友社交语聊技术栈,以下是一些详细信息和建议: 一、PHP交友系统源码 系统架构设计 前端展示层:负责向用户提供直观友好的界面,包括注册登录页面、个人资料页面、匹配页面、…

【装饰珠——分组背包】

题目 代码 #include <bits/stdc.h> using namespace std; const int N 1e410; int cnt[5]; // 存兼容i等级及以下的孔的数目的桶 int l[N], p[N]; // l[i] i号珠子等级 p[i] i号珠子的上限 int w[N][8], f[N]; // w[i][j] i号珠子镶嵌j个的值 f[i] 孔数为i的最大值…

数据库审计工具--Yearning 3.1.9普民的使用指南

1 页面登录 登录地址:18000 &#xff08;不要勾选LDAP&#xff09; 2 修改用户密码 3 DML/DDL工单申请及审批 工单申请 根据需要选择【DML/DDL/查询】中的一种进行工单申请 填写工单信息提交SQL检测报错修改sql语句重新进行SQL检测&#xff0c;如检测失败可以进行SQL美化后…

Misc_01转二维码(不是二进制)

例题ctfhub/隐写v2.0 打开是一张图片 文件分离得到zip&#xff0c;爆破密码得到7878 打开得到0和1&#xff0c; !!!不是二进制转图片&#xff0c;直接是二维码 缩小能看到 000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000…

AI工具百宝箱|任意选择与Chatgpt、gemini、Claude等主流模型聊天的Anychat,等你来体验!

文章推荐 AI工具百宝箱&#xff5c;使用Deep Live Cam&#xff0c;上传一张照片就可以实现实时视频换脸...简直太逆天&#xff01; Anychat 这是一款可以与任何模型聊天 &#xff08;chatgpt、gemini、perplexity、claude、metal llama、grok 等&#xff09;的应用。 在页面…

[论文阅读] 异常检测综述 Deep Learning for Anomaly Detection: A Review(一)

深度学习在异常检测中的应用&#xff1a;综述 摘要 异常检测&#xff0c;又称离群点检测或新奇性检测&#xff0c;在各个研究领域中数十年来一直是一个持续且活跃的研究领域。仍然存在一些独特的问题复杂性和挑战&#xff0c;需要先进的方法来解决。近年来&#xff0c;基于深…

PaddlePaddle 开源产业级文档印章识别PaddleX-Pipeline “seal_recognition”模型 开箱即用篇(一)

AI时代到来&#xff0c;各行各业都在追求细分领域垂直类深度学习模型&#xff0c;今天给大家介绍一个PaddlePaddle旗下&#xff0c;基于PaddleX Pipeline 来完成印章识别的模型“seal_recognition”。 官方地址&#xff1a;https://github.com/PaddlePaddle/PaddleX/blob/relea…

Ubuntu 22.04 上快速搭建 Samba 文件共享服务器

Samba 简介 Samba 是一个开源软件&#xff0c;它扮演着不同操作系统间沟通的桥梁。通过实现 SMB&#xff08;Server Message Block&#xff09;协议&#xff0c;Samba 让文件和打印服务在 Windows、Linux 和 macOS 之间自由流动。 以下是 Samba 的特点&#xff1a; 跨平台兼…

语义分割(semantic segmentation)

语义分割(semantic segmentation) 文章目录 语义分割(semantic segmentation)图像分割和实例分割代码实现 语义分割指将图片中的每个像素分类到对应的类别&#xff0c;语义区域的标注和预测是 像素级的&#xff0c;语义分割标注的像素级的边界框显然更加精细。应用&#xff1a…

QT基础 UI编辑器 QT5.12.3环境 C++环境

一、UI编辑器 注意&#xff1a;创建工程时&#xff0c;要勾上界面按钮 UI设计师界面的模块 UI编辑器会在项目构建目录中自动生成一个ui_xxx.h&#xff08;构建一次才能生成代码&#xff09;&#xff0c;来表示ui编辑器界面的代码&#xff0c;属于自动生成的&#xff0c;一定不…

Jmeter的后置处理器(二)

5--JSR223 PostProcessor 功能特点 自定义后处理逻辑&#xff1a;使用脚本语言编写自定义的后处理逻辑。支持多种脚本语言&#xff1a;支持 Groovy、JavaScript、BeanShell 等脚本语言。动态参数传递&#xff1a;将提取的数据存储为变量&#xff0c;供后续请求使用。灵活性高…

高阶C语言之五:(数据)文件

目录 文件名 文件类型 文件指针 文件的打开和关闭 文件打开模式 文件操作函数&#xff08;顺序&#xff09; 0、“流” 1、字符输出函数fputc 2、字符输入函数fgetc 3、字符串输出函数fputs 4、 字符串输入函数fgets 5、格式化输入函数fscanf 6、格式化输出函数fpr…

【Android、IOS、Flutter、鸿蒙、ReactNative 】实现 MVP 架构

Android Studio 版本 Android Java MVP 模式 参考 模型层 model public class User {private String email;private String password;public User(String email, String password) {this.email = email;this.password = password;}public String getEmail() {return email;}…

如何管理服务中的 “昂贵” 资源

如果接触过实际大型业务系统&#xff0c;就能体会到许多业务的正常运行都依赖于各种昂贵的第三方接口&#xff0c;调用一次都是要花元子的&#xff0c;例如 大语言模型nlp 服务&#xff1a;信息提取、分类等cv 服务&#xff1a;定位、信息提取、分类等 然而经常可能由于各种无…