1、代理模式(Proxy)
代理通常用于网络访问中,允许客户端通过代理与另一个网络终端实现非直接的连接。代理模式的思想就是来自于网络代理,创建一个类来代表现有的一个类,以便向外界提供功能接口,也可以认为是现有类的一个访问层。通常在直接访问类比较麻烦或代价较高的情况下实行。
代理模式的结构如下
1.1 简单代码框架
主要包括一个接口和实现这个接口的两个实例类,其中一个为代理类。以下实现一个从磁盘中加载图片的操作。
public interface Image{
void display();
}
public class RealImage implements Image{
private String fileName;
public RealImage(String fileName){//构造函数
this.fileName=fileName;
loadFromDisk(fileName);
}
@Override
public void display(){
...
}
private void loadFromDisk(String fileName){//从磁盘装载文件,代价高
...
}
}
//代理类
public class ProxyImage implements Image{
private Image realImage;
private String fileName;
public ProxyImage(String fileName){//代理类的构造函数无需从文件装载
this.fileName=fileName;
}
@Override
public void display(){
if(realImage==null){
realImage=new RealImage(fileName);//Delegate到原来的类完成具体的装载
}
realImage.display();
}
}
此时客户端通过代理类来加载图片。
public Client{
...
Image image=new ProxyImage("test.jpg");
image.display();
...
}
- 代理模式的优点 ;代理类的职责比较清晰,扩展性较好
- 缺点;由于在客户端和真是调用类中添加了代理类,处理速度可能会变慢,实现可能会比较复杂
2、适配器模式(Adapter)
适配器模式主要解决要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的情况,更具体地,用来解决类之间接口不兼容的问题,或为已有的类提供新的接口。主要思路是将一个类的接口转换成客户端希望的另外一个接口。适配器模式的一个直观的例子就是通过type-c实现USB接口和手机之间的连接。
适配器模式的结构(两种,一种为继承,另一种是delegation)如下:
2.1、代码框架
一个简单的例子;已存在一个Consultant类,其中有一个表示快乐情感的函数ShowHappiness(),而Client端调用的目标接口定义了与这个函数功能接近的函数ShowSmile,因此可以使用适配器来解决目标接口和已有类方法不兼容的情况。这个例子中Adapter使用委托的方式调用已存在的类。
//已存在的类
public Class Consultant{
private String name;
public Consultant(String name){
this.name=name;
}
protected void ShowHappiness(){
System.out.println(...);
...
}
}
//目标接口
public interface Employee{
void ShowSmile();
}
//Adapter
public class EmployeeAdapter extends Consultant implements Employee{
public EmployeeAdapter(String name){
super(name);
}
@Override
public void ShowSmile(){
ShowHappiness();//调用已存在类中的函数
}
}
客户端Client类中的实现
public class Client{
public static void main(String[] args){
Employee employee=new EmployeeAdapter("Alien");
employee.ShowSmile();
}
}
适配器模式的优点;
- 客户端通过适配器可以透明地调用目标接口
- 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者
- 灵活性好
适配器模式的缺点
- 过多的适配器会使得系统比较复杂
- JAVA 中一个类至多继承一个类,所以至多只能适配一个适配类,而且目标类必须是抽象类
3、代理模式 vs 适配器模式
- 适配器模式的目的是消除不兼容性,B以客户端期望的统一的方式与A建立起联系;
- 代理模式的目的是隔离对复杂对象的访问,降低难度/代价;
- 适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口;