崩溃!如何面对令人脱发的老代码?
点击关注公众号,实用技术文章及时了解


“后来有人提出了模块化的概念,设备间通过接口传递数据,于是各种外部设备如雨后春笋般涌现:鼠标,键盘,摄像头,打印机,外接硬盘……”
“但这时又出现一个问题,每种设备都有各自的接口,那么电脑主机上得有多少种接口啊?串口、并口、PS2接口……接口泛滥成灾,制定标准化的接口势在必行,于是便有了现在的USB接口。”
“USB提供了统一的接口标准,只要符合这种标准的设备则可以进行接驳,然后各种各样的设备也都陆陆续续支持了USB接口。”
“光说不练不成,我们来写点代码。”老T顺手打开了IDE。“照着上面这个图,我们先写一个USB接口。”
public interface USB {
public String readData();
}
“一目了然,上面是一个接口,名字就叫USB,它确立了一个标准的接口方法readData()。接着外设键盘(Keyboard)和鼠标(Mouse)两个类统统实现(Implements)了USB接口。”
public class Keyboard implements USB {
public String readData() {
return "键盘敲击,字符舞动……";
}
}
public class Mouse implements USB {
public String readData() {
return "鼠标移动、划出一道彩虹……";
}
}
看了代码,小白连连点头:“的确,这真的太形象了”。
“接口和它的外设都写好了,下来我们得有一台电脑主机,我们就叫它Computer类。”
public class Computer {
private USB usb;
public void setUSB(USB usb){
this.usb = usb;
}
public void display(){
System.out.println("屏幕上显示:" + usb.readData());
}
}
“看好了,这电脑里面包含了一个USB的接口(第3行),并且对外暴露了一个setUSB(USB usb)的方法(第5行),这就意味着它允许我们把任何USB设备插上去,但是一定得是USB接口的实现,否则就会报错。”
小白逐渐进入了状态:“对,这就好像以前的PS2圆口鼠标,没办法插入USB接口”。
老T趁热打铁:“此外,电脑主机还有一个display()方法(第9行)用以将usb里读取的内容展示于屏幕上。最后,见证奇迹的时刻到了,我们让这台电脑跑起来,再接入设备测试一下。”
public class Client {
public static void main(String[] args){
Computer computer = new Computer();
System.out.println("电脑启动成功。");
System.out.println("1.接入USB设备……");
computer.setUSB(new Keyboard());
computer.display();
System.out.println("2.接入USB设备……");
computer.setUSB(new Mouse());
computer.display();
}
}
键盘劈里啪啦的作响,看着老T在键盘上飞舞的双手,小白不禁解读到:“实例化电脑后,usb接口上插入了键盘(第9行),那么屏幕上应该蹦出来键盘入的字符;然后又换上了鼠标(第13行),这次屏幕上一定会显示出鼠标指针了。”
“说得不错,让我们拭目以待。”老果断运行了Client类的main方法。
“果然如你所料,接上哪个设备,电脑就显示谁送来的数据了。”老T喝了一口茶接着说:“对于电脑而言,它根本不知道对接的是谁,它只管向USB接口拿数据即可。而对于实现类已经成为独立于主机(宿主)之外的外挂模块(插件)了。在设计模式里这叫作【策略模式】”。
小白似乎已经完全搞懂了,茅塞顿开:“原来如此,这种设计简直太妙了!一个插件类就是对某种行为的封装,后面如果有新的设备需求,我只需要实现标准的USB接口,然后优雅地调用setUSB(插件对象)把它接入即可,根本不需要拆开主机重新修改里面的逻辑了,这扩展性也太棒了!”
老T接着抛出了其惊世骇俗的哲学观:“变化是世界的常态,唯一不变的就是变本身,天时地利人和,拥有顺势而为、随机应变的能力才能立于不败之地。策略模式的运用能让系统的应变能力得到提升,适应永远得不到满足而随时变化的需求。接口的巧妙运用让一系列的策略都可以脱离系统之外而单独存在了,使系统拥有更灵活、更强大的【可插拔】扩展功能。”说罢顺手抛出一张类图。
此刻老T发现小白的脸上又出现了一个大写的“懵”字:“好吧,类图其实就对应着下面这张图,对比着看是不是更好理解了?”




原文始发于微信公众号(Java知音):崩溃!如何面对令人脱发的老代码?