Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $YECBGYFECGEAFWHA as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2

Deprecated: imwpcache\f884414bce24ee67f\f73723ec7b1919fa5::__construct(): Implicitly marking parameter $BBWFDDBHHYHDXXAB as nullable is deprecated, the explicit nullable type must be used instead in /www/wwwroot/www.chuangxiangniao.com/wp-content/plugins/imwpcache-dist/build/f884414bce24ee67ff73723ec7b1919fa5.php on line 2
Python:重构模式_创想鸟

Python:重构模式

python:重构模式

摄影:帕特里克·何

言简意赅版:这份Python代码表列出了代码坏味道及其对应的设计模式解决方案。

class 代码坏味道:    代码重复 = [        组合方法,        工厂方法创建多态对象,        链式构造器,        组合替代单多关系,        提取组合,        适配器统一接口,        引入空对象,    ]    方法过长 = [        组合方法,        将累加移至收集参数,        命令替代条件派发器,        将累加移至访问者,        策略替代条件逻辑,    ]    条件复杂 = [  # 复杂的条件逻辑        策略替代条件逻辑,        装饰器修饰,        状态替代改变状态的条件语句,        引入空对象,    ]    基本类型偏执 = [        类替代类型码,        状态替代改变状态的条件语句,        策略替代条件逻辑,        组合替代隐式树,        解释器替代隐式语言,        装饰器修饰,        构建器封装组合,    ]    信息泄露 = [工厂封装类]    解决方案分散 = [将创建知识移至工厂]    接口不同类相似 = 适配器统一接口    类职责过轻 = [内联单例]    类过大 = [        命令替代条件派发器,        状态替代改变状态的条件语句,        组合替代隐式树,    ]    switch语句 = [  # 复杂的switch语句        命令替代条件派发器,        将累加移至访问者,    ]    组合爆炸 = [解释器替代隐式语言]    解决方案奇特 = [适配器统一接口]

代码重构

历时近一年,我终于完成了用Python实现Joshua Kerievsky的《重构到模式》一书中所有重构示例的目标。此书极大地提升了我理解如何在生产代码中应用设计模式的能力。

每个示例都包含对原始代码及其背景的简要描述,随后是重构后的代码以及重构带来的好处。例如,“组合方法”重构将难以理解的代码转化为简洁易懂的实现。

让我们来看一个示例,分析原始代码:

立即学习“Python免费学习笔记(深入)”;

# 原始代码# 代码难以理解def add(element):    readonly = False    size = 0    elements = []    if not readonly:        new_size = size + 1        if new_size > len(elements):            new_elements = []            for i in range(size):                new_elements[i] = elements[i]            elements = new_elements        size += 1        elements[size] = element

可见,这段代码难以理解,包含许多嵌套条件和循环。现在来看重构后的代码:

# 重构后的代码# 新代码使用更有意义的名称,避免嵌套。# 组合方法重构简化了代码。def at_capacity(new_size, elements):    return new_size > len(elements)def grow(size):    new_elements = [None] * size    for i in range(size):        new_elements[i] = elements[i]    return new_elementsdef add_elements(elements, element, size):    size += 1    elements[size] = element    return sizedef add_refac(element):    readonly = False    if readonly:        return    size = 0    elements = []    new_size = size + 1    if at_capacity(new_size, elements):        elements = grow(size)    size = add_elements(elements, element, size)

重构的核心思想是使用更有意义的方法来降低复杂度并消除嵌套分支。注意,需要将代码块提取到方法中。

在阅读并编写这些示例的过程中,我需要解释UML图并深入理解其机制。这需要高度的专注力和脑力劳动。很多时候,我不得不从头开始重建示例,因为将代码从Java转换为Python并非易事。Python原生不支持循环导入、构造函数重载或接口,因此需要一些调整。我在这些地方添加了注释,以便将来参考。

通过这个过程,我意识到之前对设计模式的理解大多停留在理论层面,仅限于简单的场景。例如,虽然我理解“多态性”解决了开发问题,但这本书通过抽象设置阶段并重用剩余的测试实现,展示了其在测试自动化中的应用。

以下是两个版本的代码。原始代码和新代码的区别在于测试的设置。

# 原始代码# 类似的方法在对象实例化方面有所不同。# 其他部分相同class testcase:    passclass dombuilder:    def __init__(self, orders) -> None:        pass    def calc(self):        return 42class xmlbuilder:    def __init__(self, orders) -> None:        pass    def calc(self):        return 42class domtest(testcase):    def run_dom_test(self):        expected = 42        builder = dombuilder("orders")  # 创建不同的对象        assert builder.calc() == expectedclass xmltest(testcase):    def run_xml_test(self):        expected = 42        builder = xmlbuilder("orders")  # 创建不同的对象        assert builder.calc() == expected# 重构后的代码# 两个测试中,唯一不同之处在于dombuilder或xmlbuilder的实例化。# 创建了一个outputbuilder作为两个类的接口(鉴于Python使用鸭子类型,这并非必要)。# 在testcase中,引入了一个名为“create_builder”的新方法,由子类实现。# 这是每个测试类型在运行时执行的步骤。这就是多态性。当执行两个测试(domtest和xmltest)时,# 从“create_builder”返回的实例取决于实现。它可以是dombuilder或xmlbuilder。class outputbuilder:    def calc(self):        raise NotImplementedError()class dombuilderrefac(outputbuilder):    def calc(self):        return 42class xmlbuilderrefac(outputbuilder):    def calc(self):        return 42class testcaserefac:    def create_builder(self):        raise NotImplementedError()    def run_test(self):        expected = 42        builder = self.create_builder()  # 创建不同的对象        assert builder.calc() == expectedclass domtestrefac(testcaserefac):    def create_builder(self) -> outputbuilder:        return dombuilderrefac()class xmltestrefac(testcaserefac):    def create_builder(self):        return xmlbuilderrefac()def run():    dom_tc = domtestrefac()    dom_tc.run_test()    xml_tc = xmltestrefac()    xml_tc.run_test()

“访问者”模式对我来说是最难理解的。在尝试重构之前,我阅读了《设计模式》一书中关于该模式的内容。只有看到原始(未重构的)代码转换为新版本之后,我才意识到该模式并不像最初看起来那么复杂。本质上,该模式将类与其方法解耦。再次,比较两段代码。该模式的实现是“按书本”进行的。

# 原始代码# TextExtractor包含许多条件来处理节点,例如StringNode# 重构的思想是将逻辑分配到访问者类中# 接口class Node:    passclass LinkTag(Node):    passclass Tag(Node):    passclass StringNode(Node):    passclass TextExtractor:    def extract_text(self, nodes: list[Node]):        result = []        for node in nodes:            if isinstance(node, StringNode):                result.append("string")            elif isinstance(node, LinkTag):                result.append("linktag")            elif isinstance(node, Tag):                result.append("tag")            else:                result.append("other")        return result# 重构后的代码# 接口(访问者)class NodeVisitorRefac:    def visit_link_tag(self, node):        return "linktag"    def visit_tag(self, node):        return "tag"    def visit_string_node(self, node: object):        return "string"class NodeRefac:    def accept(self, node: NodeVisitorRefac):        passclass LinkTagRefac(NodeRefac):    def accept(self, node: NodeVisitorRefac):        return node.visit_link_tag(self)class TagRefac(NodeRefac):    def accept(self, node: NodeVisitorRefac):        return node.visit_tag(self)class StringNodeRefac(NodeRefac):    def accept(self, node: NodeVisitorRefac):        return node.visit_string_node(self)# 具体的访问者class TextExtractorVisitorRefac(NodeVisitorRefac):    def extract_text(self, nodes: list[NodeRefac]):        result = []        for node in nodes:            result.append(node.accept(self))        return resultdef run_refac():    # 原始对象调用其方法    result1 = TextExtractor().extract_text([StringNode()])    # 新对象接受访问者    result2 = TextExtractorVisitorRefac().extract_text([StringNodeRefac()])    return result1, result2

结论

我强烈推荐这本书。当我第一次阅读它时,我发现仅仅通过静态代码示例来掌握概念既枯燥又困难。然而,当你积极地编写代码时,想法会逐渐清晰起来。错误会发生,解决这些错误需要理解基本概念。这个过程将理论转化为实践,并巩固你的知识。

以上就是Python:重构模式的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1355591.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
从电路板到代码:作为一名多语言 Web 开发人员(和电气工程师)如何增强我的编程游戏
上一篇 2025年12月13日 19:20:02
API 规划指南:代码优先 VS 设计优先方法
下一篇 2025年12月13日 19:20:17

相关推荐

  • 使用 Rest Assured 创建泛型 JSONPath 值提取函数

    使用 Rest Assured 创建泛型 JSONPath 值提取函数使用 Rest Assured 创建泛型 JSONPath 值提取函数使用 Rest Assured 创建泛型 JSONPath 值提取函数使用 Rest Assured 创建泛型 JSONPath 值提取函数

    本文探讨如何在 Rest Assured 中设计一个泛型工具函数,以实现类型安全的 JSONPath 值提取。针对直接使用 T.class 导致的编译错误,文章提供了通过将 Class 作为参数传入的解决方案,有效规避了 Java 泛型擦除问题,从而实现灵活、可复用的 JSON 数据解析。 泛型 J…

    2026年9月24日 • 用户投稿
    000
  • 怎么用豆包AI分析Python内存使用 AI辅助定位内存泄漏的实用方法

    怎么用豆包AI分析Python内存使用 AI辅助定位内存泄漏的实用方法怎么用豆包AI分析Python内存使用 AI辅助定位内存泄漏的实用方法怎么用豆包AI分析Python内存使用 AI辅助定位内存泄漏的实用方法怎么用豆包AI分析Python内存使用 AI辅助定位内存泄漏的实用方法

    python内存泄漏可通过tracemalloc、objgraph及代码分析定位。1. 使用tracemalloc模块记录内存分配堆栈,生成快照并输出统计结果,交由豆包ai分析可疑内存泄漏点;2. 用objgraph查看常见对象类型及增长趋势,若发现异常增长对象可交由豆包判断是否合理;3. 将疑似泄…

    2026年9月24日 • 用户投稿
    000
  • 抖音双11好物节有哪些优惠活动?双11抖音有什么活动

    抖音双11好物节有哪些优惠活动?双11抖音有什么活动抖音双11好物节有哪些优惠活动?双11抖音有什么活动抖音双11好物节有哪些优惠活动?双11抖音有什么活动抖音双11好物节有哪些优惠活动?双11抖音有什么活动

    一年一度的双11购物狂欢节即将来临,抖音平台也紧跟潮流,推出了抖音双11好物节活动。这次活动可谓是优惠满满,好物多多,让广大消费者在购物的同时,也能享受购物的乐趣。下面,就让我为大家详细介绍一下2025年抖音双11好物节的优惠活动吧! 一、抖音双11好物节活动时间 活动周期:2025年9月16日(中…

    2026年9月24日 • 用户投稿
    000
  • 我的花园世界最新兑换码分享

    我的花园世界最新兑换码分享我的花园世界最新兑换码分享我的花园世界最新兑换码分享我的花园世界最新兑换码分享

    在我的花园世界这款游戏中,玩家能够种植并培育上百种美丽的鲜花,尽情享受园艺带来的乐趣。为了帮助玩家更好地成长,官方每周都会推出福利兑换码,让大家免费获取游戏内道具。接下来,就为大家揭晓本周的礼包兑换码详情! 我的花园世界最新兑换码 本周专属兑换码: 花园相伴四季芬芳 礼包包含奖励: 元宝*50,加速…

    2026年9月24日 • 用户投稿
    100
  • 如何验证厂商宣传的散热技术是否切实有效?

    如何验证厂商宣传的散热技术是否切实有效?如何验证厂商宣传的散热技术是否切实有效?如何验证厂商宣传的散热技术是否切实有效?如何验证厂商宣传的散热技术是否切实有效?

    要验证散热技术是否有效,需结合产品规格、第三方评测、用户反馈及自行测试。首先查看热管数量与材质、均热板设计、风扇风量与静压等真实参数,警惕模糊宣传;其次参考专业媒体在标准环境下的烤机测试数据,如AIDA64或FurMark负载下的温度与频率表现;再通过电商平台或论坛收集长期使用反馈,关注共性问题如噪…

    2026年9月24日 • 用户投稿
    000
  • 主板声卡芯片的实际音质是否与宣传相符?

    答案:主板声卡芯片实际音质受限于电路设计与干扰,厂商宣传的高参数多为理想值,现实表现往往仅“够用”。集成声卡能满足日常需求,但细节、声场和底噪控制不如独立声卡;高端主板虽有改进,仍难敌独立供电、优质元件与屏蔽设计带来的音质优势。判断音质应以实听为准,关注底噪、分离度、动态等表现,并结合高品质音源与设…

    2026年9月24日
    000
  • 抖音账号无故被封禁该如何解决?封禁是否因他人举报而起?详解抖音账号封禁原因!

    抖音账号无故被封禁该如何解决?封禁是否因他人举报而起?详解抖音账号封禁原因!抖音账号无故被封禁该如何解决?封禁是否因他人举报而起?详解抖音账号封禁原因!抖音账号无故被封禁该如何解决?封禁是否因他人举报而起?详解抖音账号封禁原因!抖音账号无故被封禁该如何解决?封禁是否因他人举报而起?详解抖音账号封禁原因!

    一、抖音账号被封的常见原因 (一)是否因他人举报导致封号? 1. 一次举报会怎样?当一个抖音账号被用户举报时,平台通常不会立即采取严厉措施。首次举报多数情况下只会触发系统警告。例如,若发布的视频涉及轻微版权问题或存在争议性言论,虽未明显违规,但经他人举报后,可能会收到平台提醒。2. 多次举报的严重后…

    2026年9月24日 • 用户投稿
    200
  • 张含韵代言《龙之谷世界》!携”二转觉醒”重燃十年谷迷热泪!

    张含韵代言《龙之谷世界》!携”二转觉醒”重燃十年谷迷热泪!张含韵代言《龙之谷世界》!携”二转觉醒”重燃十年谷迷热泪!张含韵代言《龙之谷世界》!携”二转觉醒”重燃十年谷迷热泪!张含韵代言《龙之谷世界》!携”二转觉醒”重燃十年谷迷热泪!

    在2025年激烈异常的手游战场中,经典ip《龙之谷世界》凭借持续创新的运营策略稳居行业前列。近日,游戏再度引爆热潮——官方正式宣布人气女星张含韵出任品牌代言人,并同步上线重磅更新“二转觉醒”新版本。双管齐下,不仅点燃了玩家社群的热情,更通过“玩家共创”的深度互动模式,为经典ip的长效运营树立了全新典…

    2026年9月24日 • 用户投稿
    100
  • 中国家用电器协会倡议:杜绝无序低价竞争,坚决不搞低于成本价倾销

    中国家用电器协会倡议:杜绝无序低价竞争,坚决不搞低于成本价倾销中国家用电器协会倡议:杜绝无序低价竞争,坚决不搞低于成本价倾销中国家用电器协会倡议:杜绝无序低价竞争,坚决不搞低于成本价倾销中国家用电器协会倡议:杜绝无序低价竞争,坚决不搞低于成本价倾销

    9 月 29 日消息,今日,中国家用电器协会正式发布《关于加强家电行业自律与公平竞争的倡议书》,呼吁全行业共同维护市场秩序,推动高质量发展。 倡议书全文如下: 广大家电企业: 历经四十余年自主创新,我国家电产业已成长为制造业中最具国际竞争力的代表之一。尤其是近十年来,以智能家电为核心的创新浪潮,显著…

    2026年9月24日 • 用户投稿
    100
  • 如何用豆包 AI 大模型与 AI 聚会游戏设计工具结合,活跃聚会氛围?​

    如何用豆包 AI 大模型与 AI 聚会游戏设计工具结合,活跃聚会氛围?​如何用豆包 AI 大模型与 AI 聚会游戏设计工具结合,活跃聚会氛围?​如何用豆包 AI 大模型与 AI 聚会游戏设计工具结合,活跃聚会氛围?​如何用豆包 AI 大模型与 AI 聚会游戏设计工具结合,活跃聚会氛围?​

    豆包 ai 大模型与 ai 聚会游戏设计工具结合,能有效提升聚会互动性和趣味性。1. 可用豆包 ai 生成个性化问题或话题,如搞笑类、回忆类等,帮助破冰交流;2. 结合聚会游戏工具,利用 ai 生成的关键词或背景设定定制专属小游戏,增强即兴互动;3. 借 ai 生成角色设定和剧情线索,营造角色扮演氛…

    2026年9月24日 • 用户投稿
    100
  • sublime如何格式化sql语句 _sublime SQL格式化方法

    sublime如何格式化sql语句 _sublime SQL格式化方法sublime如何格式化sql语句 _sublime SQL格式化方法sublime如何格式化sql语句 _sublime SQL格式化方法sublime如何格式化sql语句 _sublime SQL格式化方法

    使用插件实现Sublime Text格式化SQL。1. 安装Package Control:通过控制台执行代码安装插件管理工具;2. 安装SQLPrettyPrinter:通过命令面板搜索并安装,选中SQL语句后运行“SQL Pretty Print”命令格式化;3. 高级用户可结合Python的s…

    2026年9月24日 • 用户投稿
    100
  • mysql数据库中的自增列如何使用

    自增列是MySQL中用于自动产生唯一数值的整数列,通常作为主键使用。通过AUTO_INCREMENT属性,插入数据时若未指定值,系统会自动分配比当前最大值大1的数值,确保每条记录拥有唯一标识,简化插入操作。创建表时可定义自增列,如:CREATE TABLE users (id INT AUTO_IN…

    2026年9月24日
    100
  • 如何高效管理Debian文件系统

    高效管理debian文件系统可以通过以下几个步骤来实现: 了解文件系统结构: Debian文件系统遵循标准的Linux文件系统层次结构,例如/bin, /etc, /home, /usr, /var等。熟悉这些目录的作用,有助于更好地组织和管理文件。 磁盘空间管理: 使用df -h命令查看磁盘空间使…

    2026年9月24日
    000
  • 高效集成SOAP服务:Spring Boot中WSDL转Java的实践与策略

    高效集成SOAP服务:Spring Boot中WSDL转Java的实践与策略高效集成SOAP服务:Spring Boot中WSDL转Java的实践与策略高效集成SOAP服务:Spring Boot中WSDL转Java的实践与策略高效集成SOAP服务:Spring Boot中WSDL转Java的实践与策略

    本教程旨在指导开发者如何在Spring Boot项目中将WSDL(Web Services Description Language)文件转换为Java类,并成功消费SOAP(Simple Object Access Protocol)Web服务。文章将探讨常见的转换挑战,如wsimport兼容性问…

    2026年9月24日 • 用户投稿
    100
  • 怎样让 AI 家居设计工具与豆包配合打造理想家居?实用教程​

    怎样让 AI 家居设计工具与豆包配合打造理想家居?实用教程​怎样让 AI 家居设计工具与豆包配合打造理想家居?实用教程​怎样让 AI 家居设计工具与豆包配合打造理想家居?实用教程​怎样让 AI 家居设计工具与豆包配合打造理想家居?实用教程​

    使用ai家居设计工具与豆包配合能提升家装效率,具体步骤如下:1. 利用ai工具生成设计方案,上传户型图并设定风格偏好,快速获取多个装修效果图;2. 将ai输出结果整理至豆包,为每个房间建立页面,添加说明、表格及标签以便查阅;3. 结合豆包优化预算和采购计划,记录材料价格并比对市场价,设置提醒避免遗漏…

    2026年9月24日 • 用户投稿
    100
  • Java中自定义与内置类同名冲突的解决方案:精确导入的实践

    Java中自定义与内置类同名冲突的解决方案:精确导入的实践Java中自定义与内置类同名冲突的解决方案:精确导入的实践Java中自定义与内置类同名冲突的解决方案:精确导入的实践Java中自定义与内置类同名冲突的解决方案:精确导入的实践

    本文探讨了Java中自定义类与内置类(如LinkedList)同名时引发的编译错误。当项目中同时存在自定义LinkedList和java.util.LinkedList时,程序可能错误地引用自定义实现,导致方法找不到。教程指出,通过精确导入java.util.LinkedList而非通配符java.…

    2026年9月24日 • 用户投稿
    200
  • AI聊天助手有哪些_好用的AI聊天助手工具大全

    AI聊天助手有哪些_好用的AI聊天助手工具大全AI聊天助手有哪些_好用的AI聊天助手工具大全AI聊天助手有哪些_好用的AI聊天助手工具大全AI聊天助手有哪些_好用的AI聊天助手工具大全

    ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜ 豆包:字节跳动推出的免费AI智能助手 问小白:免费AI智能助手,支持DeepSeek满血版 讯飞星火:AI智能助手,支持PPT生成、深度推理 逗逗:AI游戏陪玩,支持原神、黑神话、LOL! 立即…

    2026年9月24日 • 用户投稿
    200
  • sublime怎么把选中的代码片段发送到新的文件_sublime代码片段分离操作方法

    sublime怎么把选中的代码片段发送到新的文件_sublime代码片段分离操作方法sublime怎么把选中的代码片段发送到新的文件_sublime代码片段分离操作方法sublime怎么把选中的代码片段发送到新的文件_sublime代码片段分离操作方法sublime怎么把选中的代码片段发送到新的文件_sublime代码片段分离操作方法

    Sublime Text无一键发送代码到新文件功能,但可通过复制粘贴或拖拽方式快速实现:选中代码→复制→新建文件→粘贴并保存;或直接拖拽选中内容至标签栏创建新文件。 在 Sublime Text 中,目前没有直接的内置功能可以把选中的代码片段“一键发送”到一个新文件。但你可以通过几个简单的手动步骤快…

    2026年9月24日 • 用户投稿
    100
  • AIGC官网检测入口 知网免费查重直达链接

    知网AIGC检测与查重服务面向个人开放,官方入口为https://cx.cnki.net,按2元/千字符收费,提供简洁版与全文版报告,检测结果分四级标识AI生成风险,建议使用前确认学校要求并注意隐私保护。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 …

    2026年9月24日
    500
  • Java字符串处理:高效移除末尾逗号与空格的教程

    Java字符串处理:高效移除末尾逗号与空格的教程Java字符串处理:高效移除末尾逗号与空格的教程Java字符串处理:高效移除末尾逗号与空格的教程Java字符串处理:高效移除末尾逗号与空格的教程

    本教程将详细介绍如何在Java中高效、精确地移除字符串末尾的逗号、空格或其他指定分隔符。我们将探讨使用String.replaceAll()方法结合正则表达式的强大功能,以解决传统replace()方法无法精准定位末尾字符的问题,并提供多种场景下的示例代码与注意事项。 1. 引言:字符串清理的常见挑…

    2026年9月24日 • 用户投稿
    100

发表回复

登录后才能评论
关注微信