为另一个对象提供一个替身或占位符以控制对这个对象的访问,简而言之就是用一个对象来代表另一个对象。
类图:
简单例子:有个接口Italk,people对象实现这个接口的talk()方法,有些想另外加入sing()方法,所以增加代理类talkProxy,实现两个方法.
public interface ITalk
{
public void talk(String msg);
}
public class People implements ITalk
{
@Override
public void talk(final String msg)
{
System.out.println(msg);
}
}
public class TalkProxy implements ITalk
{
ITalk italk;
public TalkProxy(final ITalk italk)
{
this.italk = italk;
}
@Override
public void talk(final String msg)
{
this.italk.talk(msg);
}
public void sing(final String songName)
{
System.out.println("Song Name:" + songName);
}
}
public class Client
{
public static void main(final String[] args)
{
final People people = new People();
people.talk("I can't sing");
final TalkProxy proxy = new TalkProxy(people);
proxy.talk("I can talk");
proxy.sing("I can sing");
}
}
结果:
I can't sing
I can talk
Song Name:I can sing
常见的代理:
1. 远程代理(Remote Proxy):为一个位于不同的地址空间的对象提供一个本地的代理对象。这个不同的地址空间可以是在同一台主机中,也
可是在另一台主机中,远程代理又叫做大使(Ambassador)。
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface MyRemote extends Remote
{
public String getUserName(String userId) throws RemoteException;
}
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class MyRemoteImp extends UnicastRemoteObject implements MyRemote
{
protected MyRemoteImp() throws RemoteException
{
}
public String getUserName(String userId) throws RemoteException
{
return userId + "/myName is Cherry";
}
}
在cmd中输入:
javac MyRemote.java
javac MyRemoteImp.java
rmic MyRemoteImp
生成类的class文件及MyRemoteImp_Stub.class文件
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
public class MyRemoteServer
{
public static void main(final String[] args)
{
// YTODO Auto-generated method stub
MyRemote remote;
try
{
remote = new MyRemoteImp();
Naming.rebind("RemoteService", remote);
}
catch (final RemoteException e)
{
// YTODO Auto-generated catch block
e.printStackTrace();
}
catch (final MalformedURLException e)
{
// YTODO Auto-generated catch block
e.printStackTrace();
}
}
}
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
public class MyRemoteClient
{
public static void main(final String[] args)
{
try
{
final MyRemote service = (MyRemote) Naming.lookup("rmi://127.0.0.1/RemoteService");
final String name = service.getUserName("my id is 001");
System.out.println(name);
}
catch (final MalformedURLException e)
{
e.printStackTrace();
}
catch (final RemoteException e)
{
e.printStackTrace();
}
catch (final NotBoundException e)
{
e.printStackTrace();
}
}
}
在dos下运行rmiregistry, 这个命令是开启RMI注册服务, 开启以后我们的server程序才能调用rebing方法发布我们的类,然后运行server程序
.
javac MyRemoteServer.java
java MyRemoteServer
start rmiregistry
javac MyRemoteServer.java
java MyRemoteServer
再打开一个dos运行客户端代码
javac MyRemoteClient.java
java MyRemoteClient
输出:my id is 001/myName is Cherry
这里一共有三个dos窗口, 当执行start rmiregistry时,会弹出它的窗口,当执行java MyRemoteServer的服务器端窗口,执行java
MyRemoteClient的客户端窗口(这里的rmiregistry.exe的窗口需要一直打开,否则无法调用服务器端).
2. 虚拟代理(Virtual Proxy):根据需要创建开销很大的对象。如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表
示,真实对象只会在需要时才会被真正创建。
public interface Image
{
public void show();
}
public class BigImage implements Image
{
public BigImage()
{
//Thread.sleep(3000);//for simulating to load the big images
System.out.println("create the big images");
}
@Override
public void show()
{
System.out.println("show the big images");
}
}
public class ImageProxy implements Image
{
Image image;
public ImageProxy()
{
}
public ImageProxy(final Image image)
{
this.image = image;
}
@Override
public void show()
{
if (this.image == null)
{
this.image = new BigImage();
}
this.image.show();
}
}
public class Client
{
public static void main(final String[] args)
{
System.out.println("big image:");
final Image bigImage = new BigImage();
bigImage.show();
System.out.println("image proxy:");
final Image imageProxy = new ImageProxy();
imageProxy.show();
}
}
结果:
create the big images
show the big images
image proxy:
create the big images
show the big images
3. Copy-on-Write代理: 虚拟代理的一种,把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。
4. 保护代理(Protection or Access Proxy):控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
5. 智能指引(Smart Reference):取代了简单的指针,它在访问对象时执行一些附加操作.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述