陆陆续续的发表了多篇关于重构的文章了,还是那句话,重构是一个项目迭代开发中必不可少的一个阶段。其实重构伴随着你的项目的整个阶段。在前几篇关于重构的文章中我们谈到了函数的重构、类的重构、数据的重构以及条件表达式的重构,那么今天咱们就来聊聊继承关系的重构。当然还是延续前几篇博客的风格,我们在博客中的代码实例依然使用Swift语言来实现,当然还是那句话,使用什么语言无所谓,关键是看重构的场景以及重构的思想。

“重构”不仅仅可以改善你既有的代码设计,还可以改变你组织代码的思路,使你的程序在设计之初就趋于合理化,利于程序的扩充。重构往往伴随着设计模式的使用,在重构系列的博客结束后,我想系统的给大家分享一下关于设计模式的东西。当然是结合着各种实例。所谓一名Coder,重构和设计模式是必须涉猎的部分,因为这两者可以让你写出更漂亮的代码,当然要想真正的掌握设计模式以及各种重构手法,还得结合不同的实例来进行实践。理论固然重要,但是要想将理论的东西变成你自己的,还必须将理论付诸实践。废话少说,进入今天的主题。

一.Pull Up Field (字段上移) & Pull Down Field (字段下移)

字段上移与字段下移是相对的,也是我们之前所说的“凡事都有其两面性”,我们要辩证的去看待。我们只对Pull Up Field (字段上移) 这个规则做讨论,那么关于Pull Down Field (字段下移)我们不做过多的讨论,因为这两条规则是相反的,理解一条后,把这条规则反过来就是我们要理解的另一条规则。这样说起来,还是比“举一反三”要容易的多。

下方这个实例是为了解释“字段上移”所实现的一个Demo。当然Demo看上去不仅简单而且是有些夸张的,不过说明字段上移这个规则是完全足够了的。比如我们有一个父类为MySuperClass,我们有一个子类SubClass1,而在SubClass1中有一个字段父类是没有的。因为后期需求迭代或者需求变更,我们需要再创建一个SubClass1的兄弟类,就是下方的SubClass2。在SubClass2中与SubClass1中存在相同的字段,那就是var a = 0。

在上述情况下,就需要使用到我们的“字段上移”的规则。也就是说将子类中相同的字段移到父类中。在该实例中就是讲var a = 0 移到父类中。重构后的代码如下所示:

而将“Pull Down Field (字段下移)”正好与上面的情况相反。也就是父类中有某些字段,但是这些字段只有在少数子类中使用到,在这种情况下我们需要将这个字段移到相应的子类中即可。除了Pull Up Field (字段上移) & Pull Down Field (字段下移) 这两个规则外,Pull Up Method (将函数上移) 和 Pull Down Method (将函数下移)这两个规则与上述情况类似。就是将上面的字段改成函数,有时候不仅字段会出现上述情况,函数也会出现上述情况,需要我们进行移动。因为使用场景类似,再次就不做过多的赘述了。

二、Extract Subclass (提炼子类)

这种情况下用的还是比较多的,当类中的某些方法只有在特定的类的实例中才会使用到,此时我们就需要提炼出一个子类,将该方法放到相应的子类中。这样一来我们的每个类的职责更为单一,这也就是我们常说的“单一职责”。

在下方示例中,CustomerBook是一个图书消费者的类。其中customeCharge()方法是普通用户计算消费金额所需的方法,而vipCharge()方法是VIP用户调用的方法,在内部vipCharge()需要调用customeCharege()方法。但是对外部而言,vipCharge()方法只有VIP用户才会用到,在这种情况下我们就需要使用“Extract Subclass (提炼子类)”规则对VIP进行提炼。

具体做法是我们需要提炼出一个子类,也就是说将VIP用户作为普通用户的子类,然后将只有VIP用户才调用的方法放到我们的VIP子类中。这样一来层次更加明确,每个类的职责更为单一。上述示例重构后的结果如下所示。

与“提炼子类”规则相对应的是“Collapse Hierarchy (折叠继承关系)”。一句话来概括:就是当你的父类与子类差别不大时,我们就可以将子类与父类进行合并。将上面的示例翻转就是“Collapse Hierarchy (折叠继承关系)”规则的示例,再次就不做过多的赘述了。

三、Form Template Method (构造模板函数)

Form Template Method (构造模板函数)这一规则还是比较实用的。先说模板,“模板”其实就是框架,没有具体的实现细节,只有固定不变的步骤,可以说模板不关心具体的细节。举个栗子,像前段时间比较火的“秘密花园”,那些没有颜色的线条就是模板,如果一些人获取的是同一本秘密花园,那么说明每个人所获取的模板是相同的。但是每个人对每块的区域所图的颜色又有差异,这就是实现细节的不同。

言归正传,当两个兄弟类中的两个函数中的实现步骤大致一直,但是具体细节不同。在这种情况下,我们就可以将大体的步骤提取成模板,放到父类中,而具体细节由各自的子类来实现。具体实现请看下方的类,在Subclass1和Subclass2中的calculate()方法中的大体步骤是相同的,就是对两个值相加,然后返回这两个值的和。但是具体细节不同,可以看出两个相加值的具体计算方式不同。

在上述情况下我们就可以使用“Form Template Method (构造模板函数)”规则将相同的计算流程进行提取,也就是构造我们的模板函数。将模板函数放到两个类的父类中,然后在相应的子类中只给出实现细节即可。下方代码段是重构后的代码,父类中多出的方法就是我们提取的模板函数,而子类中只给出相应的实现细节即可。

四、以委托取代继承(Replace Inheritance with Delegation)

有时候我们为一些类创建子类后,发现子类只使用了父类的部分方法,而且没有继承或者部分继承了父类的数据。在这种情况下我们就可以将这种继承关系修改成委托的关系。具体做法就是修改这种继承关系,在原有子类中添加父类的对象字段,在子类中创建相应的方法,在方法中使用委托对象来调用原始父类中相应的方法。

下方示例是我们假想出来的,但是说明该规则是绰绰有余了。我们假设SubClass01类中只会用到SuperClass01中的display()方法,而没有继承父类中的数据。在下方示例中是继承关系,在这种情况下我们需要将其转换成委托关系。

下方是我们重构后的代码,在下方代码中我们去除了之前的继承关系。并在子类中创建了一个之前父类的代理对象,并且创建了一个相应的方法,在该新建的方法中通过代理对象来调用相应的方法。具体如下所示。

上述规则与以继承取代委托(Replace Delegation with Inheritance)原则相对于,使用情况与上述相反,再次就不做过多的赘述了。

几天博客就先到这儿,内容比较简单,但是还是比较重要的。

代码重构(五):继承关系重构规则相关推荐

  1. JAXB根据带继承关系的类生成soap请求的XML报文(互转)

    文章目录 生成的请求报文与需要解析的响应报文 使用Apache CXF或者jdk自带的wsimport生成客户端代码 不生成客户端代码 类的继承关系 包结构与package-info.java 将子类 ...

  2. 热血传奇服务端FIR0918源码服务端Actor继承关系以及注解

    首先要声明一下,Fir0918服务端方面个人感觉实在是渣 代码各种乱入,写此博客只是记录自己学习的点滴.并不是来告诉大家fir的代码有多好. TBaseObject 只有四个成员 对象所在地图的X,Y ...

  3. 代码重构(二):类重构规则

    在上篇博客<代码重构(一):函数重构规则(Swift版)>中,详细的介绍了函数的重构规则,其中主要包括:Extract Method, Inline Method, Inline Temp ...

  4. 代码重构(一):函数重构规则

    [笔记] 以下是通用的代码重构规则 python代码重构技巧看这里:Python重构代码的一些模式 ========================== 重构是项目做到 一定程度后必然要做的事情.代码 ...

  5. Winform打砖块游戏制作step by step第5节---重构代码,利用继承多态

    一 引子 为了让更多的编程初学者,轻松愉快地掌握面向对象的思考方法,对象继承和多态的妙用,故推出此系列随笔,还望大家多多支持. 二 本节内容---重构代码,利用继承多态 1. 主界面截图如下: 2.  ...

  6. 跟狗屎一样的代码,到底该如何重构?

    跟狗屎一样的代码,到底该如何重构? 跟大家分享一下,跟狗屎一样的代码,到底该如何重构?其实,代码都是不断改出来的,没有谁一开始就能写出漂亮的代码,因为需求都是不断变更的.在不断变更代码的时候,对代码进 ...

  7. 代码的坏味道与重构技术

    一.前言 本文大部分内容.图片来自Martin Flower的<Refactoring>一书以及refactoringguru网站(一个很棒的网站),之前在博客发表过,这次属于整理后重新发 ...

  8. 低代码发展专访系列之六:低代码平台能解决业务重构的问题么?

    编辑 | 曹芊芊 话题:低代码发展系列专访 前言:2019年开始,低代码爆火.有人认为它是第四代编程语言,有人认为它是开发模式的颠覆,也有人认为是企业管理模式的变革--有很多声音,社区讨论很热烈.CS ...

  9. UML类图五种关系与代码的对应关系

    UML类图中的五种关系的耦合强弱比较:依赖<关联<聚合<组合<继承 一.依赖关系: (一)说明 虚线+箭头 可描述为:Uses a 依赖是类的五种关系中耦合最小的一种关系. 因 ...

最新文章

  1. 浅谈GSM/GPRS模块软硬件设计(基于有方M660+模块和单片机)
  2. 1.20(设计模式)模板模式
  3. mysql pxc测试_Mysql同步机制 - PXC 压力测试 tpcc安装及使用
  4. java猜数游戏图形界面_Java做一个猜数的小游戏
  5. Activity 模版样式简介
  6. vue数据改变了,视图不更新不刷新问题
  7. [USACO 07DEC]Best Cow Line, Gold
  8. 长语音识别_长文本语音识别_语音 识别 - 云+社区 - 腾讯云
  9. ps切图后 JAVA开发_2018年设计师都在用的PS切图插件--摹客
  10. vagrant lanp mysql远程登录设置
  11. 以太坊合并后下跌22%,我们分析链上的数据看看是否能找到答
  12. 【二〇二一·立秋】读书笔记
  13. XFire野猪书-XFire开发指南第二版
  14. IE浏览器url中出现中文访问404问题解决
  15. 关于Unity LitJson写入数据报错的问题
  16. Matlab外部程序接口
  17. 人工神经网络 :模糊神经网络
  18. LeetCode 每日一题1584. 连接所有点的最小费用
  19. 初级开发和中级,高级的区别_如何从初级开发人员过渡到中级开发人员
  20. 电信4G添加ctlte接入点提高网速

热门文章

  1. Centos 7 64位 minimal 最小化安装的系统中静默安装oracle 11g r2(无图形化安装)
  2. linux更改用户的shell,Linux下通过shell更改用户密码
  3. 航空频率表 2020_航空波段+调频、中波、短波,这个美国TR608收音机值40美元吗?...
  4. 计算机应用计算题(88)10,计算机应用考试习题(88页)-原创力文档
  5. Win2008 R2 IIS7 PHP 5.4 环境搭建图文教程
  6. 洛谷P1265 公路修建题解
  7. Luogu4099 HEOI2013 SAO 组合、树形DP
  8. 洛谷——P2590 [ZJOI2008]树的统计(树链剖分模板练手)
  9. 5G通信3大场景 来源:elecfans
  10. DropDownList联动