第二篇 调整对象功能 第八章 - 适配器模式
我们在上一篇目讨论了对象的生成及初始化,主要关注的是对象从 0 到 1 的创建过程。接下来的三个章节,我们将讨论如何调整已有对象功能,主要关注的是对象从 1 到 n 的转变过程。
设计软件时常将类的职责单一化,使其各司其职。身兼数职的类往往难以阅读,不易维护。然而一旦框定了类的职责,其对象的功能也就被限制了,这又会降低程序的灵活性。
有什么方法可以调整对象,使其具备更多的功能吗?
一种直截了当的方法是转换对象的类型,新的类型自然会赋予对象新的功能。
我们以《木兰诗》中木兰替父从军的故事为例,看看这种方法的代表——适配器模式——提供的设计思路。
假设有如下两个类。
// “女孩儿”类,木兰本是女孩儿。
public class Girl {}
// “战士”类,木兰想从军。
public class Soldier {}
“女孩儿”类型的对象并不能直接转换成“战士”类型,下面的写法将引发 java.lang.ClassCastException 异常。
// 测试类
public class Test {
public void test() {
Object obj = new Girl();
obj = (Soldier) obj;
}
}
虽然“女孩儿”无法直接转换成“战士”,但她可以具备战士的特质——勇毅。
我们不妨引入一个“勇毅”接口,作为“女孩儿”和“战士”的中间类型。
完整的代码如下。
// 女孩儿
public class Girl {
public void dressAndMakeUp() {
// 当窗理云鬓,对镜帖花黄。
}
}
// “勇毅”接口
public interface Brave {
public void beBraveToDo();
}
// 战士
public class Soldier implements Brave {
@Override
public void beBraveToDo() {
// 将军百战死,壮士十年归。
}
}
// 勇毅的女孩儿
public class BraveGirl extends Girl implements Brave {
@Override
public void beBraveToDo() {
// 万里赴戎机,关山度若飞。
}
}
// 测试类
public class Test {
public void test() {
Object mulan = new BraveGirl();
// 出征
Brave obj1 = (Brave) mulan;
obj1.beBraveToDo();
// 还乡
Girl obj2 = (Girl) mulan;
obj2.dressAndMakeUp();
}
}
这里没有直接让 Girl 类实现 Brave 接口,那样会使不同职责的代码交织在同一个类中。
我们额外添加了 BraveGirl(适配器类),它是 Girl 的子类,又是 Brave 的实现类。由它产生的对象既可以转换成 Girl 类型,又可以转换成 Brave 类型。
类型转换了,对象的功能自然随之变化。
浙公网安备 33010602011771号