《重构-改善既有代码的设计》读书笔记
2023-02-18 16:36:34 时间
作者:Grey
原文地址:《重构-改善既有代码的设计》读书笔记
以查询取代临时变量
临时变量的问题在于:它们是暂时的,而且只能在所属函数内使用。由于临时变量只能在所属函数内可见,所以它们会趋势你写出更长的函数,因为只有这样你猜可以访问到所需要的临时变量,如果把临时变量替换为一个查询,那么同一个类中的所有函数都可以获得这份信息。
示例
double getPrice() {
int basePrice = number * itemPrice;
double discountFactor;
if (basePrice > 1000) discountFactor = 0.95;
else discountFactor = 0.98;
return basePrice * discountFactor;
}
将临时变量声明为final
double getPrice() {
final int basePrice = number * itemPrice;
final double discountFactor;
if (basePrice > 1000) discountFactor = 0.95;
else discountFactor = 0.98;
return basePrice * discountFactor;
}
把赋值动作的右侧表达式提炼出来
double getPrice() {
final int basePrice = getBasePrice();
final double discountFactor = getDiscount();
return getBasePrice() * discountFactor;
}
int getBasePrice() {
return number * itemPrice;
}
double getDiscount() {
if (getBasePrice() > 1000) return 0.95;
else return 0.98;
}
最后
double getPrice() {
final int basePrice = getBasePrice();
return getBasePrice() * getDiscount();
}
int getBasePrice() {
return number * itemPrice;
}
double getDiscount() {
if (getBasePrice() > 1000) return 0.95;
else return 0.98;
}
引入解释性变量
你有一个复杂的表达式,将该复杂的表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表达式的用途。
if ((platform.toUpperCase().indexOf("MAC") > -1) &&
(browser.toUpperCase().indexOf("IE") > -1) &&
wasInitialized() && resize > 0)
{
// do something
}
可以重构为:
final boolean isMacOS = platform.toUpperCase().indexOf("MAC") > -1;
final boolean isIEBrowser = platform.toUpperCase().indexOf("IE") > -1
final boolean wasResized = resize > 0;
if (isMacOS && isIEBrowser && wasInitialized() && wasResized)
{
// do something
}
分解临时变量
如果你的程序有某个临时变量赋值超过一次,它既不是循环变量也不是结果收集变量,这就意味着这个临时变量在函数中承担了一个以上的责任,如果临时变量承担多个责任,就应该针对每次赋值,创造一个独立,对应的临时变量。
double temp = 2 * (height + width);
System.out.println(temp);
temp = height * width;
System.out.println(temp);
应该改写成:
final double perimeter = 2 * (height + width);
System.out.println(perimeter);
final double area = height * width;
System.out.println(area);
以函数对象取代函数
将这个函数放进一个单独的对象中,如此一来局部变量就成了对象内的字段,然后你可以在同一个对象中将这个大型函数分解为多个小型函数
class Account {
int gamma(int inputVal, int quantity, int yearToDate) {
int importantValue1 = (inputVal * quantity) + delta();
int importantValue2 = (inputVal * yearToDate) + 100;
if ....
....
....
return importantValue3 - 2 * importantValue1;
}
}
第一步:把这个函数变为一个函数对象,并加入一个构造函数
class Gamma {
private final Account account;
private int inputVal;
private int quantity;
private int yearToDate;
private int importantValue1;
private int importantValue2;
pirvate int importantValue3;
Gamma(Account account, int inputVal, int quantity, int yearToDate) {
this.xx = xx
...
...
...
}
}
现在可以把原本的函数搬到compute()中了,
int compute() {
int importantValue1 = (inputVal * quantity) + account.delta();
int importantValue2 = (inputVal * yearToDate) + 100;
if ....
....
....
return importantValue3 - 2 * importantValue1;
}
然后,我们修改旧的函数:
int gamma(int inputVal, int quantity, int yearToDate) {
return new Gamma(this, inputVal, quantity, yearToDate).compute();
}
相关文章
- 如何看待中国联通与腾讯成立(云计算)合营公司?
- 一个核心,四张王牌!中国移动“连楹”如何赋能千家万户,连接亿万设备?
- 中国移动未来三大定位!哪些专业公司将迎来发展良机?
- 大数据面试题(一):HDFS核心高频面试题
- 大数据面试题(二):Hadoop的联邦机制核心高频面试题
- 数实融合突破虚实界限 中国移动咪咕开创世界杯观赛新玩法
- 大数据面试题(三):MapReduce核心高频面试题
- 大数据面试题(四):Yarn核心高频面试题
- 大数据面试题(五):Hadoop优化核心高频面试题
- 大数据面试题(六):ZooKeeper核心高频面试题
- 2023年三大运营商竞争格局将变?电信一攻一守、移动一守一攻、联通游击!
- 护城墙坍塌?5G专网放开,对运营商影响几何?
- 三、教你搞懂渐变堆叠面积图《手把手教你 ECharts 数据可视化详解》
- 深度!杨杰董事长回答了“数字经济”的三个问题,关系中国移动的未来
- 中国移动黄宇红:影响未来信息通信发展的十大跨界创新方向
- 中国移动:2023年派息率将提升至70%以上 累计分红超1.1万亿
- 表面风光?运营商政企业务需自我警醒“集成商陷阱”!
- 算力网络是中美科技路线分野之处,中国移动能发挥什么作用?
- 记一次线上问题 → 对 MySQL 的 ON UPDATE CURRENT_TIMESTAMP 的片面认知
- 精彩纷呈!亚信科技深度参与2022中国移动全球合作伙伴大会