一、定义
解决两个软件实体间的接口不兼容的问题,对不兼容的部分进行适配。
二、核心
将一个类的接口转换为所希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
三、实现
借鉴android中ListView的适配器ListViewAdapter,粗略仿写一个。
// 设置适配抽象类
class ListViewAdapter {
getCount() {}
getItem(index) {}
renderItem (index) {}
}
// 需要使用适配器的类
class ListView {
constructor () {
this.adapter = null;
}
// 设置一个适配器
setAdapter (adapter) {
this.adapter = adapter
}
// (粗略)渲染ListView,即把每一个子项数据渲染出来。
render () {
if (!this.adapter) return;
const count = this.adapter.getCount();
for(let i = 0; i < count; i++) {
this.adapter.renderItem(i)
}
}
}
// 测试 - 实现适配器
class MyAdapter extends ListViewAdapter {
constructor() {
super()
this.list = [{name: '张三'}, {name: '李四'}, {name: '王五'}]
}
getCount () {
return this.list.length;
}
getItem (index) {
return this.list[index];
}
renderItem (index) {
const item = this.getItem(index);
console.log('itme name:' + item.name)
}
}
// 配置使用适配器
const listView = new ListView();
listView.setAdapter(new MyAdapter());
listView.render();
// 输出:
itme name:张三
itme name:李四
itme name:王五
#适配器还可以方便只实现自己需要的方法,例如上面的MyAdapter类,可以不实现getItem方法。
class MyAdapter extends ListViewAdapter {
constructor() {
super()
this.list = [{name: '张三'}, {name: '李四'}, {name: '王五'}]
}
getCount () {
return this.list.length;
}
renderItem (index) {
const item = this.list[index];
console.log('itme name:' + item.name)
}
}
四、优缺点
优点
- 将目标类和和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无需修改原有代码;
- 增加了代码的透明性和复用性,将具体的实现封装在适配者类中,对于客户端来说是透明的,而且提高了适配者的复用性;
- 灵活性和扩展性都比较好,通过配置文件,可以方便的更换适配器,也可以在不修改原有代码的基础上增加新的适配器,符合开闭原则。
缺点
- 若设计得不合理,当使用适配器的地方需要修改的时候,可能导致所有使用实现了适配器的地方都需要更改。