(11) - 替换switch语句
用switch语句时,当通过增加一个新类对基于switch结构的系统进行修改时,程序员可能会忘记将其添加到现有的所有switch结构中。每次新增和删除一个类都需要修改系统中的所有switch结构,但追踪这些语句非常耗时,而且也容易出错。这是就多态性编成而言的。
重构后
01.
public
boolean
isLeap(
int
year) {
02.
return
(year %
4
==
0
&& year %
100
!=
0
) || (year %
400
==
0
);
03.
}
04.
05.
public
static
int
getMonthDays(
int
year,
int
month) {
06.
int
numberDays =
0
;
07.
08.
switch
(month) {
09.
case
1
:
10.
case
3
:
11.
case
5
:
12.
case
7
:
13.
case
8
:
14.
case
10
:
15.
case
12
:
16.
numberDays =
31
;
17.
break
;
18.
19.
case
4
:
20.
case
6
:
21.
case
9
:
22.
case
11
:
23.
numberDays =
30
;
24.
break
;
25.
26.
case
2
:
27.
numberDays = isLeap(year) ?
29
:
28
;
28.
break
;
29.
}
30.
31.
return
numberDays;
32.
}
01.
public
boolean
isLeap(
int
year) {
02.
return
(year %
4
==
0
&& year %
100
!=
0
) || (year %
400
==
0
);
03.
}
04.
05.
private
int
getFebruaryDays(
int
year) {
06.
return
this
.isLeap(year) ?
29
:
28
;
07.
}
08.
09.
public
int
getMonthDays(
int
year,
int
month) {
10.
int
[] months =
new
int
[] {
31
,
this
.getFebruaryDays(year),
31
,
30
,
31
,
30
,
11.
31
,
31
,
30
,
31
,
30
,
31
};
12.
13.
return
months[month];
14.
}
(12) - 使用对象分装参数
当一个方法参数太多时,我一般认为超过4个的时候
重构后
1.
public
int
getRemainMinutes(
int
hour,
int
minute,
2.
int
fromHour,
int
fromMinute
3.
int
toHour,
int
toMinute) {
4.
......
1.
public
int
getRemainMinutes(DatePart datePart) {
2.
......
谈(13) - 封装集合操作
01.
public
Class Group{
02.
03.
private
List<User> userList =
new
ArrayList<User>();
04.
05.
public
void
setUserList(List<User> userList){
06.
this
.userList = userList;
07.
}
08.
09.
public
List<User> getUserList(){
10.
return
this
.userList;
11.
}
12.
}
01.
public
Class Group{
02.
03.
private
List<User> userList =
new
ArrayList<User>();
04.
05.
public
void
setUserList(List<User> userList){
06.
this
.userList = userList;
07.
}
08.
09.
public
List<User> getUserList(){
10.
return
this
.userList;
11.
}
12.
13.
public
void
addUser(User user){
14.
this
.getUserList().add(user);
15.
user.setGroup(
this
);
16.
}
17.
18.
public
void
removeUser(User user){
19.
this
.getUserList().remove(user);
20.
user.setGroup(
null
);
21.
}
22.
}
(14) - 使用委派代替继承
当子类从关系上根本不是父类的继承时
Child 和Sanitation (公共设施)是没有逻辑上的父子关系,因为小孩不可能是一个公共设施吧!所以我们为了完成这个功能可以考虑使用委派的方式。
同理,如果反过来,委派的对象明显应该是子类,就应该改成继承
01.
public
class
Sanitation
02.
{
03.
public
String WashHands()
04.
{
05.
return
"Cleaned!"
;
06.
}
07.
}
08.
09.
public
class
Child
extends
Sanitation
10.
{
11.
12.
}
01.
public
class
Sanitation
02.
{
03.
public
String WashHands()
04.
{
05.
return
"Cleaned!"
;
06.
}
07.
}
08.
09.
public
class
Child
10.
{
11.
private
Sanitation sanitation;
12.
13.
public
Child()
14.
{
15.
sanitation =
new
Sanitation();
16.
}
17.
18.
public
String WashHands()
19.
{
20.
return
sanitation.WashHands();
21.
}
22.
}
(15) - 面向接口编程
超过一个的类要使用某一个类中部分方法时,我们应该解开它们之间的依赖,让调用者使用接口,这很容易实现也可以降低代码的耦合性
重构后
01.
public
class
ClassRegistration
02.
{
03.
public
void
Create() {
04.
//代码
05.
}
06.
07.
public
void
Transfer() {
08.
//代码
09.
}
10.
}
11.
12.
public
class
RegistrationProcessor
13.
{
14.
public
void
;P rocessRegistration(ClassRegistration registration)
15.
{
16.
registration.Create();
17.
registration.Transfer();
18.
}
19.
}
01.
public
interface
IClassRegistration
02.
{
03.
public
void
Create();
04.
05.
public
void
Transfer();
06.
}
07.
08.
public
class
ClassRegistration
implements
IClassRegistration
09.
{
10.
public
void
Create()
11.
{
12.
//代码
13.
}
14.
15.
public
void
Transfer()
16.
{
17.
//代码
18.
}
19.
}
20.
21.
public
class
RegistrationProcessor
22.
{
23.
public
void
;P rocessRegistration(IClassRegistration registration)
24.
{
25.
registration.Create();
26.
registration.Transfer();
27.
}
28.
}
(16) - 用策略模式代替if else和switch
好处是隔开耦合,以注入的形式实现功能,这使增加功能变得更加容易和简便,同样也增强了整个系统的稳定性和健壮性。
但并不是所有情况都要这么改,而是从意义上符合策略模式。
重构后
但并不是所有情况都要这么改,而是从意义上符合策略模式。
01.
public
class
ClientCode{
02.
public
double
CalculateShipping()
03.
{
04.
ShippingInfo shippingInfo =
new
ShippingInfo();
05.
return
shippingInfo.CalculateShippingAmount(State.Alaska);
06.
}
07.
}
08.
09.
public
enum
State
10.
{
11.
Alaska,
12.
NewYork,
13.
Florida
14.
}
15.
16.
public
class
ShippingInfo
17.
{
18.
public
double
CalculateShippingAmount(State shipToState)
19.
{
20.
if
(shipToState == State.Alaska)
return
GetAlaskaShippingAmount();
21.
else
if
(shipToState == State.NewYork)
return
GetNewYorkShippingAmount();
22.
else
if
(shipToState == State.Florida)
return
GetFloridaShippingAmount();
23.
else
return
0d;
24.
}
25.
26.
private
double
GetAlaskaShippingAmount()
27.
{
28.
return
15d;
29.
}
30.
31.
private
double
GetNewYorkShippingAmount()
32.
{
33.
return
10d;
34.
}
35.
36.
private
double
GetFloridaShippingAmount()
37.
{
38.
return
3d;
39.
}
40.
}
01.
public
class
ClientCode
02.
{
03.
public
IShippingInfo ShippingInfo;
04.
05.
public
double
CalculateShipping()
06.
{
07.
return
ShippingInfo.CalculateShippingAmount(State.Alaska);
08.
}
09.
}
10.
11.
public
enum
State
12.
{
13.
Alaska,
14.
NewYork,
15.
Florida
16.
}
17.
18.
public
class
ShippingInfo
implements
IShippingInfo
19.
{
20.
private
Map<State, IShippingCalculation> shippingCalculations;
21.
22.
public
ShippingInfo(List<IShippingCalculation> shippingList)
23.
{
24.
shippingCalculations =
new
HashMap<State, IShippingCalculation>();
25.
for
(IShippingCalculation calc : shippingList)
26.
{
27.
shippingCalculations.put(calc.state(), calc);
28.
}
29.
}
30.
31.
public
double
CalculateShippingAmount(State shipToState)
32.
{
33.
return
shippingCalculations.get(shipToState).Calculate();
34.
}
35.
}
36.
37.
public
interface
IShippingCalculation
38.
{
39.
State state();
40.
41.
double
Calculate();
42.
}
43.
44.
public
class
AlaskShippingCalculation
implements
IShippingCalculation
45.
{
46.
public
State State()
47.
{
48.
return
State.Alaska;
49.
}
50.
51.
public
double
Calculate()
52.
{
53.
return
15d;
54.
}
55.
}
56.
57.
public
class
NewYorkShippingCalculation
implements
IShippingCalculation
58.
{
59.
public
State State()
60.
{
61.
return
State.NewYork;
62.
}
63.
64.
public
double
Calculate()
65.
{
66.
return
10d;
67.
}
68.
}
69.
70.
public
class
NewYorkShippingCalculation
implements
IShippingCalculation
71.
{
72.
public
State State()
73.
{
74.
return
State.Florida;
75.
}
76.
77.
public
double
Calculate()
78.
{
79.
return
13
;
80.
}
81.
}
(17) - 分解复杂判断
把原来复杂的条件判断等语句用尽快返回等方式简化代码
重构后
01.
public
interface
ISecurityChecker{
02.
public
boolean
CheckPermission(String user, String permission);
03.
}
04.
public
class
Security
05.
{
06.
public
ISecurityChecker securityChecker;
07.
08.
public
Security(ISecurityChecker securityChecker) {
09.
this
.securityChecker = securityChecker;
10.
}
11.
12.
public
boolean
HasAccess(String user, String permission, List exemptions)
13.
{
14.
boolean
hasPermission =
false
;
15.
if
(user !=
null
)
16.
{
17.
if
(permission !=
null
)
18.
{
19.
if
(exemptions.size() ==
0
)
20.
{
21.
if
(securityChecker.CheckPermission(user, permission) || exemptions.contains(permission))
22.
{
23.
hasPermission =
true
;
24.
}
25.
}
26.
}
27.
}
28.
return
hasPermission;
29.
}
30.
}
01.
public
interface
ISecurityChecker
02.
{
03.
public
boolean
CheckPermission(String user, String permission);
04.
}
05.
public
class
Security
06.
{
07.
public
ISecurityChecker securityChecker;
08.
09.
public
Security(ISecurityChecker securityChecker) {
10.
this
.securityChecker = securityChecker;
11.
}
12.
13.
public
boolean
HasAccess(String user, String permission, List exemptions)
14.
{
15.
if
(user ==
null
|| permission ==
null
)
return
false
;
16.
if
(exemptions.contains(permission))
return
true
;
17.
return
securityChecker.CheckPermission(user, permission);
18.
}
19.
}
(18) - 契约式设计
契约式设计规定方法应该对输入和输出进行验证,这样你便可以保证你得到的数据是可以工作的,一切都是按预期进行的,如果不是按预期进行,异常或是错误就应该被返回,下面我们举的例子中,我们方法中的参数可能会值为null的情况,在这种情况下由于我们没有验证,NullReferenceException异常会报出
重构后
01.
public
class
Customer
02.
{
03.
public
double
balance;
04.
05.
public
double
getBalance()
06.
{
07.
return
balance;
08.
}
09.
10.
public
void
setBalance(
double
balance)
11.
{
12.
this
.balance = balance;
13.
}
14.
}
15.
16.
public
class
CashRegister
17.
{
18.
public
double
TotalOrder(List<Double> products, Customer customer)
19.
{
20.
double
total =
0
;
21.
for
(Double prise : products)
22.
{
23.
total += prise;
24.
}
25.
total += customer.getBalance();
26.
return
total;
27.
}
28.
}
01.
public
class
CashRegister
02.
{
03.
public
double
TotalOrder(List<Double> products, Customer customer)
04.
{
05.
if
(customer ==
null
)
throw
new
IllegalArgumentException(
"Customer cannot be null"
);
06.
07.
if
(products ==
null
|| products.isEmpty())
throw
new
IllegalArgumentException(
"Must have at least one product to total"
);
08.
09.
double
total =
0
;
10.
for
(Double prise : products)
11.
{
12.
total += prise;
13.
}
14.
total += customer.getBalance();
15.
return
total;
16.
}
17.
}
(19) - 除去上帝类
当一个类职责太大,方法实在太多,可以考虑细化成多个类
重构后
01.
public
class
CustomerService
02.
{
03.
public
double
calculateOrderDiscount()
04.
{
05.
//实现
06.
}
07.
08.
public
boolean
customerIsValid()
09.
{
10.
//实现
11.
}
12.
13.
public
boolean
register()
14.
{
15.
//实现
16.
}
17.
18.
public
boolean
forgotPassword()
19.
{
20.
//实现
21.
}
22.
}
01.
public
class
CustomerOrderService
02.
{
03.
public
double
calculateOrderDiscount()
04.
{
05.
//实现
06.
}
07.
08.
public
boolean
customerIsValid()
09.
{
10.
//实现
11.
}
12.
}
13.
14.
public
class
CustomerRegistrationService
15.
{
16.
public
boolean
register()
17.
{
18.
//实现
19.
}
20.
21.
public
boolean
forgotPassword()
22.
{
23.
//实现
24.
}
25.
}
(20) - 尽快返回
当条件判断对性能消耗较大时,这种的写法得尽可能避免
重构后
01.
public
boolean
test()
02.
{
03.
boolean
result;
04.
if
(条件判断) result =
true
;
05.
else
(条件判断) result =
false
;
06.
else
(条件判断) result =
true
;
07.
else
(条件判断) result =
false
;
08.
else
(条件判断) result =
true
;
09.
else
(条件判断) result =
false
;
10.
else
result =
true
;
11.
return
result;
12.
}
01.
public
boolean
test()
02.
{
03.
if
(条件判断)
return
true
;
04.
else
(条件判断)
return
false
;
05.
else
(条件判断)
return
true
;
06.
else
(条件判断)
return
false
;
07.
else
(条件判断)
return
true
;
08.
else
(条件判断)
return
false
;
09.
else
return
true
;
10.
}
相关推荐
总结,OMP压缩感知重构方法通过高效的迭代算法,实现了在低采样率下的信号重构,具有重要的理论价值和实用意义。了解并掌握这一技术,有助于我们在实际问题中实现资源的有效利用,提高系统性能。对于研究者和工程师...
- **应用实例**:通过对IEEE33节点配电网进行故障模拟,演示了如何使用本代码快速找到最优的网络重构方案。结果显示,在不同的故障情况下,算法都能够有效提高电压质量,并且重构过程直观清晰。 #### 六、参考文献...
【C语言初学,近千行代码,word高亮总结,附有富文本下的word语法高亮模板】 在学习C语言的过程中,掌握基本的输入输出、函数传参和常见算法是至关重要的。这篇总结包含了这些核心知识点,通过近千行的代码实例帮助...
总结起来,这篇以“CS_OMP_博士论文_论文matlab_matlab_重构算法”为主题的压缩包内容,提供了一篇关于压缩感知重构算法——正交匹配追踪算法的matlab仿真代码,旨在帮助读者深入理解OMP算法的原理和实现过程,是...
这本书被视为《代码大全》的姊妹篇,承载了作者在微软公司超过十年的工作经验,是微软软件工程师必读之作。它深入探讨了软件开发流程、技术、方法论等多个层面的知识,旨在为软件开发者提供宝贵的经验教训。 首先,...
10. **代码重构与设计模式**:遵循面向对象设计原则,运用设计模式(如单例、工厂、观察者等),并进行定期的代码重构,可以保持代码的清晰性和可维护性。 通过阅读“VC编程经验总结.chm”文件,你可以深入学习和...
#### 四、代码重构技巧 **原文摘要:** - **重构的重要性**:重构是提高代码质量和性能的有效手段之一。 - **重构策略**:在重构过程中,应保持原有功能不变的同时优化代码结构;重构之前应对原有代码进行全面测试...
5. **代码重构**:定期审查并重构代码,去除冗余和不必要的逻辑。 四、利用`NSObject`增强`UIViewController` `UIViewController`继承自`NSObject`,因此可以利用`NSObject`的一些特性来优化代码,如KVO(Key-Value...
本文主要介绍了如何利用Vue框架重构有赞商城,并分享了相关的开发思路和总结。文章首先提出了利用Vue进行重构的多页面...总体来说,本文对于希望掌握Vue框架重构大型应用的开发者来说,是一篇具有较高实用价值的文章。
本篇通过对淘宝左侧分类导航代码的解析,不仅了解了其基本结构和样式设置,还深入探讨了其中所涉及的技术细节及其在实际应用中的局限性。对于开发者而言,学习此类代码不仅可以增强对HTML和CSS的理解,还可以启发...
代码重构 * Ctrl + Alt + T:快速将当前代码 try/catch,if/else 等包起来 * Shift + F6:重命名文件 * Ctrl + Shift + F:全局查找 * Ctrl + Alt + S:打开设置对话框 * Ctrl + U:转到父类 代码导航 * Ctrl + ...
这篇文章提出了一种新的数据表示方法,旨在捕捉数据的主要结构,同时消除噪声和冗余信息。 低秩表示的基本思想是,许多实际问题中的数据集都可以近似地表示为一个低秩矩阵,即矩阵的秩远小于其行数或列数。这种表示...
本篇将重点介绍WebStorm中的快捷键和代码模板,帮助你更好地利用这款工具。 ### 一、WebStorm快捷键 快捷键是提升开发效率的关键,掌握WebStorm的常用快捷键能够让你在编写代码时更加得心应手。以下是一些常用的...
总结来说,实现Java代码的移方块游戏(或贪吃虫游戏)的关键在于正确处理键盘事件,以及合理地管理游戏对象的状态。通过创建键盘监听器并响应按键事件,我们可以使游戏对象根据用户的输入改变行为。同时,合理地设计...
总结,TMS320C6000系列下的MPEG-2视频压缩标准源代码实现,不仅展示了数字信号处理技术在视频编码领域的应用,也为我们提供了优化和定制解码器的参考。通过深入学习和实践,开发者可以充分利用TMS320C6000的强大性能...
26. **分析代码**:包括代码解释、性能评估、错误检测、重构建议等,确保代码的质量和效率。 27. **解释具体部分**:对代码的特定行或函数进行解释,帮助理解其作用。 28. **对照指导原则**:检查代码是否符合编程...
本篇讨论的主题是将这种理念应用于机器人实验室的学习空间重构,以提升教育质量和效率。 物联网技术在泛在学习系统中的作用至关重要。物联网通过连接各种智能设备,如传感器、执行器和移动终端,收集并传输数据,...
这篇文章主要探讨的是在该版本中使用Microsoft SQL Server Management Studio (SSMS)进行T-SQL代码编辑的特性。 首先,Management Studio提供了一个集成的环境,用于处理不同类型的SQL Server数据库产品中的查询...
这篇总结将深入探讨在Vector Cast环境下进行UT工程时可能遇到的问题以及解决方案。 1. **Vector Cast介绍**:Vector Cast 是一套全面的静态和动态测试工具,包括单元测试、覆盖率分析、静态分析等功能。它提供了一...