一天无意中在github上搜索,发现了在Java领域stars排名最多的一个项目:iluwatar/java-design-patterns 里面总结了许多在我们开发过程中会使用到的设计模式,以前虽然也学习过,可是总很快就忘,在这里打算再一个一个学习一下。
适配器,是为了适应两个原本不兼容的接口而诞生的设计模式,用我们的话说就是转接口,或者桥梁,属于结构性模式。适配器有三种:类适配器,对象适配器和接口适配器。区别三种方式也很简单,就是判断这个适配器是通过什么实现的,如果通过类就是类适配器,如果通过对象就是对象等。
举个例子,在公众号我们只能发文章,而没有类似APP题库刷题的功能,如果此时我想通过公众号来刷题?难道我们要腾讯去做一个能刷题公众号?显然不容易实现,这个时候我们可以通过一个小程序实现刷题。因为我们知道,小程序可以很容易的去实现刷题的功能,公众号有阅读文章的功能,而只要实现公众号到小程序的转换即可。这个转换在设计模式中称为适配器。 在这里使用两种方式实现
在开发过程中,我们发现在我们访问的接口A中没有我们需要方法B,我们由于某些原因又不能改变访问接口A。此时在接口B中发现了方法B,此时我们可以通过一个适配器来进行中转。如果在中转的过程中,我们的适配器继承接口B的实现类同时也实现接口A,那么此时就是类适配器。
此例子的关系图如下图所示:
//公众号接口
interface OfficialAccounts {
void readArticle();
}
//小程序接口
interface MiniProgram {
void itemBank();
}
//公众号实现类
class OfficialAccountsimp implements OfficialAccounts {
@Override
public void readArticle() {
System.out.println("关注每天学Java公众号,每日都会有文章推送哦");
}
}
//小程序实现类
class MiniProgramiml implements MiniProgram {
@Override
public void itemBank() {
System.out.println("进入每天学Java小程序,每日都有题库更新哦");
}
}
//类适配
class Adapter extends MiniProgramiml implements OfficialAccounts {
@Override
public void readArticle() {
super.itemBank();
}
}
//测试类
public static void main(String[] args) {
new Adapter().readArticle();
}
进入每天学Java小程序,每日都有题库更新哦
通过结果我们发现,我们使用公众号OfficialAccounts的接口实现了小程序MiniProgram的接口的功能。。 讲解:
在开发过程中,我们发现在我们访问的接口A中没有我们需要方法B,我们由于某些原因又不能改变访问接口A。此时在接口B中发现了方法B,此时我们可以通过一个适配器来进行中转。如果在中转的过程中,我们的适配器类持有私有变量B实现A接口,变量B通过构造方法进行实例化,那么此时就是使用的对象适配器。
对象适配器与类适配器很类似,不一致的地方在于适配器那里。
//对象适配器
class ObjAdapter implements OfficialAccounts {
private MiniProgram miniProgram;
public ObjAdapter(MiniProgram miniProgram) {
this.miniProgram = miniProgram;
}
@Override
public void readArticle() {
miniProgram.itemBank();
}
}
测试类
public static void main(String[] args) {
// new Adapter().readArticle();
new ObjAdapter(new MiniProgramiml()).readArticle();
}
结果:
进入每天学Java小程序,每日都有题库更新哦
我们都知道,在我们实现接口时一定要实现里面所有的方法,而如果我们要继承一个类,就可以实现某个我们需要的方法。而接口适配器就是实现接口的抽象类,这样我们只需要继承这个接口适配器就能操作我们需要使用的方法了。 对于接口适配器,我们可能都见过。在java.awt.event包中有许多适配器,比如监控键盘事件的接口KeyListener
public interface KeyListener extends EventListener {
/**
* Invoked when a key has been typed.
* See the class description for {@link KeyEvent} for a definition of
* a key typed event.
*/
public void keyTyped(KeyEvent e);
/**
* Invoked when a key has been pressed.
* See the class description for {@link KeyEvent} for a definition of
* a key pressed event.
*/
public void keyPressed(KeyEvent e);
/**
* Invoked when a key has been released.
* See the class description for {@link KeyEvent} for a definition of
* a key released event.
*/
public void keyReleased(KeyEvent e);
}
KeyListener接口的适配器KeyAdapter
public abstract class KeyAdapter implements KeyListener {
/**
* Invoked when a key has been typed.
* This event occurs when a key press is followed by a key release.
*/
public void keyTyped(KeyEvent e) {}
/**
* Invoked when a key has been pressed.
*/
public void keyPressed(KeyEvent e) {}
/**
* Invoked when a key has been released.
*/
public void keyReleased(KeyEvent e) {}
}
在jframe中,如果我们要监听键盘按下事件,只需继承KeyAdapter抽象类,然后实现keyPressed方法即可。
今天小程序更新的题库:
1.你知道里氏替换原则吗?
2.举例说明你什么时候会用抽象类,什么时候更愿意使用接口?
3.谈一谈Java设计模式中的结构型模式
4.说一说你对适配器模式的理解?
5.说一说适配器模式使用场景?