重构8.11-8.16

8.11、封装集合

什么时候用?  

有个函数返回一个集合(集合的处理方式应该和其他种类的数据略有不同。取值函数不该返回函数本身因为这会让用户得以修改集合内容而集合拥有者却一无所知)

怎么用?

让这个函数返回该集合的一个只读副本,并在这个类中提供添加/移除集合元素的函数。

具体步骤:

1、 加入为集合添加/移除元素的函数

2、 为保存集合的字段初始化为一个空集合,编译

3、 找出集合设值函数的所有调用者,可以修改设值函数让它调用新建的“添加/移除元素”函数,也可以直接修改调用端,改让它们调用新建的“添加/移除元素”函数,编译测试。

4、 找出所有“通过取值函数获得集合并修改其内容”的函数,逐一修改这些函数,让它们改用添加/移除函数。每次修改后,编译并测试。

5、 修改完上述所有“通过取值函数获得集合并修改其内容”的函数后,修改取值函数自身,使它返回该集合的一个只读副本。(在Java2中可以使用collection.unmodifiabblexxx()得到该集合的只读副本)编译,测试。

6、 找出取值函数的所有用户,从中找出应该存在于集合所属对象内的代码,运用提炼函数和搬移函数将这些代码移到寄主对象去。(如果使用的是Java2那么本项重构到此为止,如果用的是Java1那么还需要下列步骤)

7、 修改现有取值函数的名字,然后添加一个新的取值函数,使其返回一个枚举,找出旧取值函数的所有被使用点,将他们都改为使用新取值函数。

8、 如果这一步跨度太大,可以先使用函数改名修改原取值的名称,再建立一个新取值函数用以返回枚举,最后再修改所有调用者,使其调用新取值函数。编译测试。

8.12、以数据类取代记录

什么时候用?

面对传统编程环境中记录结构

怎么用?

为该记录创建一个“哑”数据对象(看起来类似外部记录的类)

具体步骤:

1、 新建一个类表示这个记录

2、 对于记录中的每一项数据,在新建的类中建立对应的一个private字段,并提供相应的取值/设值函数。

8.13、以类取代类型码

什么时候用?

类中有一个数值类型码,但它并不影响类的行为

怎么用?

以一个新的类替换该数值类型码

具体步骤:

1、 为类型码建立一个类(这个类需要一个用以记录类型码的字段,其类型应该和类型码相同,并有对应的取值函数)

2、 修改源类实现,让它使用上述新建的类(修改类型码相关函数),编译测试。

3、 对于源类中每一个使用类型码的函数,相应建立一个函数,让新函数使用新建的类。(需要建立“以新类实例为自变量”的函数,用以替换原先“直接以类型码为参数”的函数,还需建立一个“返回新类实例”的函数用以替换原先“直接返回类型码”的函数)

4、 逐一修改源类用户,让它们使用新接口

5、 每修改一个用户,编译并测试。

6、 删除使用类型码的旧接口,并删除保存旧类型码的静态变量,编译并测试。

8.14、以子类取代类型码

什么时候用?

有一个不可变的类型码,它会影响类的行为(如果类型码不会影响寄主类的行为可以使用以类取代类型码,如果影响寄主类的行为那么最好的办法就是借助多态来处理变化行为)

怎么用?

以子类取代这个类型码

具体步骤:

1、使用自封装字段将类型码自我封装起来(如果类型码被传递给构造函数,就需要将构造函数换成工厂函数)

2、为类型码的每一个数值建立一个相应的子类。在每个子类中覆写类型码的取值函数,使其返回相应的类型码值(这个值暂时被硬编码于return中,如:return 1)

3、每建立一个新的子类,编译并测试

4、从超类中删除保存类型码的字段,将类型码访问函数声明为抽象函数。编译并测试。

8.15、以state/strategy取代类型码

什么时候用?

有一个类型码,它的行为会影响类的行为,但无法通过继承手法消除它

怎么用?

以状态对象取代类型码

具体步骤:

1、使用自封装字段将类型码自我封装起来

2、新建一个类,根据类型码的用途为它命名。这就是一个状态对象。

3、为这个新类添加子类,每个子类对应一种类型码。

4、在超类中建立一个抽象的查询函数,用以返回类型码。在每个子类中覆写该函数,返回确切的类型码。编译测试

5、在源类中建立一个字段,用以保存新建的状态对象

6、调整源类中负责查询类型码的函数,将查询动作转发给状态对象

7、调整源类中为类型码设值的函数,将一个恰当的状态对象子类赋值给“保存状态对象”的那个字段。编译并测试

8.16、以字段取代子类

什么时候用?

各个子类的差别只在于“返回常量数据”的函数身上

怎么用?

修改这些函数,使他们返回超类中的某个(新增)字段,然后销毁子类(尽管常量函数有其用途,但如果子类中只有常量函数,实在没有足够存在的价值)

具体步骤:

1、对所有子类使用以工厂函数取代构造函数

2、如果有任何代码直接引用子类,令它改而引用超类

3、针对每个常量函数,在超类中声明一个final字段

4、为超类声明一个protected构造函数,用以初始化这些新增字段。

5、新建或修改子类构造函数,使它调用超类的新增构造函数。编译并测试。

6、在超类中实现所有常量函数,令它们返回相应字段值,然后将该函数从子类中删除。

7、每删除一个常量函数,编译并测试。

8、子类中所有的常量函数都被删除后,使用内联函数将子类构造函数内联到超类的工厂函数中,编译并测试。

9、将子类删除,编译并测试。

10、重复“内联构造函数、删除子类”过程,直到所有子类都被删除

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值