24. 敏捷开发的必要技巧----Wingel 翻译自 Essential Skills for Agile Development
ParticipantsInDB p;
Participant part1=new Participant("ABC001","Kent","Tong",true,"Manager");
Participant part2=new Participant("ABC003","Paul","Chan",true,"Manager");
void setUp() {
p=ParticipantsInDB.getInstance();
}
void tearDown() {
ParticipantsInDB.freeInstance();
}
void testAdd() {
p.deleteAllParticipants();
p.addParticipant(part1);
assertEquals(p.getCount(),1);
}
void testAdd2() {
p.deleteAllParticipants();
p.addParticipant(part1);
p.addParticipant(part2);
assertEquals(p.getCount(),2);
}
void testEnum() {
p.deleteAllParticipants();
p.addParticipant(part2);
p.addParticipant(part1);
ParticipantEnumeratorById penum=new ParticipantEnumeratorById();
assertTrue(penum.next());
assertTrue(penum.get().equals(part1));
assertTrue(penum.next());
assertTrue(penum.get().equals(part2));
assertTrue(!penum.next());
penum.close();
}
}
5. 指出并修改下面的重复代码:
class ReportCatalogueIndexCommandParser {
final String NO_GROUPING = "orgNoGrouping";
static final int ORG_CATALOG = 0;
static final int PART_CATALOG = 1;
int getGroupingType(String grouping) {
if (grouping.equals(NO_GROUPING)) {
return ORG_CATALOG;
厦门:王伟杰(Wingel) MSN: wingel_wang@hotmail.com
邮箱: seewingel@gmail.com 博客: http://blog.csdn.net/Wingel
25. 敏捷开发的必要技巧----Wingel 翻译自 Essential Skills for Agile Development
} else if (grouping.equals("orgGroupByCountry")) {
return ORG_CATALOG;
} else if (grouping.equals("orgGroupByTypeOfOrgName")) {
return ORG_CATALOG;
} else if (grouping.equals("part")) {
return PART_CATALOG;
} else
throw new IllegalArgumentException("Invalid grouping!");
}
...
}
每个 if-then 的分支都做了类似的事,将字符串放在一个集合里面中.
class ReportCatalogueIndexCommandParser {
final String NO_GROUPING = "orgNoGrouping";
static final int ORG_CATALOG = 0;
static final int PART_CATALOG = 1;
int getGroupingType(String grouping) {
Set orgGroupings = new TreeSet();
orgGroupings.add(NO_GROUPING);
orgGroupings.add("orgGroupByCountry");
orgGroupings.add("orgGroupByTypeOfOrgName");
if (orgGroupings.contains(grouping)) {
return ORG_CATALOG;
}
if (grouping.equals("part")) {
return PART_CATALOG;
} else
throw new IllegalArgumentException("Invalid grouping!");
}
}
用 Set 可能会有些大材小用了,我们应该需要什么,用什么. 简单的一个方法,就是将返回结果的代码抽取出来.
class ReportCatalogueIndexCommandParser {
final String NO_GROUPING = "orgNoGrouping";
static final int ORG_CATALOG = 0;
static final int PART_CATALOG = 1;
int getGroupingType(String grouping) {
厦门:王伟杰(Wingel) MSN: wingel_wang@hotmail.com
邮箱: seewingel@gmail.com 博客: http://blog.csdn.net/Wingel
26. 敏捷开发的必要技巧----Wingel 翻译自 Essential Skills for Agile Development
if (grouping.equals(NO_GROUPING) ||
grouping.equals("orgGroupByCountry") ||
grouping.equals("orgGroupByTypeOfOrgName")) {
return ORG_CATALOG;
} else if (grouping.equals("part")) {
return PART_CATALOG;
} else
throw new IllegalArgumentException("Invalid grouping!");
}
...
}
6. 指出并修改下面的重复代码:
class Restaurant extends Account {
//字符串"Rest"是作为前缀来组成饭店的 id
final static String RestaurantIDText = "Rest";
String website;
//中文地址
String addr_cn;
//英文地址
String addr_en;
//下面是最新的传真号码,饭店想要更新它的传真号,等确认下面的新传真号是正确的以后
//新传真号就会存放在 Account 中,在这之前,都会存放在这个位置
String numb_newfax;
boolean has_NewFax = false;
//存放假日的一个集合
Vector Holiday; // a holiday
//该饭店所属分类的 id
String catId;
//营业时段的集合,每个营业时段都是一个数组,
//数组中包括两个时间,前面一个表示开始时间,后面一个表示结束时间
//饭店在所有的时间段内营业
Vector BsHour; //营业时段集
...
//y: 年.
//m: 月.
厦门:王伟杰(Wingel) MSN: wingel_wang@hotmail.com
邮箱: seewingel@gmail.com 博客: http://blog.csdn.net/Wingel
27. 敏捷开发的必要技巧----Wingel 翻译自 Essential Skills for Agile Development
//d: 日.
void addHoliday(int y,int m,int d){
if(y<1900) y+=1900;
Calendar aHoliday = (new GregorianCalendar(y,m,d,0,0,0));
Holiday.add(aHoliday);
}
public boolean addBsHour(int fromHr, int fromMin, int toHr, int toMin){
int fMin = fromHr*60 + fromMin; //以分表示的开始时间
int tMin = toHr*60 + toMin; //以分表示的结束时间
//确定所有的时间都是有效的,而且结束时间比开始时间晚
if(fMin > 0 && fMin <= 1440 && tMin > 0 && tMin <=1440 && fMin < tMin){
GregorianCalendar bs[] = {
new GregorianCalendar(1900,1,1, fromHr, fromMin,0),
new GregorianCalendar(1900,1,1, toHr, toMin,0)
};
BsHour.add(bs);
return true;
} else {
return false;
}
}
}
有三处代码重复:1. 将几时几分转化为总计几分的代码重复. 2. 验证分的总数是否合理的代码重复. 3. 创建
一个从 1900.1.1 算起的 GregorianCalendar 的代码重复.
class Restaurant extends Account {
...
int getMinutesFromMidNight(int hours, int minutes) {
return hours*60+minutes;
}
boolean isMinutesWithinOneDay(int minutes) {
return minutes>0 && minutes<=1440;
}
GregorianCalendar convertTimeToDate(int hours, int minutes) {
return new GregorianCalendar(1900, 1, 1, hours, minutes, 0);
}
public boolean addBsHour(int fromHr, int fromMin, int toHr, int toMin){
int fMin = getMinutesFromMidNight(fromHr, fromMin);
int tMin = getMinutesFromMidNight(toHr, toMin);
厦门:王伟杰(Wingel) MSN: wingel_wang@hotmail.com
邮箱: seewingel@gmail.com 博客: http://blog.csdn.net/Wingel
28. 敏捷开发的必要技巧----Wingel 翻译自 Essential Skills for Agile Development
if (isMinutesWithinOneDay(fMin) &&
isMinutesWithinOneDay(tMin) &&
fMin < tMin){
GregorianCalendar bs[] = {
convertTimeToDate(fromHr, fromMin),
convertTimeToDate(toHr, toMin)
};
BsHour.add(bs);
return true;
} else {
return false;
}
}
}
7. 指出并修改下面的重复代码:
class Order {
...
boolean IsSameString(String s1, String s2){
if(s1==s2) return true;
if(s1==null) return false;
return(s1.equals(s2));
}
}
class Mail {
...
static boolean IsSameString(String s1, String s2) {
if (s1 == s2)
return true;
if (s1 == null)
return false;
return (s1.equals(s2));
}
}
方法 IsSameString 重复.
class StringComparer {
厦门:王伟杰(Wingel) MSN: wingel_wang@hotmail.com
邮箱: seewingel@gmail.com 博客: http://blog.csdn.net/Wingel
29. 敏捷开发的必要技巧----Wingel 翻译自 Essential Skills for Agile Development
static boolean IsSameString(String s1, String s2) {
if (s1 == s2)
return true;
if (s1 == null)
return false;
return (s1.equals(s2));
}
}
class Order {
...
//如果可能的话,将这个方法移到一个 Util 的类里面作为一个静态方法,比如 StringComparer
//然后直接调用 StringComparer.IsSameString.
boolean IsSameString(String s1, String s2){
return StringComparer.IsSameString(s1, s2);
}
}
class Mail {
...
//如果可能的话,将这个方法移到一个 Util 的类里面作为一个静态方法,比如 StringComparer
//然后直接调用 StringComparer.IsSameString.
static boolean IsSameString(String s1, String s2) {
return StringComparer.IsSameString(s1, s2);
}
}
8. 指出并修改下面的重复代码:
class FoodDB {
//找出所有名字都包括这两个关键字的食物,返回一个迭代器(Iterator)
public Iterator srchFood(String cName, String eName){
//it contains all the foods to be returned.
TreeMap foodTree = new TreeMap();
Iterator foodList;
Food food;
foodList = getAllRecords();
while (foodList.hasNext()){
food = (Food) foodList.next();
//有没有包括两个关键字?
厦门:王伟杰(Wingel) MSN: wingel_wang@hotmail.com
邮箱: seewingel@gmail.com 博客: http://blog.csdn.net/Wingel