Python设计模式:你的代码真的够优雅吗?
当涉及到代码优化时,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设计模式:你的代码真的够优雅吗?的更多相关文章
- Python设计模式: 最佳的"策略"模式实践代码
Python设计模式: 最佳的"策略"模式实践代码 今天抽空看了下流畅的python,发现里面介绍了不少python自带的库的使用实例,用起来非常的优雅. 平时用Python来写爬 ...
- 最全36种python设计模式
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用.设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案.这些解决方案是众多软件开发人员经过 ...
- python设计模式之装饰器详解(三)
python的装饰器使用是python语言一个非常重要的部分,装饰器是程序设计模式中装饰模式的具体化,python提供了特殊的语法糖可以非常方便的实现装饰模式. 系列文章 python设计模式之单例模 ...
- python设计模式之常用创建模式总结(二)
前言 设计模式的创建模式终极目标是如何使用最少量最少需要修改的代码,传递最少的参数,消耗系统最少的资源创建可用的类的实例对象. 系列文章 python设计模式之单例模式(一) python设计模式之常 ...
- python设计模式之适配器模式
python设计模式之适配器模式 结构型设计模式一个系统中不同实体(比如,类和对象)之间的关系,关注的是提供一种简单的对象组合方式来创造功能. 适配器模式( Adapter pattern)是一种结构 ...
- Python设计模式 - UML - 类图(Class Diagram)
简介 类图是面向对象分析和设计的核心,用来描述系统各个模块中类与类之间.接口与接口之间.类与接口之间的关系,以及每个类的属性.操作等特性,一般在详细设计过程中实施. 类图本身就是现实世界的抽象,是对系 ...
- python——设计模式
设计模式是什么? 设计模式是经过总结.优化的,对我们经常会碰到的一些编程问题的可重用解决方案.一个设计模式并不像一个类或一个库那样能够直接作用于我们的代码.反之,设计模式更为高级,它是一种必须在特定情 ...
- Python设计模式 - 总览(更新中...)
最近打算重构部分python项目,有道是"工欲善其事,必先利其器",所以有必要梳理一下相关设计模式.每次回顾基本概念或底层实现时都会有一些新的收获,希望这次也不例外. 本系列打算先 ...
- python设计模式之工厂模式
一.理解工厂模式 在面向对象编程中,术语“工厂”表示一个负责创建替他类型对象的类.通常情况下,作为一个工厂的类有一个对象以及与它关联的多个方法.客户端使用某些参数调用此方法,之后,工厂会据此创建所需类 ...
- python设计模式-单例模式
单例模式应用场景 代码的设计模式共有25种,设计模式其实是代码无关的.其目的是基于OOP的思想,不同应用场景应用不同的设计模式,从而达到简化代码.利于扩展.提示性能等目的.本文简述Python实现的单 ...
随机推荐
- 鸿蒙轻内核M核源码分析:中断Hwi
摘要:本文带领大家一起剖析了鸿蒙轻内核的中断模块的源代码,掌握中断相关的概念,中断初始化操作,中断创建.删除,开关中断操作等. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列五 中断Hwi&g ...
- 火山引擎DataTester:三类AB实验,让企业营销拥有灵敏“网感”
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 作者:火山引擎AB测试 近日,火山引擎数智平台举办了"走进火山-全链路增长:数据飞轮转动消费新生力& ...
- 从银行数字化转型来聊一聊,火山引擎 VeDI 旗下 ByteHouse 的应用场景
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 近日,火山引擎凭借云原生数据分析平台 ByteHouse,成功入围行业媒体 Internet Deep(互联网周刊 ...
- 火山引擎ByteHouse助力中国地震台网中心,快速构建一站式实时数仓
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,并进入官方交流群 近日,中国地震台网中心与火山引擎达成合作,双方将围绕 ByteHouse 实时数仓展开合作. 中国地震台网中心为中国地震局 ...
- 【mongodb】pymongo使用
pymongo基本使用 import pymongo from bson.objectid import ObjectId # 连接方式1 client = pymongo.MongoClient(h ...
- ME21N 采购订单屏幕增强
1.业务需求 采购订单行项目新增"图号"和"价格类型"字段.其中图号只查询底表展示,不做修改:价格类型做下拉框: 2.增强实现 增强标准表EKPO结构CI_EK ...
- PS CJ34预算转借
一.CJ34,输入发出预算和接收预算的WBS 二.调用BAPI "-----------------------------------------@斌将军----------------- ...
- AtCoder Beginner Contest 174 个人题解(ABC水题,D思维,E题经典二分,F离线树状数组)
做完本期以后,最近就不会再发布 AtCoder 的往届比赛了(备战蓝桥杯ing) 补题链接:Here ABC题都是水题,这里直接跳过 D - Alter Altar 题意:一个R-W串,可以进行两种操 ...
- 深入学习和理解 Redux
本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/jhgQXKp4srsl9_VYMTZXjQ作者:曾超 Redux官网上是这样描述Redux, ...
- python生成word文档
python生成word文档,感觉比java生成方便很多 下面看看步骤 1.环境 pip install python-docx 2.准备一张需要插入word中的图片monty-truth.png 3 ...