定义
代理模式是一种结构型设计模式,它允许通过创建一个代理对象来控制对另一个对象的访问。代理模式在不改变原始对象的情况下,提供了对其方法的间接访问,从而可以在调用前后执行额外的逻辑或控制访问权限。
代理模式涉及三个核心角色:
-
抽象主题(Subject):定义了真实主题和代理主题的共同接口,这样代理对象可以替代真实对象。它通常是一个接口或抽象类。
-
真实主题(Real Subject):实现了抽象主题接口,是真正执行业务逻辑的类。
-
代理(Proxy):实现了抽象主题接口,持有对真实主题的引用。在需要时,它将请求传递给真实主题,并可以在请求前后执行额外的逻辑。
代理模式的主要目的是控制对真实主题的访问,它可以提供以下功能:
- 远程代理:通过代理对象在不同的地址空间中创建对象,使得客户端可以访问远程对象,如远程方法调用(RPC)。
- 虚拟代理:延迟创建真实主题对象,直到需要的时候,以提升性能。
- 安全代理:控制对真实主题的访问权限,例如在访问前进行身份验证或权限检查。
- 智能代理:在调用真实主题的方法前后执行额外的逻辑,例如缓存结果、记录日志等。
代理模式可以增加代码的灵活性和可维护性,它可以隐藏真实主题的实现细节,同时提供了额外的功能和控制。
示例一:显示图片
// 抽象主题接口
interface Image {
void display();
}
// 真实主题类
class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadFromDisk();
}
private void loadFromDisk() {
System.out.println("Loading image: " + filename);
}
@Override
public void display() {
System.out.println("Displaying image: " + filename);
}
}
// 代理类
class ImageProxy implements Image {
private String filename;
private RealImage realImage;
public ImageProxy(String filename) {
this.filename = filename;
}
@Override
public void display() {
if (realImage == null) {
realImage = new RealImage(filename);
}
realImage.display();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
// 使用代理对象访问图片
Image image = new ImageProxy("image.jpg");
// 图片首次显示
image.display();
System.out.println("------");
// 图片再次显示
image.display();
}
}
在上面的示例中,我们定义了抽象主题接口 Image,并有一个具体的实现类 RealImage,它代表真正的图片。然后我们创建了一个代理类 ImageProxy,它实现了抽象主题接口,并持有对真实主题的引用。在代理类的 display() 方法中,我们在首次访问时创建真实图片对象,并调用其 display() 方法显示图片。
客户端代码通过创建代理对象 ImageProxy 来访问图片。在第一次调用 display() 方法时,代理对象会创建真实图片对象,并调用其 display() 方法显示图片。在后续的调用中,代理对象直接调用真实图片对象的 display() 方法。
输出结果:
Loading image: image.jpg
Displaying image: image.jpg
------
Displaying image: image.jpg
通过这个示例,我们演示了代理模式的应用。代理对象 ImageProxy 控制了对真实图片对象 RealImage 的访问,并在需要时进行了创建,从而实现了对真实主题的间接访问和控制。
示例二:房地产经纪人
房地产经纪人充当买家和卖家之间的中介,他们协助买家找到适合的房产,并促进买卖交易的进行。以下是一个简单的示例:
// 抽象主题接口
interface House {
void sell();
}
// 真实主题类
class HouseSeller implements House {
private String address;
public HouseSeller(String address) {
this.address = address;
}
@Override
public void sell() {
System.out.println("House for sale at " + address);
}
}
// 代理类
class RealEstateAgent implements House {
private HouseSeller houseSeller;
public RealEstateAgent(HouseSeller houseSeller) {
this.houseSeller = houseSeller;
}
@Override
public void sell() {
System.out.println("Agent showing the house to potential buyers");
houseSeller.sell();
System.out.println("Agent facilitating the sale process");
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
HouseSeller houseSeller = new HouseSeller("123 Main St");
House realEstateAgent = new RealEstateAgent(houseSeller);
realEstateAgent.sell();
}
}
在上面的示例中,HouseSeller 是真实主题类,代表了要出售的房产。RealEstateAgent 是代理类,它持有对真实主题对象的引用,并在 sell() 方法中添加了额外的逻辑。当代理对象被调用时,它会先展示房屋给潜在买家,然后调用真实主题对象的 sell() 方法进行房屋出售,最后完成交易的过程。
客户端代码通过创建代理对象 RealEstateAgent 来实现买卖房屋的过程。代理对象充当买家和卖家之间的中介,负责展示房屋、促进交易,并在交易过程中提供支持。
输出结果:
Agent showing the house to potential buyers
House for sale at 123 Main St
Agent facilitating the sale process
通过这个例子,我们可以看到代理模式在房地产经纪人的场景中的应用。代理对象 RealEstateAgent 控制了买家对房产的访问,通过添加额外的逻辑和功能,使交易过程更加顺利和方便。