从避免重复到设计模式

03-03-15 VRGL
    

避免重复是为了使相同或相似的代码不再重复出现,

相同的代码很容易发现并且被复用,但相似的代码

不那么容易发现并且被复用。如果只是几个参数有

变化,可以通过传参的方法。但如果像下面的例子,

怎么分离变和不变的呢?

class Invoice...

String asciiStatement() {

StringBuffer result = new StringBuffer();

result.append(“Bill for “ + customer + “\n”);

Iterator it = items.iterator();

while(it.hasNext()) {

LineItem each = (LineItem) it.next();

result.append(“\t” + each.product() + “\t\t”

+ each.amount() + “\n”);

}

result.append(“total owed:” + total + “\n”);

return result.toString();

}

String htmlStatement() {

StringBuffer result = new StringBuffer();

result.append(“<P>Bill for <I>” + customer + “</I></P>”);

result.append(“<table>”);

Iterator it = items.iterator();

while(it.hasNext()) {

LineItem each = (LineItem) it.next();

result.append(“<tr><td>” + each.product()

+ “</td><td>” + each.amount() + “</td></tr>”);

}

result.append(“</table>”);

result.append(“<P> total owed:<B>” + total + “</B></P>”);

return result.toString();

}

这里要完成显示ascii和html两种形式的表达式。

两种情况下,都有如下的结构(不变的东西):

1.打印一个页头。

2.遍历所有item,并打印出来。

3.打印一个页脚。

所以可以抽象出以下一个接口:

interface Printer {

String header(Invoice iv);

String item(LineItem line);

String footer(Invoice iv);

}

和一个实现这个接口的类:

static class AsciiPrinter implements Printer {

public String header(Invoice iv) {

return “Bill for “ + iv.customer + “\n”;

}

public String item(LineItem line) {

return “\t” + line.product()+ “\t\t” + line.amount() +“\n”;

}

public String footer(Invoice iv) {

return “total owed:” + iv.total + “\n”;

}

}

客户端代码如下:

class Invoice...

public String statement(Printer pr) {

StringBuffer result = new StringBuffer();

result.append(pr.header(this));

Iterator it = items.iterator();

while(it.hasNext()) {

LineItem each = (LineItem) it.next();

result.append(pr.item(each));

}

result.append(pr.footer(this));

return result.toString();

}

class Invoice...

public String asciiStatement2() {

return statement (new AsciiPrinter());

}

熟悉设计模式的朋友可能会发现这就是Template method。

所以如果你坚决要在一个地方使用设计模式,一定要问自己

:“这里我消除了什么代码重复?”。如果答案是没有任何

代码重复被消除,那么就不要用设计模式。

    

VRGL
2003-03-16 18:13

怎么没人回我?

banq
2003-03-16 20:07

你这其实是refactory的宗旨,当你第三次发现重复时,你就要着手重整了。