我们周围的适配器
比方说:如果你需要在欧洲国家使用美国制造的笔记本电脑,你可能需要使用一个交流电的适配器......
适配器改变了插座的接口,以符合美式笔记本电脑的需求。
面向对象适配器
假设已经有一个软件系统,你希望它能和一个新的厂商类库搭配使用,但是这个新的厂商设计出来的接口不同于旧的厂商的接口
要解决这个问题,可以写一个适配器类来将新的厂商接口转换成你所期待的接口
火鸡转换器
如果它走起路来像只鸭子,叫起来像只鸭子,那么它必定可能是一只鸭子包装了鸭子适配器的火鸡
鸭子接口
public interface Duck {
/**
* 叫
*/
public void quack();
/**
* 飞
*/
public void fly();
}
绿头鸭子是鸭子的子类
public class MallardDuck implements Duck {
@Override
public void quack() {
System.out.println("Quack");
}
@Override
public void fly() {
System.out.println("I'm flying");
}
}
火鸡接口
public interface Turkey {
/**
* 叫
*/
public void gobble();
/**
* 飞
*/
public void fly();
}
火鸡的实现类
public class WildTurkey implements Turkey {
@Override
public void gobble() {
System.out.println("Gobble gobble");
}
@Override
public void fly() {
System.out.println("I'm flying short distance");
}
}
现在,假如我们缺鸭子对象,需要一些火鸡来冒充,然而因为火鸡和鸭子的接口不同,不能直接拿来使用,需要编写一个适配器
public class TurkeyAdapter implements Duck {
Turkey turkey;
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
public void quack() {
turkey.gobble();
}
public void fly() {
for (int i = 0; i < 5; i++) {
turkey.fly();
}
}
}
测试
public class DuckTest {
public static void main(String[] args) {
MallardDuck duck = new MallardDuck();
WildTurkey turkey = new WildTurkey();
TurkeyAdapter turkeyAdapter = new TurkeyAdapter(turkey);
System.out.println("Turkey-------------------------");
turkey.gobble();
turkey.fly();
System.out.println("Duck--------------------------");
testDuck(duck);
System.out.println("TurkeyAdapter---------------");
testDuck(turkeyAdapter);
}
static void testDuck(Duck duck){
duck.quack();
duck.fly();
}
}
测试结果
适配器模式解析
定义
将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。
上文已经看到了适配器模式的例子,现在来看它的类图
对象和类的适配器
对象适配器的类图
-
Target目标角色
该角色定义把其他类转换为何种接口, 也就是我们的期望接口, 例子中的IUserInfo接口就是目标角色。 -
Adaptee源角色
你想把谁转换成目标角色, 这个“谁”就是源角色, 它是已经存在的、 运行良好的类或对象, 经过适配器角色的包装, 它会成为一个崭新、 靓丽的角色。 -
Adapter适配器角色
适配器模式的核心角色, 其他两个角色都是已经存在的角色, 而适配器角色是需要新建立的, 它的职责非常简单: 把源角色转换为目标角色, 怎么转换? 通过继承或是类关联的方式。
类适配器的类图
在java中是不可能实现类适配器的,因为需要多重继承才能实现它,它和对象适配器的唯一区别就是类适配器继承了Target和Adaptee,而对象适配器利用组合的方式将请求传送给适配器。
适配器模式的优点
- 适配器模式可以让两个没有任何关系的类在一起运行, 只要适配器这个角色能够搞定
他们就成。 - 增加了类的透明性
想想看, 我们访问的Target目标角色, 但是具体的实现都委托给了源角色, 而这些对高
层次模块是透明的, 也是它不需要关心的。 - 提高了类的复用度
当然了, 源角色在原有的系统中还是可以正常使用, 而在目标角色中也可以充当新的演
员。 - 灵活性非常好
某一天, 突然不想要适配器, 没问题, 删除掉这个适配器就可以了, 其他的代码都不用
修改, 基本上就类似一个灵活的构件, 想用就用, 不想就卸载
适配器模式的使用场景
你有动机修改一个已经投产中的接口时, 适配器模式可能是最适合你的模式。 比如系统扩展了, 需要使用一个已有或新建立的类, 但这个类又不符合系统的接口,怎么办?使用适配器模式。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。