《设计模式解析(第2版•修订版)》—第1章 1.4节应对变化:使用功能分解

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 更进一步地来看“显示形状”问题。怎样编写代码才能更容易地应付多变的需求呢?与其编写一个大函数,不如使之更加模块化。

本节书摘来自异步社区《设计模式解析(第2版•修订版)》一书中的第1章,第1.4节应对变化:使用功能分解,作者【美】Alan Shalloway(艾伦•沙洛维) , James R.Trott(詹姆斯•R.特罗特),更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.4 应对变化:使用功能分解
设计模式解析(第2版•修订版)
用模块化封装变化

更进一步地来看“显示形状”问题。怎样编写代码才能更容易地应付多变的需求呢?与其编写一个大函数,不如使之更加模块化。

例如,在前面提到的步骤4c“以形状的位置作为参数,调用显示形状的函数”中,可以写一个例1-1所示的模块。

例1-1 用模块化封装变化

函数:显示形状
输入:形状类型,形状描述
操作:

switch (形状类型)
    case 方形:调用显示方形的函数
    case 圆形:调用显示圆形的函数

功能分解方法中模块化的问题

然后,在接到一个需求,要显示新的形状(例如三角形)时,我只需改变这个模块即可。(希望如此!)

但是这种方法仍然存在问题。比如,前面说过,这个模块的输入是形状的类型和描述。然而,在不同的形状存储方式下,对所有形状都适用的一致描述可能存在,也可能不存在。如果形状的描述有时以包含坐标点的数组方式存储,有时以其他方式存储,怎么办呢?这种方法还适用吗?

模块化肯定有助于提供代码的可理解性,而容易理解将使代码更容易维护。但是模块化并不总是有助于代码应对所有可能遇到的变化。

低内聚,紧耦合

这种方法我一直在使用,我发现它主要有两个问题,按术语来说就是低内聚(weak cohesion)和紧耦合(tight coupling)。在Code Complete一书(Microsoft Press, 1993)中,Steve McConnell对内聚性和耦合性有很精彩的描述。他说:

内聚性(cohesion)指的是“例程中操作之间联系的紧密程度”1。

我还听说过有人将内聚性称为清晰性(clarity),因为例程(或类)中的多个操作联系越紧密,就越容易理解其含义。说一个类低内聚,指的就是它任务很多而且互不相关,代码经常看上去像是令人疑惑的一大团。最极端的情形下,这些类会与系统中差不多所有东西都纠缠在一起,据说有人称之为“上帝对象”,因为它们好像是万能的(或许是因为只有上帝才能理解它们)。

耦合性(coupling)指的是“两个例程之间联系的紧密程度。耦合性与内聚性是相辅相成的关系。内聚性描述的是一个例程内部组成部分之间相互联系的紧密程度,而耦合性描述的是一个例程与其他例程之间联系的紧密程度。软件开发的目标应该是创建这样的例程:内部完整(高内聚),而与其他例程之间的联系则是小巧、直接、可见、灵活的(松耦合)。” 2

修改一个函数甚至是函数所用的数据,都可能对其他函数产生严重破坏

大多数程序员都会有这样的经验:在代码的某个地方修改了一个函数或一个数据,后来却对代码的其他地方造成了意想不到的影响,这种bug称为“不良副作用”。这是因为,虽然我们获得了希望的结果(进行了修改),但是也得到了不需要的结果——bug!更糟糕的是,这些bug经常难以发现,因为我们一开始往往不会注意到那些导致副作用的代码联系(如果能够注意到这些联系,就不会用这种方式修改程序了)。

事实上,这种bug使我有了一个非常惊人的发现:我们实际上并没有花费很多时间改正程序的bug。

我认为,在维护和调试过程中,改正bug只需要花费很少的时间。维护和调试的绝大多数时间都被用于努力弄清代码的运作机理、寻找bug和防止出现不良副作用上了,真正的改正时间却相当短!

因为不良副作用经常是最难发现的bug,所以如果让一个函数处理很多不同的数据,一旦需求发生变化,就更可能出问题。

问题就出在副作用中

只关注函数,就可能引起难以发现的副作用。
维护和调试中所耗费的大多数时间不是花在修改bug上,而是花在寻找bug,弄清如何避免在修改代码时导致不良副作用上了。
功能分解将注意力放在错误的地方

使用功能分解时,需求变更会对软件开发和维护工作产生极大影响。这时候,主要的精力都放在函数上了,而对一组函数或者数据的修改会影响到其他函数和数据,并依此类推地影响到其他必须修改的函数。就像一个雪球滚下山来,一路裹挟了更多的雪一样,只关注函数,将导致一连串变化,而且难以避免。

1 McConnell S.,Code Complete: A Practical Handbook of Software Construction,Redmond: Microsoft Press,1993,p. 81。(请注意,这些术语并不是McConnell发明的,发明者是Ed Yourdon 和 Constantine。我们只是碰巧更喜欢McConnell的定义而已。)
2同上,第87页。
本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

相关文章
|
14天前
|
数据可视化 数据挖掘 BI
团队管理者必读:高效看板类协同软件的功能解析
在现代职场中,团队协作的效率直接影响项目成败。看板类协同软件通过可视化界面,帮助团队清晰规划任务、追踪进度,提高协作效率。本文介绍看板类软件的优势,并推荐五款优质工具:板栗看板、Trello、Monday.com、ClickUp 和 Asana,助力团队实现高效管理。
39 2
|
6天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
6天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
6天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
6天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
6天前
|
设计模式 Java 程序员
【23种设计模式·全精解析 | 概述篇】设计模式概述、UML图、软件设计原则
本系列文章聚焦于面向对象软件设计中的设计模式,旨在帮助开发人员掌握23种经典设计模式及其应用。内容分为三大部分:第一部分介绍设计模式的概念、UML图和软件设计原则;第二部分详细讲解创建型、结构型和行为型模式,并配以代码示例;第三部分通过自定义Spring的IOC功能综合案例,展示如何将常用设计模式应用于实际项目中。通过学习这些内容,读者可以提升编程能力,提高代码的可维护性和复用性。
【23种设计模式·全精解析 | 概述篇】设计模式概述、UML图、软件设计原则
|
10天前
|
小程序 安全 搜索推荐
陪玩小程序的搭建解析与功能需求
陪玩小程序是为玩家提供专业陪玩服务的应用,嵌入社交或游戏平台,具备智能匹配、实时聊天、预约服务等功能,支持便捷高效的游戏体验。源码交付时需提供详细文档、技术支持及定制开发服务,确保客户能顺利维护和升级。选择陪玩小程序时应关注功能需求、用户体验、安全性和成本效益,以确保最佳使用效果。
36 0
|
27天前
|
存储 安全 数据安全/隐私保护
深入解析iOS 14隐私保护功能:用户数据安全的新里程碑
随着数字时代的到来,个人隐私保护成为全球关注的焦点。苹果公司在最新的iOS 14系统中引入了一系列创新的隐私保护功能,旨在为用户提供更透明的数据使用信息和更强的控制权。本文将深入探讨iOS 14中的几项关键隐私功能,包括App跟踪透明性、简化的隐私设置以及增强的系统安全性,分析它们如何共同作用以提升用户的隐私保护水平。
80 3
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。

推荐镜像

更多