设计模式之适配器模式与外观模式
时间:2019-02-05 分类:设计模式 作者:编程之家用户
适配器模式
适配器模式就是将一个接口转化成另一个接口。
一个常见的例子是插头转换器
我们知道英式插头长这样:
而国内的插头一般是这样的
这时候,你就需要一个转换插头了
而适配器的工作就像是一个转换插头。你不需要从新买一个电器,也不用换一个插孔,只需要一个转换器即可。
假设已有一个软件系统,你希望它能和新的厂商类库搭配使用,但是这个新厂商设计出来的接口,不同于旧厂商的接口。
你不想改变现有的代码,也不能改变厂商的代码,于是你可以写一个类,将新厂商接口转成你所希望的接口。
情景:
首先你有一个鸭子接口(这书有毒啊啊啊这都什么破例子)
有一个鸭子的子类
MallardDuck @Override
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> quack() {
System.out.println(</span>"Quack"<span style="color: #000000;">);
}
@Override
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> fly() {
System.out.println(</span>"I'm flying"<span style="color: #000000;">);
}
}
然后现在有一只火鸡
<div class="cnblogs_code">
WildTurkey @Override
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> gobble() {
System.out.println(</span>"Gobble gobble"<span style="color: #000000;">);
}
@Override
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> fly() {
System.out.println(</span>"I'm flying a short diatance"<span style="color: #000000;">);
}
}
因为你想要鸭子,鸭子不够用了,但是我们有火鸡,于是你决定为火鸡写一个配适器,偷偷地假装它们是鸭子。。。。
当需要鸭子叫的时候,就让火鸡叫,当需要鸭子飞的时候,就让火鸡飞。火鸡飞的距离短,所以还要多飞几次。
TurkeyAdapter </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> TurkeyAdapter(Turkey turkey) {
</span><span style="color: #0000ff;">this</span>.turkey =<span style="color: #000000;"> turkey;
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> quack() {
turkey.gobble();
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> fly() {
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 火鸡飞行距离短 要连续飞五次才能对应鸭子的飞行</span>
<span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i < 5; ++<span style="color: #000000;">i) {
turkey.fly();
}
}
}
然后测试一下:
= WildTurkey turkey </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> WildTurkey();
Duck turkeyAdapter </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> TurkeyAdapter(turkey);
System.out.println(</span>"The turkey says..."<span style="color: #000000;">);
turkey.gobble();
turkey.fly();
System.out.println(</span>"\nThe Duck says..."<span style="color: #000000;">);
testDuck(duck);
System.out.println(</span>"\nThe TurkeyAdapter says..."<span style="color: #000000;">);
testDuck(turkeyAdapter);
}
</span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> testDuck(Duck duck) {
duck.quack();
duck.fly();
}
}
输出:
'm flying a short diatance
'm flying
'm flying a short diatance
I'm flying a short diatance
I'm flying a short diatance
I'm flying a short diatance
I'm flying a short diatance
我们就可以把火鸡当成鸭子了~(真·有毒。。。。
类图:
上面的类图表现的是“对象”适配器,还有一种适配器,被称作“类”适配器,需要多重继承才能实现,所以在Java中是不可能的。
现实世界一个简单的适配器。
在早期的集合实现如Vector,Stack,HashTable都实现了一个elements()的方法,该方法会返回一个Enumeration,这个接口可以逐一走过集合内的每一个元素。
而新的集合类,使用Iterator来遍历集合。
现在,将枚举适配到迭代器。
<span style="color: #0000ff;">public <span style="color: #0000ff;">class EnumerationIterator <span style="color: #0000ff;">implements<span style="color: #000000;"> Iterator {
Enumeration enu;
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> EnumerationIterator(Enumeration enu) {
</span><span style="color: #0000ff;">this</span>.enu =<span style="color: #000000;"> enu;
}
@Override
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;"> hasNext() {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> enu.hasMoreElements();
}
@Override
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Object next() {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> enu.nextElement();
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> remove() {
</span><span style="color: #0000ff;">throw</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> UnsupportedOperationException();
}
}
反过来也可以将迭代器适配到枚举
<span style="color: #0000ff;">public <span style="color: #0000ff;">class IteratorEnumeration <span style="color: #0000ff;">implements<span style="color: #000000;"> Enumeration {
Iterator iterator;
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> IteratorEnumeration(Iterator iterator) {
</span><span style="color: #0000ff;">this</span>.iterator =<span style="color: #000000;"> iterator;
}
@Override
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;"> hasMoreElements() {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> iterator.hasNext();
}
@Override
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Object nextElement() {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> iterator.next();
}
}
测试一下:
<span style="color: #0000ff;">public <span style="color: #0000ff;">class <span style="color: #000000;"> ArrayListEnumTest {
<span style="color: #0000ff;">public <span style="color: #0000ff;">static <span style="color: #0000ff;">void<span style="color: #000000;"> main(String[] args) {
ArrayList list = <span style="color: #0000ff;">new<span style="color: #000000;"> ArrayList();
list.add("适"<span style="color: #000000;">);
list.add("配"<span style="color: #000000;">);
list.add("器"<span style="color: #000000;">);
list.add("模"<span style="color: #000000;">);
list.add("式"<span style="color: #000000;">);
Iterator iterator =<span style="color: #000000;"> list.iterator();
Enumeration ei = <span style="color: #0000ff;">new<span style="color: #000000;"> IteratorEnumeration(iterator);
showListByEnum(ei);
}
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 一些遗留的“客户代码”仍然使用依赖于枚举接口</span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> showListByEnum(Enumeration enumeration) {
</span><span style="color: #0000ff;">while</span><span style="color: #000000;"> (enumeration.hasMoreElements()) {
System.out.print(enumeration.nextElement());
}
}
}
外观模式
情景:当你需要看一场电影的时候,你可能需要调灯光放屏幕打开投影机选择模式……每一次都是一样的步骤,等结束的时候,又是一系列繁琐的动作。
如果提供一个简单的类,能够一下就完成这一系列工作就好了。
这时就需要用外观模式,将一系列子类包装起来,提供一个简单的接口,来替代访问一系列子系统的接口。
外观模式不只简化了接口,也将客户从组件的子系统中解耦。
外观模式和适配器模式可以包装许多类,但外观的意图是简化接口,而适配器的意图是将接口转换成不同接口。
原谅自己只能写一个拙劣的例子,折叠掉。。。
<span style="color: #0000ff;">public <span style="color: #0000ff;">class<span style="color: #000000;"> FacadeTest {
<span style="color: #0000ff;">public <span style="color: #0000ff;">static <span style="color: #0000ff;">void<span style="color: #000000;"> main(String[] args) {
A a = <span style="color: #0000ff;">new<span style="color: #000000;"> A();
B b = <span style="color: #0000ff;">new<span style="color: #000000;"> B();
C c = <span style="color: #0000ff;">new<span style="color: #000000;"> C();
Facade facade = <span style="color: #0000ff;">new<span style="color: #000000;"> Facade(a,b,c);
facade.ABC1();
System.out.println();
facade.ABC2();
}
}
<span style="color: #0000ff;">class<span style="color: #000000;"> A {
<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> a1() {
System.out.println("a1"<span style="color: #000000;">);
}
<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> a2() {
System.out.println("a2"<span style="color: #000000;">);
}
}
<span style="color: #0000ff;">class<span style="color: #000000;"> B {
<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> b1() {
System.out.println("b1"<span style="color: #000000;">);
}
<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> b2() {
System.out.println("b2"<span style="color: #000000;">);
}
}
<span style="color: #0000ff;">class<span style="color: #000000;"> C {
<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> c1() {
System.out.println("c1"<span style="color: #000000;">);
}
<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> c2() {
System.out.println("c2"<span style="color: #000000;">);
}
}
<span style="color: #0000ff;">class<span style="color: #000000;"> Facade {
A a;
B b;
C c;
<span style="color: #0000ff;">public<span style="color: #000000;"> Facade(A a,B b,C c) {
<span style="color: #0000ff;">this.a =<span style="color: #000000;"> a;
<span style="color: #0000ff;">this.b =<span style="color: #000000;"> b;
<span style="color: #0000ff;">this.c =<span style="color: #000000;"> c;
}
<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> ABC1() {
a.a1();
b.b1();
c.c1();
}
<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> ABC2() {
a.a2();
b.b2();
c.c2();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。