重构 改善既有代码的设计

重构 改善既有代码的设计 pdf epub mobi txt 电子书 下载 2025

[美] 马丁·福勒(Martin Fowler) 著,熊节 译
图书标签:
  • 重构
  • 代码设计
  • 软件工程
  • 代码质量
  • 可维护性
  • 设计模式
  • 编程实践
  • 技术书籍
  • 软件开发
  • 代码改进
想要找书就要到 新城书站
立刻按 ctrl+D收藏本页
你会得到大惊喜!!
出版社: 人民邮电出版社
ISBN:9787115369093
版次:2
商品编码:11728740
品牌:异步图书
包装:平装
开本:16开
出版时间:2015-08-01
用纸:胶版纸
页数:452
字数:490000

具体描述

产品特色


编辑推荐

软件开发的不朽经典
生动阐述重构原理和具体做法
普通程序员进阶到编程高手必须修炼的秘笈
重构,一言以蔽之,就是在不改变外部行为的前提下,有条不紊地改善代码。多年前,正是本书原版的出版,使重构终于从编程高手们的小圈子走出,成为众多普通程序员日常开发工作中不可或缺的一部分。本书也因此成为与《设计模式》齐名的经典著作,被译为中、德、俄、日等众多语言,在世界范围内畅销不衰。
《重构 改善既有代码的设计》凝聚了软件开发社区专家多年摸索而获得的宝贵经验,拥有不因时光流逝而磨灭的价值。今天,无论是重构本身,业界对重构的理解,还是开发工具对重构的支持力度,都与本书出版时不可同日而语,但书中所蕴涵的意味和精华,依然值得反复咀嚼,而且往往能够常读常新。

内容简介

《重构 改善既有代码的设计》清晰揭示了重构的过程,解释了重构的原理和实践方式,并给出了何时以及何地应该开始挖掘代码以求改善。书中给出了70 多个可行的重构,每个重构都介绍了一种经过验证的代码变换手法的动机和技术。《重构 改善既有代码的设计》提出的重构准则将帮助你一次一小步地修改你的代码,从而减少了开发过程中的风险。

作者简介

Martin Fowler,世界软件开发大师,在面向对象分析设计、UML、模式、XP和重构等领域都有卓越贡献,现为软件开发咨询公司ThoughtWorks的首席科学家。他的多部著作《分析模式》、《UML精粹》和《企业应用架构模式》等都已经成为脍炙人口的经典。

熊节,ThoughtWorks中国公司的高级咨询师、架构师和项目经理,在大型企业应用及互联网应用的架构和管理方面拥有丰富经验。作为敏捷方法学顾问和重构专家,他拥有在各种技术平台、编程语言、软件形态的项目中实施重构的丰富经验,并曾主持极具挑战性的超大规模电信软件系列重构工作。

内页插图

精彩书评

“这本书之于重构就相当于韵谱之于作诗。一个翻着韵书作诗的诗人一定是蹩脚的,但好的诗人却要对那109个韵部了然于胸;同样,一个好的程序员要求能够主动自然地重构代码,虽不应翻着重构手册干活,但需对本书中提到的70多个重构方法成竹在胸。然而,在达到这一境界之前,需要不断的时间和经验积累,并且要先读读Fowler的这本书。”

“一口气读完了这本书,感觉书中作者对代码的整理不像是一种技术,更像是一种艺术。”

“太经典了,看这本书真有醍醐灌顶的感觉。”

“处于金字塔顶部的书不多,而这一本书恰恰就是,很幸运我看到了它。”

“这本书本质上是向我们推荐了一种编程习惯和编程态度。在领会本书思想的同时,我们也应该培养一种精益求精的工作态度,探索一条更适合自己的重构道路。”

“今年已经看了两遍,每次都有很大的收获。特别喜欢其中对其他章节的索引,当你把它作为一个手边随时翻阅的参考书看时,它不知不觉引导你读了很多内容,问题也在不知不觉中有了求解思路,得以解决。”

“不要写完代码就束之高阁,适当地优化代码结构,能够为以后的开发带来许多方便,这本书就向你介绍了这方面的技巧,说得非常详细。”

“程序几乎离不开重构。但如何更加迅速有效地重构却一直没有系统性的指导。本书就是这样的经典巨著,有了它,重构不再烦琐!”

目录

第1章 重构,第一个案例 1
1.1 起点 1
1.2 重构的第一步 7
1.3 分解并重组statement() 8
1.4 运用多态取代与价格相关的条件逻辑 34
1.5 结语 52
第2章 重构原则 53
2.1 何谓重构 53
2.2 为何重构 55
2.3 何时重构 57
2.4 怎么对经理说 60
2.5 重构的难题 62
2.6 重构与设计 66
2.7 重构与性能 69
2.8 重构起源何处 71
第3章 代码的坏味道 75
3.1 Duplicated Code(重复代码) 76
3.2 Long Method(过长函数) 76
3.3 Large Class(过大的类) 78
3.4 Long Parameter List(过长参数列) 78
3.5 Divergent Change(发散式变化) 79
3.6 Shotgun Surgery(霰弹式修改) 80
3.7 Feature Envy(依恋情结) 80
3.8 Data Clumps(数据泥团) 81
3.9 Primitive Obsession(基本类型偏执) 81
3.10 Switch Statements(switch惊悚现身) 82
3.11 Parallel InheritanceHierarchies(平行继承体系) 83
3.12 Lazy Class(冗赘类) 83
3.13 Speculative Generality(夸夸其谈未来性) 83
3.14 Temporary Field(令人迷惑的暂时字段) 84
3.15 Message Chains(过度耦合的消息链) 84
3.16 Middle Man(中间人) 85
3.17 Inappropriate Intimacy(狎昵关系) 85
3.18 Alternative Classes with Different Interfaces(异曲同工的类) 85
3.19 Incomplete Library Class(不完美的库类) 86
3.20 Data Class(纯稚的数据类) 86
3.21 Refused Bequest(被拒绝的遗赠) 87
3.22 Comments(过多的注释) 87
第4章 构筑测试体系 89
4.1 自测试代码的价值 89
4.2 JUnit测试框架 91
4.3 添加更多测试 97
第5章 重构列表 103
5.1 重构的记录格式 103
5.2 寻找引用点 105
5.3 这些重构手法有多成熟 106
第6章 重新组织函数 109
6.1 Extract Method(提炼函数) 110
6.2 Inline Method(内联函数) 117
6.3 Inline Temp(内联临时变量) 119
6.4 Replace Temp with Query(以查询取代临时变量) 120
6.5 Introduce Explaining Variable(引入解释性变量) 124
6.6 Split Temporary Variable(分解临时变量) 128
6.7 Remove Assignments to Parameters(移除对参数的赋值) 131
6.8 Replace Method with Method Object(以函数对象取代函数) 135
6.9 Substitute Algorithm(替换算法) 139
第7章 在对象之间搬移特性 141
7.1 Move Method(搬移函数) 142
7.2 Move Field(搬移字段) 146
7.3 Extract Class(提炼类) 149
7.4 Inline Class(将类内联化) 154
7.5 Hide Delegate(隐藏“委托关系”) 157
7.6 Remove Middle Man(移除中间人) 160
7.7 Introduce Foreign Method(引入外加函数) 162
7.8 Introduce Local Extension(引入本地扩展) 164
第8章 重新组织数据 169
8.1 Self Encapsulate Field(自封装字段) 171
8.2 Replace Data Value with Object(以对象取代数据值) 175
8.3 Change Value to Reference(将值对象改为引用对象) 179
8.4 Change Reference to Value(将引用对象改为值对象) 183
8.5 Replace Array with Object(以对象取代数组) 186
8.6 Duplicate Observed Data(复制“被监视数据”) 189
8.7 Change Unidirectional Association to Bidirectional(将单向关联改为双向关联) 197
8.8 Change Bidirectional Association to Unidirectional(将双向关联改为单向关联) 200
8.9 Replace Magic Number with Symbolic Constant(以字面常量取代魔法数) 204
8.10 Encapsulate Field(封装字段) 206
8.11 Encapsulate Collection(封装集合) 208
8.12 Replace Record with Data Class(以数据类取代记录) 217
8.13 Replace Type Code with Class(以类取代类型码) 218
8.14 Replace Type Code with Subclasses(以子类取代类型码) 223
8.15 Replace Type Code with State/Strategy(以State/Strategy取代类型码) 227
8.16 Replace Subclass with Fields(以字段取代子类) 232
第9章 简化条件表达式 237
9.1 Decompose Conditional(分解条件表达式) 238
9.2 Consolidate Conditional Expression(合并条件表达式) 240
9.3 Consolidate Duplicate Conditional Fragments(合并重复的条件片段) 243
9.4 Remove Control Flag(移除控制标记) 245
9.5 Replace Nested Conditional with Guard Clauses(以卫语句取代嵌套条件表达式) 250
9.6 Replace Conditional with Polymorphism(以多态取代条件表达式) 255
9.7 Introduce Null Object(引入Null对象) 260
9.8 Introduce Assertion(引入断言) 267
第10章 简化函数调用 271
10.1 Rename Method(函数改名) 273
10.2 Add Parameter(添加参数) 275
10.3 Remove Parameter(移除参数) 277
10.4 Separate Query from Modifier(将查询函数和修改函数分离) 279
10.5 Parameterize Method(令函数携带参数) 283
10.6 Replace Parameter with Explicit Methods(以明确函数取代参数) 285
10.7 Preserve Whole Object(保持对象完整) 288
10.8 Replace Parameter with Methods(以函数取代参数) 292
10.9 Introduce Parameter Object(引入参数对象) 295
10.10 Remove Setting Method(移除设值函数) 300
10.11 Hide Method(隐藏函数) 303
10.12 Replace Constructor with Factory Method(以工厂函数取代构造函数) 304
10.13 Encapsulate Downcast(封装向下转型) 308
10.14 Replace Error Code with Exception(以异常取代错误码) 310
10.15 Replace Exception with Test(以测试取代异常) 315
第11章 处理概括关系 319
11.1 Pull Up Field(字段上移) 320
11.2 Pull Up Method(函数上移) 322
11.3 Pull Up Constructor Body(构造函数本体上移) 325
11.4 Push Down Method(函数下移) 328
11.5 Push Down Field(字段下移) 329
11.6 Extract Subclass(提炼子类) 330
11.7 Extract Superclass(提炼超类) 336
11.8 Extract Interface(提炼接口) 341
11.9 Collapse Hierarchy(折叠继承体系) 344
11.10 Form Tem Plate Method(塑造模板函数) 345
11.11 Replace Inheritance with Delegation(以委托取代继承) 352
11.12 Replace Delegation with Inheritance(以继承取代委托) 355
第12章 大型重构 359
12.1 Tease Apart Inheritance(梳理并分解继承体系) 362
12.2 Convert Procedural Design to Objects(将过程化设计转化为对象设计) 368
12.3 Separate Domain from Presentation(将领域和表述/显示分离) 370
12.4 Extract Hierarchy(提炼继承体系) 375
第13章 重构,复用与现实 379
13.1 现实的检验 380
13.2 为什么开发者不愿意重构他们的程序 381
13.3 再论现实的检验 394
13.4 重构的资源和参考资料 394
13.5 从重构联想到软件复用和技术传播 395
13.6 小结 397
13.7 参考文献 397
第14章 重构工具 401
14.1 使用工具进行重构 401
14.2 重构工具的技术标准 403
14.3 重构工具的实用标准 405
14.4 小结 407
第15章 总结 409
参考书目 413
要点列表 417
索引 419

前言/序言


《代码的艺术:精炼与演进》 在快速迭代的软件开发浪潮中,我们常常面临一个棘手的现实:那些曾经优雅设计的系统,随着时间的推移和需求的变迁,逐渐变得难以理解、难以维护,甚至成为阻碍创新的绊脚石。它们就像一座逐渐失修的古老建筑,虽然曾经辉煌,但如今却吱呀作响,危机四伏。这时,我们需要一种方法,能够审慎而有效地对现有代码进行“外科手术”,在不破坏原有功能的前提下,提升其内在的质量,使其焕发生机。 《代码的艺术:精炼与演进》正是这样一本深入探讨如何处理“遗留代码”的实战指南。它并非讲述如何从零开始构建全新的系统,而是聚焦于一个更具挑战性但也更普遍存在的场景——当我们继承、接手或不得不维护一个已经存在的、可能并不完美的代码库时,我们应该如何做。这本书的出发点是,几乎所有的软件系统最终都会走向“遗留”的命运,而对这些代码进行精心维护和持续改进,是工程师职业生涯中不可或缺的一部分。 理解遗留代码的本质与挑战 本书首先带领读者深入理解“遗留代码”的真正含义。它不仅仅是“旧”代码,更关键的是那些缺乏测试、文档稀少、设计不清晰、紧耦合严重、难以修改的代码。遗留代码带来的挑战是多方面的: 风险高昂的修改: 由于缺乏充分的测试覆盖,任何对遗留代码的修改都可能引发意想不到的副作用,导致线上故障,给业务带来损失。 理解困难的逻辑: 随着时间的推移,编写代码的初衷可能已不复存在,代码逻辑变得晦涩难懂,阅读和理解需要耗费大量精力。 技术债务的累积: 历史上的妥协、快速修复以及缺乏重构,导致技术债务不断累积,使得未来的开发成本越来越高。 创新受阻: 庞大而僵化的遗留代码库,使得引入新功能、新技术或进行架构升级变得异常困难,扼杀了创新的可能性。 团队士气低落: 长期与难以维护的代码打交道,会让开发者感到沮丧和疲惫,影响团队的整体士气和效率。 《代码的艺术》认为,面对遗留代码,逃避或完全重写往往不是最优解。重写固然可以带来全新的设计,但其巨大的风险、成本和时间投入,常常使得项目难以按时完成,甚至可能引入新的问题。因此,本书提倡的是一种“循序渐进、小步快跑”的改进策略,通过一系列经过验证的技术和方法,逐步净化代码,提升其质量。 精炼代码的原则与方法 本书的核心内容围绕着“精炼”二字展开。精炼并非粗暴的删减,而是通过一系列精细的操作,去除冗余、简化复杂、提升清晰度、增强可读性和可维护性。书中详细阐述了多种精炼代码的原则和具体方法: “三法则”与“YAGNI”的再审视: 在遗留代码环境中,这些经典的原则如何被理解和应用?如何避免在精炼过程中过度设计? 理解与探索: 如何有效地阅读和理解陌生的遗留代码?如何通过调试、日志、静态分析等手段,抽丝剥茧,找到问题的根源? 添加测试: 这是进行任何遗留代码重构的基石。本书将详细介绍如何为缺乏测试的代码编写单元测试、集成测试,甚至编写“契约测试”,为后续的重构提供安全网。即使是针对复杂的遗留模块,也能找到切入点,逐步增加测试覆盖率。 提取与封装: 如何将重复的代码段提取成独立的函数或方法?如何将紧耦合的类进行解耦,封装内部细节? 简化条件逻辑: 复杂的if-else语句、嵌套循环如何通过多态、策略模式、卫语句等方式进行简化? 消除重复与冗余: 如何识别并消除代码中的重复模式,减少维护成本? 重命名与清晰化: 恰当的命名是代码可读性的关键。本书将指导读者如何通过重命名变量、方法、类,使代码的意图更加明确。 参数传递的优化: 如何优化方法参数,减少过长的参数列表,提高方法的可调用性? 处理“魔法数字”与硬编码: 如何将硬编码的常量替换为有意义的命名常量或配置项,提高代码的可维护性? 拆分大型类与方法: 如何将臃肿的类和冗长的函数拆分成更小、职责更单一的单元? 引入设计模式的审慎: 在遗留代码中引入设计模式,何时是合适的时机?如何以最小的代价实现? 演进式设计的实践艺术 “演进”是本书另一个重要的主题。它强调代码的改进是一个持续的、逐步的过程,而非一次性的“大手术”。本书倡导的演进式设计,意味着在现有代码的基础上,进行小的、安全的、可控的改动,每一步都朝着更好的设计方向迈进。 “金丝雀发布”与“分支 by Abstraction”: 如何在不影响线上服务的前提下,测试和部署新的代码?如何利用抽象层来隔离和替换旧的模块? “截断”与“重写”的结合: 对于实在无法通过精炼改进的模块,如何设计一种“截断”策略,逐步用新的代码替换旧的实现,同时保证系统的稳定运行? 自动化重构工具的应用: 现代IDE提供了强大的自动化重构能力。本书将指导读者如何有效地利用这些工具,提高重构效率,降低人为失误。 度量与反馈: 如何通过代码度量工具(如圈复杂度、耦合度、代码覆盖率等)来量化代码质量的变化?如何建立有效的反馈机制,持续改进代码? “代码的演进图谱”: 本书将通过大量的真实案例,展示不同类型的遗留代码问题,以及如何运用书中介绍的方法,一步步将其转化为更健康、更易于维护的代码。这些案例涵盖了从小型函数到整个模块的演进过程,让读者能够直观地理解演进式设计的强大力量。 重构的文化与团队协作 《代码的艺术:精炼与演进》也深刻地认识到,代码的精炼与演进不仅仅是技术问题,更是一个关乎团队文化和协作的问题。 建立“代码健康”的文化: 如何在团队内部倡导对代码质量的重视?如何让每一位开发者都意识到维护遗留代码的重要性? 沟通与共识: 在进行重构时,如何与团队成员、产品经理进行有效沟通,解释重构的必要性和带来的收益? 知识分享与学习: 如何通过代码审查、技术分享等方式,促进团队成员之间的知识共享,共同提升代码质量? 避免“完美主义陷阱”: 在追求代码质量的同时,如何把握“适度”原则,避免陷入无休止的重构,影响项目进度? 本书的价值所在 《代码的艺术:精炼与演进》并非一本教人“写漂亮代码”的理论书籍,而是一本“实践出真知”的操作手册。它充满了实操性的建议、清晰的步骤和丰富的示例。阅读本书,你将能够: 掌握一套系统性的遗留代码处理方法论。 学会识别代码中的“坏味道”,并找到相应的解决方案。 在保证功能不丢失的前提下,自信地对现有代码进行改进。 显著提升代码的可读性、可维护性和可测试性。 降低开发和维护成本,加速新功能的开发。 提升团队的开发效率和代码质量。 最终,构建出更具弹性和生命力的软件系统。 无论你是经验丰富的资深工程师,还是刚刚步入软件开发领域的新人,《代码的艺术:精炼与演进》都将是你手中不可或缺的工具。它将帮助你告别对遗留代码的恐惧,拥抱代码演进的乐趣,最终成为一名更优秀的软件工程师,用精炼的艺术,雕琢出稳健而优雅的软件世界。

用户评价

评分

这本书是一次关于“代码优化”的哲学之旅。它让我从更深层次去理解“为什么”我们需要重构。很多时候,我们沉浸在功能的实现中,而忽略了代码长期的健康。这本书提醒我,代码不仅仅是机器执行的指令,更是人与人之间沟通的桥梁。那些“魔术数字”、“全局变量”等“坏味道”,在书中得到了细致的剖析,让我意识到它们是如何悄无声息地侵蚀代码质量的。书中提供的“代码气味列表”就像一个诊断手册,我可以在工作中对照,及时发现并解决潜在的问题。更重要的是,这本书让我理解了重构是一种持续的过程,而不是一次性的任务。它鼓励我们保持敏锐的“代码嗅觉”,并不断追求更优的设计。读完这本书,我感觉自己不仅仅是一个码农,更是一个有追求的“代码工匠”,时刻关注着代码的“身心健康”,致力于打造经得起时间考验的软件。

评分

我是一个刚入行不久的开发者,面对公司里那些庞大且复杂的遗留系统,常常感到束手无策。这本书就像一座灯塔,为我指明了方向。它没有那些晦涩难懂的术语,而是用一种非常平实易懂的方式,将重构的要领一一呈现。我尤其喜欢书中关于“保持行为不变”的原则,这让我明白了重构的本质不是为了“创造”,而是为了“优化”。通过书中的例子,我学会了如何在不改变程序功能的前提下,一点点地改进代码结构,让它变得更加清晰和易于理解。那些关于“提取超类”、“隐藏委托”等章节,让我对如何组织和管理代码有了新的认识。这本书不仅提升了我的技术能力,更重要的是,它给了我面对复杂代码的勇气和信心。感觉现在即使面对一个陌生的项目,我也能从中找到切入点,进行有效的代码改进。

评分

如果说编程是一门艺术,那么重构就是让这门艺术更加精湛的画笔。这本书的内容让我领略到了代码之美。它不仅仅是讲授技术,更是在传递一种“工程师的思维方式”。我曾经以为,写好代码只需要掌握最新的技术和框架,但这本书让我意识到,优秀的代码设计和长期的可维护性才是真正的核心竞争力。书中对“意图表达”的强调,让我开始思考如何让代码本身就能“说话”,让其他开发者(或者未来的自己)能够快速理解代码的意图。我尝试着在自己的项目中应用书中介绍的一些重构模式,比如“移动方法”、“替换继承为组合”,效果立竿见影。代码的可读性大大提高,bug也明显减少。这本书就像一本“秘籍”,里面藏着让代码“返老还童”的绝世武功。读完之后,我感觉自己对代码的“品味”都提升了,不再满足于仅仅实现功能,而是开始追求代码的“美感”和“生命力”。

评分

我一直认为,写出能工作的代码只是第一步,让代码易于理解、易于维护,这才是真正考验开发者功力的环节。这本书恰恰解决了我的这个痛点。它没有那种虚无缥缈的理论,而是从实际开发中遇到的各种问题出发,提供了切实可行的解决方案。书中对“坏味道”的诊断和治理,简直是开发者福音。我常常会遇到那种“意大利面条式”的代码,逻辑纠缠不清,改动任何一点都可能引发连锁反应。读了这本书,我学会了如何识别这些“坏味道”,并有条不紊地运用各种重构技巧去“净化”它们。特别是关于“封装”、“组合”等概念的阐述,让我看到了如何将复杂的逻辑解耦,让代码模块化、可复用性更强。这本书就像一位经验丰富的导师,循循善诱地指导我如何写出更清晰、更健壮、更有弹性的代码。我尤其欣赏书中强调的“测试先行”的重构理念,这保证了重构过程的安全性,让我敢于大胆地去优化代码。

评分

这本书简直是一场代码的“整容手术”,让我对“重构”这个词有了全新的认识。以前觉得重构就是改改名字、挪挪位置,让代码看起来顺眼一点,但这本书彻底颠覆了我的认知。它深入浅出地剖析了如何系统性地、有策略地对现有代码进行改进,而不仅仅是表面上的修饰。我特别喜欢书中提到的“小步快跑”原则,每一次小的重构都能带来明确的改进,而且风险极低,让我这种对大规模改动心存畏惧的开发者感到无比安心。书中列举的各种重构手法,比如“提取方法”、“合并字段”、“替换条件表达式为多态”等等,每一个都配有清晰的图示和代码示例,让人一学就会。而且,它不仅仅是告诉“怎么做”,更重要的是解释了“为什么这么做”,让我理解了每种重构背后的设计思想和收益。读完这本书,我感觉自己不仅仅是学会了几个技巧,更是提升了对代码质量和设计原则的深刻理解,仿佛打开了一扇通往“优雅代码”的大门。感觉以后面对那些“遗留代码”不再头疼,而是充满信心去“拯救”它们。

评分

经常在京东买书,头一次碰到这种情况,非常的扎心!

评分

给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力给力

评分

!!!!?。?!

评分

很不错很不错很不错很不错很不错

评分

一次买了5本,原价四百多,一百三十多拿下,这是本经典!

评分

朋友推荐的,感觉不错,好好看看

评分

书非常好,放在购物车已经很久了,赶上年中的购物节非常高兴,赶快把所有的书都买了,关键是一点便宜便宜便宜,重要的事儿说三遍

评分

书不错,主要是优惠太大,根本忍不住,囤啊囤

评分

非常好的一本书,重构改善既有代码的设计。代码整洁,是每个程序员的必要,不断的去改变原有的代码,也是每个程序员进阶提高的必胜法宝。赶上京东做活动很便宜,很值得。

相关图书

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 book.cndgn.com All Rights Reserved. 新城书站 版权所有