第二篇 调整对象功能 第八章 - 适配器模式

  我们在上一篇目讨论了对象的生成及初始化,主要关注的是对象从 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 类型。
  类型转换了,对象的功能自然随之变化。

posted on 2025-03-23 16:09  星辰河岳  阅读(24)  评论(0)    收藏  举报