- 浏览: 117530 次
- 性别:
文章分类
最新评论
-
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 11770敏捷开发的必要技巧完整版.rar 或者 下载 目录: ... -
敏捷开发的必要技巧14:结对编程
2006-12-14 21:23 2227链接: 第14章结对编程.rar 或者 下载 结对编程 ... -
敏捷开发的必要技巧13:测试驱动编程
2006-12-11 16:47 2745下载地址: 第13章测试 ... -
敏捷开发必要技巧12:单元测试
2006-12-09 09:54 1209到第12章单元测试.rar 或者 下载 下载pdf。 第1 ... -
敏捷开发的必要技巧11:对UI进行验收测试.doc
2006-12-08 21:15 1682第11章对UI进行验收测试.rar or 下载 第11章 ... -
敏捷开发的必要技巧10:验收测试(Acceptance Test)
2006-12-07 11:13 2121... -
敏捷开发的必要技巧9:用CRC卡协助设计
2006-12-05 10:47 4530摘录一些东西,具体请下附件观看: 因为在这些卡里面,我们写上 ... -
敏捷开发的必要技巧8:用用户例事(user story)来管理项目
2006-12-04 11:29 1763第 8 章 以用户例事管理项目 ... -
敏捷开发的必要技巧7:将数据库访问,UI和域逻辑分离
2006-12-01 16:13 1675(这里面的域逻辑,原文是叫Domain logic,我想用业务 ... -
敏捷开发的必要技巧6 处理不合适的依赖
2006-12-01 09:17 1169请下载附件观看 -
敏捷开发的必要技巧5:慎用继承
2006-11-29 20:38 997第5章 慎用继承 示例 ... -
敏捷开发的必要技巧1-2:移除重复代码,将注释转为代码
2006-11-26 13:41 1427pdf的下载地址: http://www.blogjava.n ... -
敏捷开发的必要技巧第3章----消除代码异味
2006-11-27 21:13 1156完整: http://www.blogjava.n ...
相关推荐
本篇将探讨敏捷开发中的重要技巧之一——单元测试,以及如何通过有效的单元测试提升软件质量。 单元测试是对软件中最小可测试单元进行检查和验证的过程,通常是函数、方法或类。在敏捷开发中,单元测试扮演着至关...
第4章:保持代码简洁 简洁的代码是敏捷开发的关键,因为它易于理解、修改和测试。本章探讨了编写简洁代码的原则和技巧,如避免过度设计,遵循DRY(Don't Repeat Yourself)原则,以及使用有意义的命名。此外,还介绍...
本文通过详细解读《敏捷开发的必要技巧》这一资料,旨在帮助读者了解并掌握敏捷开发的核心技能与实践方法。 #### 二、移除重复代码 **1. 重复代码产生的原因** - **需求变更导致的复制粘贴**:为了满足新的功能...
### 敏捷开发的必要技巧 #### 一、引言 敏捷开发是一种以人为本、迭代、循序渐进的开发方法论。它强调快速响应变化、持续交付可用软件、紧密合作与适应性规划。《敏捷开发的必要技巧》这本书由Wingel翻译自...
### 敏捷软件开发的必要技巧 #### 一、引言 敏捷开发是一种以人为本、迭代、循序渐进的开发方法,在21世纪初开始流行起来。它强调快速响应变化,通过持续的反馈循环来提高项目的成功率。本文档旨在介绍一系列重要的...
- **Rails是敏捷的**:Rails框架的设计初衷就是为了支持敏捷开发,它强调简洁、直观的代码编写方式,以及快速迭代的开发流程。 - **读你所需**:作者建议读者可以根据自己的需求和兴趣选择性地阅读书中的章节,不必...
敏捷建模鼓励通过持续重构来保持代码的简洁性和可维护性,同时更新模型以反映代码的最新状态。 5. **自动化测试**:敏捷建模强调测试驱动开发(TDD),在编写代码之前先编写测试用例。JUnit和其他Java测试框架为...
接着,开发者编写代码使测试通过,但这通常是实现功能的最小必要部分,代码的编写要尽量简洁。最后,为了提高代码的质量和可维护性,开发者需要在测试通过的基础上进行代码重构,移除重复、优化设计,但整个过程中...
- 内容概述:结合敏捷开发原则,讲解了如何在C#中运用最佳实践进行高效编程。 #### 六、结语 通过对本书内容的学习,开发者不仅能了解到编写高质量代码的重要性,还能掌握一系列实用的方法和技巧。在日常工作中...
9. **敏捷开发与迭代**:公司追求快速迭代,强调迅速推出产品并持续改进。这种开发模式要求开发者适应快速变化的需求,并能及时反馈和调整。 10. **原型设计的重要性**:在开发前未充分构思原型,导致了设计上的...
1. **TDD的起源与背景**:介绍TDD的发展历程,以及为什么它在敏捷开发中占有一席之地。 2. **TDD的步骤与技巧**:详细阐述“红-绿-重构”循环的执行过程,以及如何有效地编写测试用例。 3. **实战案例**:通过具体...