重构手法——提炼函数、搬移函数、以多态取代条件表达式

目录

    • 我的心路历程
    • 我的学习概括
      • Extract Method(提炼函数)
        • 动机*--做法
        • 动机--做法*
      • Move Method(搬移函数)
        • 动机*--做法
        • 动机--做法*
      • Replace Conditional with Polymorphism(以多态取代条件表达式)
        • 动机*--做法
        • 动机--做法*

我的心路历程

今天开始学习《重构改善既有代码的设计》这本书。我首先翻阅了前言部分,书中写了什么是重构。什么是重构?

我的思考心路:
对于重构的认识,我认为程序开发并不是一个设计后即动作的行为,它需要在开发过程中持续整理程序,最大限度减少引入错误的概率的过程。

继续翻阅前言,书中写了本书有什么。告诉了书本的章节对应内容。第1章是一个重构的Demo,第2章是重构的原则定义,第3章是“坏代码”的味道,第5-12章是核心部分——重构的一些手法,等等。从哪开始快速入手看呢?

我的思考心路:
翻开第1章,我了解到这个Demo主要是个影片出租店程序,程序的功能是计算顾客消费金额并打印详单。翻看了第1章目录:起点–重构第一步–分解并重组statement()–运用多态取代与价格相关的逻辑条件–结语。我看看结语讲了什么?

翻阅结语,结语中表示第一章的Demo示范了数个重构手法。重构后的程序使责任分配更合理,这种风格,将迥异于过程化风格,也使码农难以再满足于结构化风格。看看Demo示范了那几个重构手法?

Demo中重构手法有:
P110 提炼函数
P142 搬移函数
P255 以多态取代条件表达式
P171 自封装字段
P227 以state/strategy取代类型码

我的学习概括

Extract Method(提炼函数)

动机*–做法

我自己的理解如下:
概念:
这个手法做法是,把可以被组织到一起的代码提炼到一个独立函数中,并用名称来表示用途。

应用场景:

  1. 过长的函数。
  2. 需要注释才能理解用途的代码。

达到目的:
得到简短而命名良好的函数。

优势:

  1. 函数粒度小,复用机会大,且覆写更容易。
  2. 使高层函数读起来像一系列注释。

动机–做法*

我自己的理解如下:
做法简图:
在这里插入图片描述

结合上图,我的关注点如下:

copy过程中注意安全:

  1. 源函数层面:注意考虑变量、参数的作用域
  2. 提炼出的代码层面:临时变量问题

意外1:
源函数中变量、参数的作用域与新函数不一致。
措施:若是局部变量,新函数里传入这部分参数。

意外2:
copy过程中临时变量被修改了。
措施:将被提炼代码段处理为一个查询,将结果赋值给相关变量。

Move Method(搬移函数)

动机*–做法

我自己的理解如下:

概念简图:

在这里插入图片描述

概念:
类A中函数Fun a与类B有调用关系的情况下,Fun a最常引用的类B中建立类似形为Fun a`的新函数,则Fun a变成单纯的委托函数,或可完全移除Fun a。

应用场景:

  1. 一个类有太多行为。
  2. 或类与类之间有太多合作而形成高度耦合。

达到目的:
使系统中的类更简单,系统任务交付更干脆。

动机–做法*

我自己的理解如下:
做法简图:
在这里插入图片描述

结合上图,我的关注点如下:
移动路径方向:函数Fun a与对象B交流比自己对象A交流多,所以搬移方向往B合适。

搬移过程中注意安全:

  1. 源类A的子类超类层面:若源类A的子类和超类,有函数Fun a的声明不能进行搬移。除非类B表现出多态性

意外1:
新目标类B中缺少对A的引用机制。
措施:把源对象类A的引用当作参数,传给新目标类B的Fun a`。

意外2:
Fun a包含异常处理,搬移后出现异常处理异常。
措施:根据逻辑判断某个异常该由哪个类处理,若类A负责,则异常处理留在类A。

Replace Conditional with Polymorphism(以多态取代条件表达式)

动机*–做法

我自己的理解如下:

概念简图:

在这里插入图片描述

概念:
将条件表达式的每个分支放进一个子类的覆写函数中,然后将原始函数声明为抽象函数。

应用场景:
同一组表达式在程序多个地方出现。

优势:

  1. 减少编写明显的条件表达式。
  2. 使“类型码switch语句”、“基于类型名称的if-then-else语句”出现减少。
  3. 避免条件表达式情况下,添加新类型时要更新所有表达式的缺点。
  4. 降低系统各部分间的依赖。

动机–做法*

我自己的理解如下:

结合上面的概念简图,我的关注点如下:
替换过程中注意安全:

  1. 多态性层面:必须有一个继承结构。它可以有2种选择来做到这个结构。一般情况下采取以子类取代类型码的方法。若出现对象已经创建后,要修改类型码;或者,要重构的类已经有子类,则采取以state/strategy取代类型码的方法。
  2. 超类层面:超类中某些private可能需要声明为protected。另外,超类中容纳条件表达式的函数要声明为抽象函数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/549222.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

FTP服务器架设详细图解

FTP是File Transfer Protocol(文件传输协议)的缩写,用来在两台计算机之间互相传送文件。FTP服务作为Internet最古老的服务之一,无论在过去还是现在都有着不可替代的作用。在企业中,对于一些大文件的共享,通…

IP-tools

IP-tools 网管员的第三只眼^ Ip-tools是一款功能齐全的网管软件,可以随时随地的向网管员报告网络的运行情况ip-tools自身集成多种tcp/ip使用工具,如本地信息、链接信息、端口扫描、ping、WHOIS、finger、nslookup、telnet、NetBIOS等功能。界面是全英的&…

用git提交代码到远程仓库遇到的问题

目录我的学习过程git环境配置(Mac版)git原理图git的push操作思路遇到的问题我的学习过程 昨天重写了一遍聊天程序,准备提交到git上进行代码管理。结果遇到了不少问题。我照着网上的教程进行操作,一步一步踩了很多坑。 git环境配…

git pull和push整理和归纳

目录各个模块概念工作区版本库暂存区远程仓库pull和push流程相关的命令暂存区相关版本库相关远程仓库相关利用远程仓库协作开发各个模块概念 我的理解: Git是版本管理工具,它主要对指定目录下的一些特定的文件的修改进行版本管理。 相关的模块有&#x…

Linux中点号,星号,加号,问号实战

目录Linux中的星号,点号和加号概念我的学习过程:我的思考过程:点号(.)星号(*)加号()问号(?)linux星号,点号,加号&#xf…

广播地址的计算方法(与运算、或运算)

目录我的学习过程Python中逻辑运算符notandor位运算符取反(~)与(&)或(|)广播地址计算方法IP地址子网掩码网络地址广播地址广播地址计算举例我的学习过程 今天学习UDP的单播、多播、广播中,…

Wt::WTreeNode

2019独角兽企业重金招聘Python工程师标准>>> A single node in a tree. 〔 这个 widget 渲染的是一棵树的一个节点。〕 A tree list is constructed by combining several tree node objects in a tree hierarchy, by passing the parent tree node as the last arg…

匿名内部类探究——它是一个实例

目录我的学习过程匿名内部类概述匿名内部类探究代码验证(匿名内部类是一个实例)结论我的学习过程 昨天想学习一下Java8新特性,看到Lambda表达式可以替代匿名内部类。我对匿名内部类不太理解,决定学习一下。并进行了下面的归纳和思…

Lambda表达式及应用

目录Lambda表达式概念应用在forEach()方法使用用来替代匿名内部类代码验证(Lambda表达式替代匿名内部类)Lambda表达式 概念 语法形式: () -> {} 组成: 括号:表示参数列表;箭头:表示lambda…

网络地址和广播地址的快速计算方法

目录前提条件方法原理网络地址快速计算示例广播地址快速计算示例前提条件 由IP地址和子网掩码,快速计算网络地址和广播地址。 小窍门前提:当子网掩码组成只有255和0组成时。 方法原理 利用255(或者0)和其他数字的&&#xf…

把十六进制字符转换成十进制数

2019独角兽企业重金招聘Python工程师标准>>> /*** Get the hex value of a character (base16).* param c A character between 0 and 9 or between A and F or* between a and f.* return An int between 0 and 15, or -1 if c was not a hex digit.*/public stat…

SQL Server更新某一列中多个字典码对应内容(sql示例)

目录示例-查询出多个字典码对应的内容示例-替换多个字典码对应的内容说明CHARINDEXFOR XML PATH示例-查询出多个字典码对应的内容 建立表格:学生-学习科目表student_study 注意:科目kemu列内容是字典码,需要更换成对应内容。 建立表格&…

mybatisPlus中的field-strategy(字段更新插入策略):null值插入和更新问题

目录mybatisPlus中null值插入和更新问题实际项目解决方法示例一实际项目解决方法示例二field-strategy字段更新插入策略介绍枚举类FieldStrategy源码枚举类字段简介mybatisPlus中null值插入和更新问题 配置mybatisPlus的项目中,默认进行了不是全量更新的策略&#…

linux构建主从域名服务器

实验步骤:一、构建主域名服务器1、安装域名服务(BIND服务器软件包)BIND软件包是目前Linux下使用最广泛的DNS服务器安装包,它可以运行到大多数UNIX服务器中,也包括Linux系统。RHEL4默认没有安装BIND服务器软件包&#x…

管道过滤器(Pipe-And-Filter)模式

按照《POSA(面向模式的软件架构)》里的说法,管道过滤器(Pipe-And-Filter)应该属于架构模式,因为它通常决定了一个系统的基本架构。管道过滤器和生产流水线类似,在生产流水线上,原材料在流水线上经一道一道的…

PCI_Express规范第七章解读-Software Initialization and configuration

7.Software Initialization and configuration PCI EXPRESS Configuration model 支持两种配置空间的访问机制: -PCI 兼容配置机制:100%的二进制兼容PCI 2.3中定义的,以及兼容早期的OS或类似的总线枚举和配置软件。 -PCI Express增强配置机制…

Asp.net基础概念之 事件

.NET Framework中的事件 事件体系结构 引发事件的对象叫做事件源。事件源发布它可以引发的事件。事件的类型总是委托类型,这个委托类型的签名定义了处理该事件的方法的签名。定义事件处理程序方法的对象称为事件接收方。事件接收方预订要在事件源上处理的事件事件接…

Facebook图片存储架构技术全解析

Haystack提出了一种通用的基于HTTP的对象存储,它含有指针,映射到存储对象。在Haystack中以指针储存照片,把数以十万计的图像聚集到一个Haystack存储文件,从而消除了元数据负荷。这就使得元数据的开销非常小,并且使我们…

Shiro授权流程图

Shiro授权流程Shiro授权流程图Shiro授权流程图 根据Shiro授权流程,绘制流程图如下: