题目
现有一个接口DataOperation定义了排序方法sort(int[])和查找方法search(int[], int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法,类BinarySearch的binarySearch(int[], int)方法实现了二分查找算法。
试使用适配器模式设计一个系统,在不修改源代码的情况下将类QuickSort和类BinarySearch的方法适配到DataOperation接口中。绘制类图并编程实现。(要求实现快速排序和二分查找,使用对象适配器实现)
类图
实现代码
/*
*author:Renard_H
*/
package com.back.huangliqing;
public interface DataOperation{
public void sort(int data[ ]); // 排序方法
public void search(int[ ] list, int key); // 查找方法
}
/*
author:Renard_H
*/
package com.back.huangliqing;
public class SunanFaAdapter implements DataOperation{
private QuickSort quicksort; // 定义适配者QuickSort的对象
private BinarySearch binarysearch; // 定义适配者 BinarySearch的对象
// 构造函数初始化适配者对象
public SuanFaAdapter( ){
quicksort = new QuickSort( ); // 实例化QuickSort对象
binarysearch = new BinarySearch( ); //实例化 BinarySearch对象
}
@Override
public void sort(int data[ ]){
// 建立连接实现快速排序
quicksort.quickSort(data); // 通过对象调用实现快速排序的功能
}
@Override
public void search(int[ ] list, int key){
// 建立连接实现二分查找
binarysearch.binarySearch(list, key); // 通过对象调用实现二分查找的功能
}
}
/*
*author:Renard_H
*/
public class QuickSort{
// 快速排序
public void quickSort(int data[ ]){
java.util.Arrays.sort(data); // 直接调用排序方法
print(data);
}
// 数组输出
public void print(int data[ ]){
for(int x=0; x<data.length; x++){
System.out.print(data[x]+"、");
}
}
}
/*
*author:Renard_H
*/
package com.back.huangliqing;
// 二分查找
public void binarySearch(int[ ] list, int key){
// 调用 java.util.Arrays 的binarySearch 二分查找方法
System.out.print(java.util.Arrays.binarySearch(list, key));
}
}
/*
*author:Renard_H
*/
package com.back.huangliqing;
public class Client{
public static void main(String[ ] args){
// TODO 自动生成的方法存根
// 定义一个数组
int data[ ]=new int[ ]{2,4,1,5,3,8,6,7};
DataOperation operation; // 定义接口对象
operation=new SuanFaAdapter( ); // 实例化接口对象向上转型
System.out.println("排序前的数组:");
for(int i=0; i<data.length; i++){
System.out.print(data[i]+"、");
}
System.out.println("\n\n排序后的数组");
operation.sort(data); //调用排序
// 查找数据4所在的下表
System.out.println("\n\n输出数字4所在的索引:");
operation.search(data, 4); //调用查找
}
}
适配器
适配器模式的三个分类
适配器模式又称为包装器,是用来将一个类的接口转换成客户希望的另外一个接口。这可以使得原本由于接口不兼容而不能在一起工作的那些类可以一起工作
适配器模式的关键是建立一个适配器,这个适配器实现类目标接口并且包含了被适配者的引用。
类图
适配器中各个类的含义:
- 源(Adaptee): 需要被适配的对象或类型,相当于二座插头
- 适配器(Adapter): 连接目标和源的中间对象,相当于交流电适配器
- 目标(Target): 期待得到的目标接口,相当于插座
适配器模式分为类适配器器,对象适配器和接口适配器模式
对象适配器
UML 类图
target 目标角色:
该角色定义把其他类转换为何种接口,也就是我们的期望接口
Adapter 适配器角色:
- 适配器模式核心角色,其他两个角色都是已经存在的角色,而适配器角色是需要新建立的
- 主要职责: 把源角色转换为目标角色,通过继承或是持有类引用关联的方式
Adaptee 源角色:
想要把谁转换成目标角色,“谁” 就是源角色,它是已经存在的、运行良好的类或对象,通过适配器角色的包装,它会成为一个崭新的靓丽的角色
优点
- 将目标类和适配器类解耦
- 增加了类的透明性和复用性,通过一个适配器可以重用现有的适配者类
- 灵活性和扩展性好,符合开闭原则
缺点
- 对于 Java 、 C++ 等不支持多重继承的语言,一次最多只能适配一个适配者
- 适配者不能作为最终类
- 在 Java 等语言中类适配器的目标抽象类必须是接口,不能为类