- 浏览: 115071 次
- 性别:
文章分类
最新评论
-
airskys:
世故
教你世故的方法
有的时候我还是觉得还是外国人能
把这一套 ...
转载:如何避免制造敌人 -
rtdb:
绿阳科技 写道全文读完,感觉受益非浅,可奇怪的是,为什么好像没 ...
转载:如何避免制造敌人 -
绿阳科技:
全文读完,感觉受益非浅,可奇怪的是,为什么好像没什么人看呢?
转载:如何避免制造敌人 -
Wingel:
这个,我还真不知道。年轻人,总喜欢用简单的一两句,很精僻的概述 ...
转载:你不可能在争辩中获胜 -
realdah:
我最不喜欢的就是那些愚蠢而又不肯承认的人
转载:如果你错了就承认
完整:
http://wingel.iteye.com/topics/download/3589b4d8-8e29-4560-b0e7-8cb15a8ed995
或者
http://www.blogjava.net/Files/Wingel/%E7%AC%AC4%E7%AB%A0%E4%BF%9D%E6%8C%81%E4%BB%A3%E7%A0%81%E7%AE%80%E6%B4%81.rar
第4章 保持代码简洁
示例
这是一个会议管理系统。它用来管理所有参会者的信息。刚开始的时候,我们只需要记录每个参会者的ID(这是会议组织者分配的),姓名,电话和地址就行。于是,我们写了如下的代码:
class Participant {
String id;
String name;
String telNo;
String address;
}
class ConferenceSystem {
Participant participants[];
}
接着,新的需求来了:现在每个参会者都可以让组织者帮忙预订酒店,所以我们要记录下他想预订的酒店名,入住日期,离开日期,房间类型(单人房或者双人房)。于是我们又扩充成如下的代码:
class Participant {
String id;
String name;
String telNo;
String address;
boolean bookHotelForHim;
String hotelName;
Date checkInDate;
Date checkOutDate;
boolean isSingleRoom;
void setHotelBooking(String hotelName, Date checkInDate, ...) {
...
}
}
接着,又有一个新的需求来了:参会者可以参加不同的研讨会,所以我们要记录下参会者参加的研讨会。对于他要参加的每一场研讨会,我们还要记录下他的登记时间,同时他还需要什么翻译设备。于是代码又扩充成:
class Participant {
String id;
String name;
String telNo;
String address;
boolean bookHotelForHim;
String hotelName;
Date checkInDate;
Date checkOutDate;
boolean isSingleRoom;
String idOfSeminarsRegistered[];
Date seminarRegistrationDates[];
boolean needSIDeviceForEachSeminar[];
void setHotelBooking(String hotelName, Date checkInDate, ...) {
...
}
void registerForSeminar(String seminarId, Date regDate, boolean needSIDevice) {
//将seminarId加到idOfSeminarsRegistered
//将regDate加到seminarRegistrationDates
//将needSIDevice加到needSIDeviceForEachSeminar.
}
boolean isRegisteredForSeminar(String seminarId) {
...
}
Date getSeminarRegistrationDate(String seminarId) {
...
}
boolean needSIDeviceForSeminar(String seminarId) {
...
}
String [] getAllSeminarsRegistered() {
return idOfSeminarsRegistered;
}
}
代码开始肿胀起来了
请注意,这已经是我们第二次扩充Participant这个类了。每扩充一次,它就包含了更多的代码(实例变量和方法)及更多的功能。本来它只有4个属性。现在已经是12个了!此外,这个类要处理的业务逻辑也极大的增加了。本来它只需要处理参会者的基本信息(姓名,地址等等),现在它还要包含酒店,酒店预订,研讨会和翻译设备等等的逻辑。如果以后新的需求又来了,我们又要扩充Participant这个类,到时候,这个类要复杂庞大成什么样子!
所以我们得修整这个类了!
那怎么修整Participant这个类呢?怎么让它一直保持在第一天那样的简洁度?在回答这两个问题之前,我们先来考虑一下另一个需要优先回答的问题:给你一个类,你怎么认定它需要修整?
怎么判断一个类需要修整
要判断一个类是否需要修整,一个比较主观的方法是:当在读一个类的代码时,看看我们会不会觉得这个类“太长了”,“太复杂了”,或者讲的概念“太多了”?如果会这样觉得的话,我们就认定,这个类需要修整。
另外一个比较简单而且客观的方法是:当发现我们已经在第二次或者第三次扩充这个类的时候,我们认定这个类要修整了。这是一个比较”懒惰,被动”的方法,但却很有效。
现在让我们看一下怎么修整Participant这个类吧。
抽取出有关酒店预订的功能
首先,先来考虑一下怎么抽取出酒店预订的功能。一个可行的方案是:
class Participant {
String id;
String name;
String telNo;
String address;
}
class HotelBooking {
String participantId;
String hotelName;
Date checkInDate;
Date checkOutDate;
boolean isSingleRoom;
}
class HotelBookings {
HotelBooking hotelBookings[];
void addBooking(HotelBooking booking) {
...
}
}
class ConferenceSystem {
Participant participants[];
HotelBookings hotelBookings;
}
现在,Participant这个类就一点都不知道酒店预订的存在。当然,我们不一定要用数组来存放酒店预订情况。比如,我们可以用Map:
class Participant {
String id;
String name;
String telNo;
String address;
}
class HotelBooking {
String participantId;
String hotelName;
Date checkInDate;
Date checkOutDate;
boolean isSingleRoom;
}
class HotelBookings {
HashMap mapFromPartIdToHotelBooking;
//必须提供参会者id
void addBooking(String participantId, HotelBooking booking) {
...
}
}
class ConferenceSystem {
Participant participants[];
HotelBookings hotelBookings;
}
这样的方案优点是Participant一点都不知道HotelBooking的存在,Participant不依赖于HotelBooking。
还有另一个可行的方案是:
class Participant {
String id;
String name;
String telNo;
String address;
HotelBooking hotelBooking;
}
class HotelBooking {
String hotelName;
Date checkInDate;
Date checkOutDate;
boolean isSingleRoom;
}
class ConferenceSystem {
Participant participants[];
}
注意到,在这种方案里面,Participant这个类还是要知道HotelBooking的存在,也就是说,Participant还是要知道有酒店预订这回事。只是具体酒店预订是怎么做的,这些真正的功能是放在HotelBooking这个里面实现的。因为每个Participant都直接引用了本人的酒店预订情况,所以可以直接找到他的酒店预订情况。而代价就是,Pariticipant还是要知道酒店预订的概念。从类的关系来讲,Pariticipant还要依赖HotelBooking这个类。
当然,除了以上几种情况,还有许多其他的可行方案。
抽取研讨会的相关功能
现在我们来考虑一下怎么抽取出研讨会的功能。一个可行的方案:
class Participant {
String id;
String name;
String telNo;
String address;
}
class SeminarRegistration {
String participantId;
String seminarId;
Date registrationDate;
boolean needSIDevice;
}
class SeminarRegistry {
SeminarRegistration registrations[];
void registerForSeminar(SeminarRegistration registration) {
//将registration加到registrations.
}
boolean isRegisteredForSeminar(String participantId, String seminarId) {
...
}
Date getSeminarRegistrationDate(String participantId, String seminarId) {
...
}
boolean needSIDeviceForSeminar(String participantId, String seminarId) {
...
}
SeminarRegistration[] getAllRegistrations(String participantId) {
...
}
}
class ConferenceSystem {
Participant participants[];
SeminarRegistry seminarRegistry;
}
当然,除了以上的方案以外,还有其他可行的方案,这里就先不讲。
改进后的代码
下面就是改进后的代码:
class Participant {
String id;
String name;
String telNo;
String address;
}
class HotelBooking {
String participantId;
String hotelName;
Date checkInDate;
Date checkOutDate;
boolean isSingleRoom;
}
class HotelBookings {
HotelBooking hotelBookings[];
void addBooking(HotelBooking booking) {
...
}
}
class SeminarRegistration {
String participantId;
String seminarId;
Date registrationDate;
boolean needSIDevice;
}
class SeminarRegistry {
SeminarRegistration registrations[];
void registerForSeminar(SeminarRegistration registration) {
//将registration加到registrations.
}
boolean isRegistered (String participantId, String seminarId) {
...
}
Date getRegistrationDate(String participantId, String seminarId) {
...
}
boolean needSIDevice(String participantId, String seminarId) {
...
}
SeminarRegistration[] getAllRegistrations(String participantId) {
...
}
}
class ConferenceSystem {
Participant participants[];
HotelBookings hotelBookings;
SeminarRegistry seminarRegistry;
}
http://wingel.iteye.com/topics/download/3589b4d8-8e29-4560-b0e7-8cb15a8ed995
或者
http://www.blogjava.net/Files/Wingel/%E7%AC%AC4%E7%AB%A0%E4%BF%9D%E6%8C%81%E4%BB%A3%E7%A0%81%E7%AE%80%E6%B4%81.rar
http://wingel.iteye.com/topics/download/3589b4d8-8e29-4560-b0e7-8cb15a8ed995
或者
http://www.blogjava.net/Files/Wingel/%E7%AC%AC4%E7%AB%A0%E4%BF%9D%E6%8C%81%E4%BB%A3%E7%A0%81%E7%AE%80%E6%B4%81.rar
第4章 保持代码简洁
示例
这是一个会议管理系统。它用来管理所有参会者的信息。刚开始的时候,我们只需要记录每个参会者的ID(这是会议组织者分配的),姓名,电话和地址就行。于是,我们写了如下的代码:
class Participant {
String id;
String name;
String telNo;
String address;
}
class ConferenceSystem {
Participant participants[];
}
接着,新的需求来了:现在每个参会者都可以让组织者帮忙预订酒店,所以我们要记录下他想预订的酒店名,入住日期,离开日期,房间类型(单人房或者双人房)。于是我们又扩充成如下的代码:
class Participant {
String id;
String name;
String telNo;
String address;
boolean bookHotelForHim;
String hotelName;
Date checkInDate;
Date checkOutDate;
boolean isSingleRoom;
void setHotelBooking(String hotelName, Date checkInDate, ...) {
...
}
}
接着,又有一个新的需求来了:参会者可以参加不同的研讨会,所以我们要记录下参会者参加的研讨会。对于他要参加的每一场研讨会,我们还要记录下他的登记时间,同时他还需要什么翻译设备。于是代码又扩充成:
class Participant {
String id;
String name;
String telNo;
String address;
boolean bookHotelForHim;
String hotelName;
Date checkInDate;
Date checkOutDate;
boolean isSingleRoom;
String idOfSeminarsRegistered[];
Date seminarRegistrationDates[];
boolean needSIDeviceForEachSeminar[];
void setHotelBooking(String hotelName, Date checkInDate, ...) {
...
}
void registerForSeminar(String seminarId, Date regDate, boolean needSIDevice) {
//将seminarId加到idOfSeminarsRegistered
//将regDate加到seminarRegistrationDates
//将needSIDevice加到needSIDeviceForEachSeminar.
}
boolean isRegisteredForSeminar(String seminarId) {
...
}
Date getSeminarRegistrationDate(String seminarId) {
...
}
boolean needSIDeviceForSeminar(String seminarId) {
...
}
String [] getAllSeminarsRegistered() {
return idOfSeminarsRegistered;
}
}
代码开始肿胀起来了
请注意,这已经是我们第二次扩充Participant这个类了。每扩充一次,它就包含了更多的代码(实例变量和方法)及更多的功能。本来它只有4个属性。现在已经是12个了!此外,这个类要处理的业务逻辑也极大的增加了。本来它只需要处理参会者的基本信息(姓名,地址等等),现在它还要包含酒店,酒店预订,研讨会和翻译设备等等的逻辑。如果以后新的需求又来了,我们又要扩充Participant这个类,到时候,这个类要复杂庞大成什么样子!
所以我们得修整这个类了!
那怎么修整Participant这个类呢?怎么让它一直保持在第一天那样的简洁度?在回答这两个问题之前,我们先来考虑一下另一个需要优先回答的问题:给你一个类,你怎么认定它需要修整?
怎么判断一个类需要修整
要判断一个类是否需要修整,一个比较主观的方法是:当在读一个类的代码时,看看我们会不会觉得这个类“太长了”,“太复杂了”,或者讲的概念“太多了”?如果会这样觉得的话,我们就认定,这个类需要修整。
另外一个比较简单而且客观的方法是:当发现我们已经在第二次或者第三次扩充这个类的时候,我们认定这个类要修整了。这是一个比较”懒惰,被动”的方法,但却很有效。
现在让我们看一下怎么修整Participant这个类吧。
抽取出有关酒店预订的功能
首先,先来考虑一下怎么抽取出酒店预订的功能。一个可行的方案是:
class Participant {
String id;
String name;
String telNo;
String address;
}
class HotelBooking {
String participantId;
String hotelName;
Date checkInDate;
Date checkOutDate;
boolean isSingleRoom;
}
class HotelBookings {
HotelBooking hotelBookings[];
void addBooking(HotelBooking booking) {
...
}
}
class ConferenceSystem {
Participant participants[];
HotelBookings hotelBookings;
}
现在,Participant这个类就一点都不知道酒店预订的存在。当然,我们不一定要用数组来存放酒店预订情况。比如,我们可以用Map:
class Participant {
String id;
String name;
String telNo;
String address;
}
class HotelBooking {
String participantId;
String hotelName;
Date checkInDate;
Date checkOutDate;
boolean isSingleRoom;
}
class HotelBookings {
HashMap mapFromPartIdToHotelBooking;
//必须提供参会者id
void addBooking(String participantId, HotelBooking booking) {
...
}
}
class ConferenceSystem {
Participant participants[];
HotelBookings hotelBookings;
}
这样的方案优点是Participant一点都不知道HotelBooking的存在,Participant不依赖于HotelBooking。
还有另一个可行的方案是:
class Participant {
String id;
String name;
String telNo;
String address;
HotelBooking hotelBooking;
}
class HotelBooking {
String hotelName;
Date checkInDate;
Date checkOutDate;
boolean isSingleRoom;
}
class ConferenceSystem {
Participant participants[];
}
注意到,在这种方案里面,Participant这个类还是要知道HotelBooking的存在,也就是说,Participant还是要知道有酒店预订这回事。只是具体酒店预订是怎么做的,这些真正的功能是放在HotelBooking这个里面实现的。因为每个Participant都直接引用了本人的酒店预订情况,所以可以直接找到他的酒店预订情况。而代价就是,Pariticipant还是要知道酒店预订的概念。从类的关系来讲,Pariticipant还要依赖HotelBooking这个类。
当然,除了以上几种情况,还有许多其他的可行方案。
抽取研讨会的相关功能
现在我们来考虑一下怎么抽取出研讨会的功能。一个可行的方案:
class Participant {
String id;
String name;
String telNo;
String address;
}
class SeminarRegistration {
String participantId;
String seminarId;
Date registrationDate;
boolean needSIDevice;
}
class SeminarRegistry {
SeminarRegistration registrations[];
void registerForSeminar(SeminarRegistration registration) {
//将registration加到registrations.
}
boolean isRegisteredForSeminar(String participantId, String seminarId) {
...
}
Date getSeminarRegistrationDate(String participantId, String seminarId) {
...
}
boolean needSIDeviceForSeminar(String participantId, String seminarId) {
...
}
SeminarRegistration[] getAllRegistrations(String participantId) {
...
}
}
class ConferenceSystem {
Participant participants[];
SeminarRegistry seminarRegistry;
}
当然,除了以上的方案以外,还有其他可行的方案,这里就先不讲。
改进后的代码
下面就是改进后的代码:
class Participant {
String id;
String name;
String telNo;
String address;
}
class HotelBooking {
String participantId;
String hotelName;
Date checkInDate;
Date checkOutDate;
boolean isSingleRoom;
}
class HotelBookings {
HotelBooking hotelBookings[];
void addBooking(HotelBooking booking) {
...
}
}
class SeminarRegistration {
String participantId;
String seminarId;
Date registrationDate;
boolean needSIDevice;
}
class SeminarRegistry {
SeminarRegistration registrations[];
void registerForSeminar(SeminarRegistration registration) {
//将registration加到registrations.
}
boolean isRegistered (String participantId, String seminarId) {
...
}
Date getRegistrationDate(String participantId, String seminarId) {
...
}
boolean needSIDevice(String participantId, String seminarId) {
...
}
SeminarRegistration[] getAllRegistrations(String participantId) {
...
}
}
class ConferenceSystem {
Participant participants[];
HotelBookings hotelBookings;
SeminarRegistry seminarRegistry;
}
http://wingel.iteye.com/topics/download/3589b4d8-8e29-4560-b0e7-8cb15a8ed995
或者
http://www.blogjava.net/Files/Wingel/%E7%AC%AC4%E7%AB%A0%E4%BF%9D%E6%8C%81%E4%BB%A3%E7%A0%81%E7%AE%80%E6%B4%81.rar
- 第4章保持代码简洁.rar (261 KB)
- 下载次数: 14
发表评论
-
(强烈推荐)敏捷开发的必要技巧完整版
2006-12-16 09:48 11702敏捷开发的必要技巧完整版.rar 或者 下载 目录: ... -
敏捷开发的必要技巧14:结对编程
2006-12-14 21:23 2198链接: 第14章结对编程.rar 或者 下载 结对编程 ... -
敏捷开发的必要技巧13:测试驱动编程
2006-12-11 16:47 2710下载地址: 第13章测试 ... -
敏捷开发必要技巧12:单元测试
2006-12-09 09:54 1177到第12章单元测试.rar 或者 下载 下载pdf。 第1 ... -
敏捷开发的必要技巧11:对UI进行验收测试.doc
2006-12-08 21:15 1650第11章对UI进行验收测试.rar or 下载 第11章 ... -
敏捷开发的必要技巧10:验收测试(Acceptance Test)
2006-12-07 11:13 2082... -
敏捷开发的必要技巧9:用CRC卡协助设计
2006-12-05 10:47 4488摘录一些东西,具体请下附件观看: 因为在这些卡里面,我们写上 ... -
敏捷开发的必要技巧8:用用户例事(user story)来管理项目
2006-12-04 11:29 1734第 8 章 以用户例事管理项目 ... -
敏捷开发的必要技巧7:将数据库访问,UI和域逻辑分离
2006-12-01 16:13 1645(这里面的域逻辑,原文是叫Domain logic,我想用业务 ... -
敏捷开发的必要技巧6 处理不合适的依赖
2006-12-01 09:17 1111请下载附件观看 -
敏捷开发的必要技巧5:慎用继承
2006-11-29 20:38 966第5章 慎用继承 示例 ... -
敏捷开发的必要技巧1-2:移除重复代码,将注释转为代码
2006-11-26 13:41 1397pdf的下载地址: http://www.blogjava.n ... -
敏捷开发的必要技巧第3章----消除代码异味
2006-11-27 21:13 1133完整: http://www.blogjava.n ...
相关推荐
博文链接:https://wingel.iteye.com/blog/38201
博文链接:https://wingel.iteye.com/blog/36890
博文链接:https://wingel.iteye.com/blog/37727
博文链接:https://wingel.iteye.com/blog/36618
敏捷开发的必要技巧 目录 第 1 章 移除重复代码 第 2 章 将注释转换为代码 第 3 章 除去代码异味 第 4 章 保持代码简洁 第 5 章 慎用继承 第 6 章 处理不合适的依赖 第 7 章 将数据库访问,UI和域逻辑分离 第 8 章...
敏捷开发的理念已经流行了很长的时间,在敏捷开发中的开发迭代阶段中,我们可以通过五个步骤,来有效的提高整个项目的代码质量。 Java项目开发过程中,由于开发人员的经验、Java代码编写习惯,以及缺乏统一的标准和...
在本书中,享誉全球的软件开发专家和软件工程大师Robert C.Martin将向您展示如何解决软件开发人员、项目经理及软件项目领导...这本综合性、实用性的敏捷开发和极限编程方面的指南,是由敏捷开发的创始人之一所撰写的。