当涉及到代码优化时,Python作为一种高级编程语言,具有广泛的应用领域和强大的功能。在软件开发中,设计模式是一种被广泛采用的解决问题的方案,它提供了一种在特定情境中重复使用的可行方案。在Python中,有许多设计模式可以用来优化代码。

其中两种常见的设计模式是单例模式和工厂模式。

单例模式

单例模式是一种只允许创建一个实例的设计模式。在Python中,可以使用类变量和类方法来实现单例模式。通过将类变量设置为None,并在类方法中进行判断和实例化,可以确保只有一个实例被创建。这在需要共享资源或限制实例数量的情况下非常有用。

举个例子,我们有一个日志记录器,我们希望在整个应用程序中只有一个实例来记录日志。我们可以创建一个单例模块,如下所示:

# logger.py
class Logger:
def __init__(self):
self.log = [] def add_log(self, message):
self.log.append(message) def print_log(self):
for message in self.log:
print(message) logger = Logger()
logger.add_log("Error: Something went wrong.")
logger.add_log("Info: Process completed successfully.")
logger.print_log()

上面的代码实际上是一个简单的对象生成过程,然而,如果将其独立生成为一个文件模块,那么它就成为了一个简单的单例模式的实现。

在其他模块中,我们可以直接导入logger模块并使用其中的实例。这样做的好处是,由于模块在整个应用程序中只被加载一次,我们可以确保只有一个Logger实例存在。这样可以提高代码的可维护性和可读性,并且可以避免多次实例化Logger的开销。

double-check

在Java中,我们经常需要确保单例模式在多线程环境下的正确性,这涉及到对多线程的处理。具体而言,当多个线程同时尝试创建单例对象时,我们需要使用锁和双重检查机制来保证单例的唯一性和正确性。至于为什么需要使用双重检查机制,这里就不再详述了。现在,让我们一起来看一下相关的代码实现。

import threading

class Logger:
_instance = None
_lock = threading.Lock() def __new__(cls):
if not cls._instance:
with cls._lock:
if not cls._instance:
cls._instance = super(Logger, cls).__new__(cls)
cls._instance.log = []
return cls._instance def add_log(self, message):
self.log.append(message) def print_log(self):
for message in self.log:
print(message) logger = Logger()
logger.add_log("Error: Something went wrong.")
logger.add_log("Info: Process completed successfully.")
logger.print_log()

以上就是单例模式的具体实现。在实际工作中,我们可以结合具体的需求编写代码。通过使用单例模式,我们可以轻松地在整个应用程序中共享一个对象实例,从而避免了重复创建对象所带来的开销。

工厂模式

工厂模式是一种创建型设计模式,它提供了一种通用的接口来创建对象,具体的对象创建逻辑由子类来决定。在Python中,我们可以使用工厂模式来实现动态对象创建,这样可以根据不同的情况返回不同的对象实例。这种灵活性使得我们能够轻松地扩展和修改代码,同时提高了代码的可维护性和可重用性。

简单工厂

在这个计算器类的例子中,我们可以使用工厂模式来根据不同的运算符创建不同类型的计算器对象。首先,我们可以创建一个抽象的计算器接口,定义了计算方法。然后,我们可以为每种运算符创建一个具体的计算器类,实现计算器接口,并实现相应的计算逻辑。接下来,我们可以创建一个工厂类,该工厂类提供一个静态方法,根据不同的运算符参数来实例化对应的具体计算器对象,并返回给调用方。

class Calculator:
def calculate(self, a, b):
pass class AddCalculator(Calculator):
def calculate(self, a, b):
return a + b class SubtractCalculator(Calculator):
def calculate(self, a, b):
return a - b class CalculatorFactory:
@staticmethod
def create_calculator(operator):
if operator == "+":
return AddCalculator()
elif operator == "-":
return SubtractCalculator() calculator = CalculatorFactory.create_calculator("+")
result = calculator.calculate(10, 5)
print(result)

这种实现方式会导致代码重复和维护困难。为了优化这个工厂模式,我们可以采用字典来存储运算操作和对应的计算器类,而不是使用多个if-elif语句。

优化简单工厂

class Calculator:
def calculate(self, a, b):
pass class AddCalculator(Calculator):
def calculate(self, a, b):
return a + b class SubtractCalculator(Calculator):
def calculate(self, a, b):
return a - b class CalculatorFactory:
calculators = {
"+": AddCalculator,
"-": SubtractCalculator
} @staticmethod
def create_calculator(operator):
if operator in CalculatorFactory.calculators:
return CalculatorFactory.calculators[operator]()
else:
raise ValueError("Invalid operator")

简单抽象工厂

在这个示例中,我们首先创建了一个名为CalculatorFactory的类。该类的主要功能是注册和创建计算器。接下来,我们创建了两个具体的计算器类,分别命名为AddCalculator和SubtractCalculator,并将它们注册到CalculatorFactory中。

通过这种方式,我们可以轻松地进行注册和创建各种不同的计算器类,而无需对主要的工厂代码进行修改。这样一来,在需要添加新的计算器时,我们只需要创建一个新的计算器类,并将其方便地注册到工厂中即可。这种灵活的设计使得系统具有良好的可扩展性,可以随时满足不断变化的需求。

class CalculatorFactory:
def __init__(self):
self.calculators = {} def register_calculator(self, operator, calculator):
self.calculators[operator] = calculator def create_calculator(self, operator):
if operator in self.calculators:
return self.calculators[operator]()
else:
raise ValueError("Invalid operator") class AddCalculator:
def calculate(self, x, y):
return x + y class SubtractCalculator:
def calculate(self, x, y):
return x - y # 创建一个工厂实例
factory = CalculatorFactory() # 注册计算器类
factory.register_calculator("+", AddCalculator)
factory.register_calculator("-", SubtractCalculator) # 使用工厂创建计算器
calculator = factory.create_calculator("+")
result = calculator.calculate(2, 3)
print(result) # 输出 5

抽象工厂模式的优点在于其能够使得代码变得更加可扩展、可维护,并且符合开闭原则。通过使用抽象工厂模式,我们可以将具体产品的创建过程与客户端代码相分离,从而使得系统更加灵活和可扩展。

当需要增加新的产品时,只需要创建新的具体产品类和对应的具体工厂类,而无需修改已有的代码。这种设计模式的使用能够有效地降低系统的耦合度,并且提高了代码的可维护性和可复用性。因此,抽象工厂模式是一种非常有效的设计模式,特别适用于需要频繁添加新的产品的场景。

复杂抽象工厂

我们可以进一步优化上述工厂的抽象,通过将所有的方法进行提取和抽离。

from abc import ABC, abstractmethod

# 抽象工厂类
class CalculatorFactory(ABC):
@abstractmethod
def create_calculator(self):
pass # 具体工厂类1 - 加法计算器工厂
class AdditionCalculatorFactory(CalculatorFactory):
def create_calculator(self):
return AdditionCalculator() # 具体工厂类2 - 减法计算器工厂
class SubtractionCalculatorFactory(CalculatorFactory):
def create_calculator(self):
return SubtractionCalculator() # 计算器接口
class Calculator(ABC):
@abstractmethod
def calculate(self, num1, num2):
pass # 具体计算器类1 - 加法计算器
class AdditionCalculator(Calculator):
def calculate(self, num1, num2):
return num1 + num2 # 具体计算器类2 - 减法计算器
class SubtractionCalculator(Calculator):
def calculate(self, num1, num2):
return num1 - num2 # 使用抽象工厂模式创建计算器
def create_calculator(operator):
if operator == "+":
factory = AdditionCalculatorFactory()
elif operator == "-":
factory = SubtractionCalculatorFactory()
else:
raise ValueError("Invalid operator") return factory.create_calculator() # 使用示例
calculator = create_calculator("+")
num1 = 1
num2 = 2
result = calculator.calculate(num1, num2)
print("运算结果为:", result)

这种实现方式将创建计算器对象的逻辑封装在工厂类中,使得代码更加清晰和可扩展。如果需要添加新的运算符,只需创建对应的具体工厂类和计算器类,并在工厂类中进行相应的判断即可。

总结

Python设计模式为我们提供了一种解决问题的方法。单例模式确保一个类只有一个实例,并提供全局访问点;工厂模式提供了一种创建对象的接口,但具体的对象创建逻辑由子类决定。通过使用这些设计模式,我们可以更好地组织和管理代码,提高代码的可读性和可维护性。

Python设计模式:你的代码真的够优雅吗?的更多相关文章

  1. Python设计模式: 最佳的"策略"模式实践代码

    Python设计模式: 最佳的"策略"模式实践代码 今天抽空看了下流畅的python,发现里面介绍了不少python自带的库的使用实例,用起来非常的优雅. 平时用Python来写爬 ...

  2. 最全36种python设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用.设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案.这些解决方案是众多软件开发人员经过 ...

  3. python设计模式之装饰器详解(三)

    python的装饰器使用是python语言一个非常重要的部分,装饰器是程序设计模式中装饰模式的具体化,python提供了特殊的语法糖可以非常方便的实现装饰模式. 系列文章 python设计模式之单例模 ...

  4. python设计模式之常用创建模式总结(二)

    前言 设计模式的创建模式终极目标是如何使用最少量最少需要修改的代码,传递最少的参数,消耗系统最少的资源创建可用的类的实例对象. 系列文章 python设计模式之单例模式(一) python设计模式之常 ...

  5. python设计模式之适配器模式

    python设计模式之适配器模式 结构型设计模式一个系统中不同实体(比如,类和对象)之间的关系,关注的是提供一种简单的对象组合方式来创造功能. 适配器模式( Adapter pattern)是一种结构 ...

  6. Python设计模式 - UML - 类图(Class Diagram)

    简介 类图是面向对象分析和设计的核心,用来描述系统各个模块中类与类之间.接口与接口之间.类与接口之间的关系,以及每个类的属性.操作等特性,一般在详细设计过程中实施. 类图本身就是现实世界的抽象,是对系 ...

  7. python——设计模式

    设计模式是什么? 设计模式是经过总结.优化的,对我们经常会碰到的一些编程问题的可重用解决方案.一个设计模式并不像一个类或一个库那样能够直接作用于我们的代码.反之,设计模式更为高级,它是一种必须在特定情 ...

  8. Python设计模式 - 总览(更新中...)

    最近打算重构部分python项目,有道是"工欲善其事,必先利其器",所以有必要梳理一下相关设计模式.每次回顾基本概念或底层实现时都会有一些新的收获,希望这次也不例外. 本系列打算先 ...

  9. python设计模式之工厂模式

    一.理解工厂模式 在面向对象编程中,术语“工厂”表示一个负责创建替他类型对象的类.通常情况下,作为一个工厂的类有一个对象以及与它关联的多个方法.客户端使用某些参数调用此方法,之后,工厂会据此创建所需类 ...

  10. python设计模式-单例模式

    单例模式应用场景 代码的设计模式共有25种,设计模式其实是代码无关的.其目的是基于OOP的思想,不同应用场景应用不同的设计模式,从而达到简化代码.利于扩展.提示性能等目的.本文简述Python实现的单 ...

随机推荐

  1. 看MindSpore加持下,如何「炼出」首个千亿参数中文预训练语言模型?

    摘要:千亿参数量的中文大规模预训练语言模型时代到来. 本文分享自华为云社区< MindSpore开源框架加持,如何「炼出」首个千亿参数.TB级内存的中文预训练语言模型?>,原文作者:che ...

  2. 为了减少代码复杂度,我将if-else升级为面向状态编程

    摘要:面向过程设计和面向对象设计的主要区别是:是否在业务逻辑层使用冗长的if else判断. 本文分享自华为云社区<从面向if-else编程升级为面向状态编程,减少代码复杂度>,作者:br ...

  3. 火山引擎DataLeap:助力PICO落地数据流程规范,提升开发效率

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群   作为目前中国市场领跑的头部XR品牌之一,字节跳动旗下的PICO已经拥有了超百万客户.   过去一年,PICO在 ...

  4. 编码器-解码器 | 基于 Transformers 的编码器-解码器模型

    基于 transformer 的编码器-解码器模型是 表征学习 和 模型架构 这两个领域多年研究成果的结晶.本文简要介绍了神经编码器-解码器模型的历史,更多背景知识,建议读者阅读由 Sebastion ...

  5. 干掉 LaTeX !用BookDown写本书

    Bookdown是著名R包作者谢益辉开发的,支持采用Rmarkdown (R代码可以运行)或普通markdown编写文档,然后编译成HTML, WORD, PDF, Epub等格式. bookdown ...

  6. mysql--ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded: /usr/lib64/mysql/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory

    问题背景: 1.在授权机器上连接mysql 8.0的数据库,账号.密码都没有问题,报错 2.使用 navicat工具连接8.0版本,报错 排查思路: 可能是创建用户没有指定插件使用了8.0自带的插件, ...

  7. 【TCP】学习笔记:application/octet-stream

    当浏览器在请求资源时,会通过http返回头中的content-type决定如何显示/处理将要加载的数据,如果这个类型浏览器能够支持阅览,浏览器就会直接展示该资源,比如png.jpeg.video等格式 ...

  8. AtCoder Beginner Contest 163 (6/6)

    比赛链接:Here AB水题, C - management 题意:给一棵 \(N(2\le N\le2e5)\)​ 个节点的有根树,求每个节点的儿子数. 思路:由于输入直接给的是每个节点的父节点,直 ...

  9. 共享内存原理与VCS监控采集实战

    作者:cluo 一.前言 共享内存广泛用于Redis,Kafka,RabbitMQ 等高性能组件中,本文主要提供一个共享内存在广告埋点数据采集的实战场景. 二.共享内存原理 1.原理 在Linux中, ...

  10. 【驱动】以太网扫盲(二)phy寄存器简介

    PHY 寄存器的地址空间为 5 位,从 0 到 31 最多可以定义 32 个寄存器(随着芯片功能不断增加,很多 PHY 芯片采用分页技术来扩展地址空间以定义更多的寄存器),IEEE802.3 定义了地 ...