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

一 装饰器模式

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

13. Linux上CUDA的安装

这个专栏记录我学习/科研过程中遇到的一些小问题以及解决方案,一些问题可能比较蠢请见谅。自用,仅供参考。 ------------------------------------------------------------------------------------ Linux上CUDA的安装 在安装之前,首先要确…

ThinkPHP6门面(Facade)

门面 门面(Facade) 门面为容器中的(动态)类提供了一个静态调用接口,相比于传统的静态方法调用, 带来了更好的可测试性和扩展性,你可以为任何的非静态类库定义一个facade类。 系统已经为大部分…

(计算机毕设)基于SpringBoot+Vue的房屋租赁系统的设计与实现

博主可接毕设设计!!! 各种毕业设计源码只要是你有的题目我这里都有源码 摘 要 社会的发展和科学技术的进步,互联网技术越来越受欢迎。网络计算机的生活方式逐渐受到广大人民群众的喜爱,也逐渐进入了每个用户的使用。互…

[Admin] Dashboard Filter for Mix Report Types

Background RevOps team has built a dashboard for sales team to track team members’ performance, but they’re blocked by how to provide a manager view based on sales’ hierarchy. Therefore, they seek for dev team’s help to clear their blocker. From foll…

游戏引擎学习第19天

介绍 这段内容描述了开发者在进行游戏开发时,对于音频同步和平台层的理解和调整的过程。以下是更详细的复述: 开发者表达了他希望今天继续进行的工作内容。他提到,昨天他讲解了一些关于音频的内容,今天他想稍微深入讲解一下他正…

高阶云服务-ELB+AS

ELBAS 弹性负载均衡弹性伸缩 原来1台web服务器不满足相应,现部署多台提供相同服务; 由于多个服务器多个ip该如何提供给应用呢? 引申出负载均衡(HAProxy,LVS01四层,Nginx七层) 防单点故障做主备…

STM32设计防丢防摔智能行李箱-分享

目录 目录 前言 一、本设计主要实现哪些很“开门”功能? 二、电路设计原理图 1.电路图采用Altium Designer进行设计: 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 随着科技的不断发展,嵌入式系统、物联网技术、智能设备…

Mysql中REPLACE INTO详解及和INSERT INTO的区别

前言 我们在进行数据库操作的时候,经常会遇到这样的场景: 首先判断数据是否存在;如果不存在,则插入;如果存在,则更新。 博主之前是是Java来进行逻辑判断,例如: 看起来似乎也很简洁…

基于Java Springboot发艺美发店管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…

element ui 走马灯一页展示多个数据实现

element ui 走马灯一页展示多个数据实现 element ui 走马灯一页展示多个数据实现 element ui 走马灯一页展示多个数据实现 主要是对走马灯的数据的操作,先看js处理 let list [{ i: 1, name: 1 },{ i: 2, name: 2 },{ i: 3, name: 3 },{ i: 4, name: 4 },]let newL…

ACM招新赛<赛后题解与反思总结>③

问题 A: 数数(Easy) 题目描述 某一天,工作室需要统计人数,现在小劉开始数人数,但是由于小劉数学极差,因此他数数的时候总是会忘记数数字8,也就是说他数完7以后,就会直接数数字9,直观的讲就是数字…

网络安全:我们的安全防线

在数字化时代,网络安全已成为国家安全、经济发展和社会稳定的重要组成部分。网络安全不仅仅是技术问题,更是一个涉及政治、经济、文化、社会等多个层面的综合性问题。从宏观到微观,网络安全的重要性不言而喻。 宏观层面:国家安全与…

八、鸿蒙开发-网络请求、应用级状态管理

提示:本文根据b站尚硅谷2024最新鸿蒙开发HarmonyOS4.0鸿蒙NEXT星河版零基础教程课整理 链接指引 > 尚硅谷2024最新鸿蒙开发HarmonyOS4.0鸿蒙NEXT星河版零基础教程 文章目录 一、网络请求1.1 申请网络访问权限1.2 安装axios库1.2.1 配置环境变量1.2.2 第二步&…

【MySQL实战45讲笔记】基础篇——MySQL 的基础架构

目录 1. MySQL 的基础架构1.1 连接器1.2 查询缓存1.3 分析器1.4 优化器1.5 执行器 1. MySQL 的基础架构 我们由一个问题引入对MySQL 基础架构的学习:一条SQL查询语句是如何执行的? mysql> select * from T where ID10;通过分析学习MySQL…

计算机网络 (5)数据通信的基础知识

前言 数据通信是一种以信息处理技术和计算机技术为基础的通信方式,它通过数据通信系统将数据以某种信号方式从一处传送到另一处,为计算机网络的应用和发展提供了技术支持和可靠的通信环境,是现代通信技术的关键部分。 一、数据通信的基本概念…

【操作系统笔记】目录

【操作系统笔记】操作系统框架https://blog.csdn.net/Resurgence03/article/details/142624262 【操作系统笔记】CPU管理https://blog.csdn.net/Resurgence03/article/details/142621526 【操作系统笔记】内存管理https://blog.csdn.net/Resurgence03/article/details/142669…

linux之调度管理(7)-SMP cpu 的spin-table启动

一、smp启动总体介绍 soc在启动阶段除了一些特殊情况外(如为了加快启动速度,在bl2阶段通过并行加载方式同时加载bl31、bl32和bl33镜像),一般都没有并行化需求。因此只需要一个cpu执行启动流程即可,这个cpu被称为primar…

基于Java Springboot活力健身馆管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…

BERT-TFBS:一种基于 BERT 的新型模型,通过迁移学习预测转录因子结合位点

转录因子(TF)是通过结合 DNA 序列中的转录因子结合位点(TFBS)来调控基因转录所必需的蛋白质。准确预测 TFBS 有助于设计和构建基于 TF 的代谢调控系统。尽管已经开发了各种用于预测 TFBS 的深度学习算法,但预测性能仍有…

前端pdf预览方案

前端pdf预览方案 pdf预览一般不需要前端生成pdf文件,pdf文件一般是通过接口,获取pdf文件【responseType:‘blob’,】或二进制文件流【responseType: ‘arraybuffer’,】或者已有的pdf文件。 前端PDF预览通常是通过读取现有的PDF文件,并使用…