您的位置:首页 > 其它

设计模式学习笔记1 - Adapter(适配器模式)

2009-09-19 00:03 591 查看
Adapter是常用设计模式之一,通过他可以将一个类的接口转换成客户希望的另外一个接口。

Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

下面我们来看一个例子:

假设定义了下面四个类:

public class 吃饭 {
public void eat() {
System.out.println("吃饭");
}
}
public class 喝水 {
public void drink() {
System.out.println("喝水");
}
}
public class 睡觉 {
public void sleep() {
System.out.println("睡觉");
}
}
public class 方便 {
public void wc() {
System.out.println("方便");
}
}

现在一个人来了肚子饿了,于是写了下面代码,并且把吃饭传进去,并且调用eat()方法:

public class 人 {
public void dosomething(Object o){
((吃饭)o).eat();
}
}

过了一会,他又想喝水了,于是去改代码,这次又把喝水传进去,把eat()方法改为drink()方法:

public class 人 {
public void dosomething(Object o){
((喝水)o).drink();
}
}

就这样,要睡觉改成调用sleep(),要方便又改成wc()。

没过多久,他就觉得每次都改代码太麻烦了,于是考虑如何把四件事通用出来,但很快他发现由于前期的设计没有考虑周全,

吃饭、喝水、方便、睡觉 并没有统一抽象出一个 doit() 的方法。于是现在只能分别调用各自的eat() drink()等。

而且更糟糕的是吃饭、喝水、方便、睡觉四个类的代码别处也有调用,还不能改,很苦恼。

解决的办法:

首先定义一个接口:

public interface I {
public void doit();
}

然后定一个吃饭的适配器类,让他实现接口I ,并实现抽象方法doit(),聚合 "吃饭" ,在doit()中调用 "吃饭" 的eat()方法。

public class 适配器1 implements I{

public 吃饭 eat = new 吃饭();

public void doit() {
eat.eat();
}

}

修改 "人" 的代码:

public class 人 {
public void dosomething(I i){
i.doit();
}
}

这样在 "人" 这个类中,只要传入适配器1,就可以调用 "吃饭" 的eat()方法了!

其余的按照同样的方法封装出Adapter适配器,这样只要传入不同的Adapter,就会做不同的事,

这里由于有了接口规范,抽象出了doit()方法,

所以以后再也不用改人类的代码了^^

当然适配器也可以使用继承来实现,例如喝水的适配器这样来写:

public class 适配器2 extends 喝水 implements I{

public void doit() {
drink();
}

}

注意:本例中抽象出的是一个接口,所以适配器2方案可行,但如果是抽象类的情况时,方案2会受java单继承的影响不可使用,所以请优先选用聚合的方式。

最后再介绍一下抽象适配器:

例如有下列接口,如果要直接实现这个接口,一定会非常郁闷,因为实现接口意味着你要来实现所有的方法,即便你不需要这个方法 (> <

public interface I {
public void a();
public void b();
public void c();
public void d();
public void e();
public void f();
public void g();
public void h();
...
...
...
}

使用抽象适配器可以帮助我们避免直接实现接口的苦恼:

public abstract class MyAdapter implements I {
public void a(){};
public void b(){};
public void c(){};
public void d(){};
public void e(){};
public void f(){};
public void g(){};
public void h(){};
...
...
...
}

有了抽象适配器,我们就不必痛苦的直接实现接口了,而是从抽象适配器继承。

抽象适配器只会强制重写部分抽象方法,而其他方法已经做了空实现,我们可以自己选择哪个方法来重写,所以非常灵活。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: