理解代理模式:使用房屋中介案例
代理模式(Proxy Pattern)是结构型设计模式之一,通过代理对象来控制对真实对象的访问。代理对象在不改变真实对象的情况下,可以添加一些额外的逻辑,例如访问控制、延迟加载等。本文将通过一个房屋中介的案例,详细介绍代理模式的概念、应用场景以及代码实现。
什么是代理模式?
代理模式 | 菜鸟教程 (runoob.com)
代理模式提供了一个代理对象,控制对其他对象的访问。代理对象可以在不改变真实对象的情况下,添加额外的功能或控制。代理模式通常用于以下场景:
-
访问控制:控制对资源的访问权限。
-
性能优化:在实际使用时才创建和初始化资源。
-
日志记录:记录对真实对象的操作日志。
-
远程代理:控制对远程对象的访问。
代理模式的优缺点
优点:
-
单一职责原则:代理模式将实际的业务处理和附加的功能分离开来,使代码更加清晰和可维护。
-
开闭原则:可以在不修改现有代码的情况下,通过代理模式添加新功能。
-
控制访问:代理对象可以控制对真实对象的访问。
缺点:
-
增加复杂性:引入代理对象会增加系统的复杂性和理解难度。
-
性能开销:代理模式会带来一些额外的性能开销,例如方法调用的额外开销。
案例介绍
小明想要购买一套房子,他决定寻求一家房屋中介来帮助他找到一个面积超过100平方米的房子,只有符合条件的房子才会被传递给小明查看。
【设计模式专题之代理模式】7-小明买房子 (kamacoder.com)
输入描述
第一行是一个整数 N(1 ≤ N ≤ 100),表示可供查看的房子的数量。
接下来的 N 行,每行包含一个整数,表示对应房子的房屋面积。
输出描述
对于每个房子,输出一行,表示是否符合购房条件。如果房屋面积超过100平方米,输出 "YES";否则输出 "NO"。
输入示例
3 120 80 110
输出示例
YES NO YES
代码实现
我们将通过代理模式来实现这个需求,首先定义一个 House
接口,然后定义 RealHouse
类和 ProxyHouse
类。
-
定义接口
House
:-
House
接口定义了一个display
方法,所有房子类都要实现这个方法。
-
interface House {void display();
}
-
真实对象
RealHouse
:-
RealHouse
实现了House
接口,表示具体的房子。它有一个size
属性表示房子的面积。 -
display
方法用于输出房子的基本信息,在这个例子中输出 "YES"。
-
class RealHouse implements House {private int size;public RealHouse(int size) {this.size = size;}public int getSize() {return size;}@Overridepublic void display() {System.out.println("YES");}
}
-
代理对象
ProxyHouse
:-
ProxyHouse
也实现了House
接口,包含一个List<RealHouse>
用于存储所有的房子对象。 -
addHouse
方法用于添加房子对象到列表中。 -
display
方法遍历房子列表,检查每个房子的面积是否大于100平方米,如果大于则调用RealHouse
的display
方法输出 "YES",否则输出 "NO"。
-
class ProxyHouse implements House {private List<RealHouse> realHouses = new ArrayList<>();public void addHouse(RealHouse realHouse) {realHouses.add(realHouse);}@Overridepublic void display() {for (RealHouse realHouse : realHouses) {if (realHouse.getSize() > 100) {realHouse.display();} else {System.out.println("NO");}}}
}
-
主程序
Main
:-
从输入中读取房子的数量和面积。
-
创建
ProxyHouse
实例,并将每个RealHouse
对象添加到代理对象中。 -
调用代理对象的
display
方法,显示房子的筛选结果。
-
public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();ProxyHouse proxyHouse = new ProxyHouse();for (int i = 0; i < n; i++) {int size = sc.nextInt();RealHouse realHouse = new RealHouse(size);proxyHouse.addHouse(realHouse);}proxyHouse.display();sc.close();}
}
代理模式的作用
在这个案例中,代理模式的作用如下:
-
ProxyHouse
对象作为RealHouse
对象的代理,对外提供统一的接口display
。 -
ProxyHouse
对象在调用RealHouse
的display
方法之前,先进行了面积的检查,只有面积大于100平方米的房子才会调用RealHouse
的display
方法输出 "YES",否则输出 "NO"。
通过代理模式,我们将筛选逻辑从主程序中抽离出来,封装到 ProxyHouse
类中,使得代码更加清晰,符合单一职责原则。代理模式还可以让我们在不修改 RealHouse
类的情况下,添加额外的控制逻辑,提高代码的灵活性和可维护性。
完整代码
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;// House接口
interface House {void display();
}// RealHouse类实现House接口
class RealHouse implements House {private int size;public RealHouse(int size) {this.size = size;}public int getSize() {return size;}@Overridepublic void display() {System.out.println("YES");}
}// ProxyHouse类实现House接口
class ProxyHouse implements House {private List<RealHouse> realHouses = new ArrayList<>();public void addHouse(RealHouse realHouse) {realHouses.add(realHouse);}@Overridepublic void display() {for (RealHouse realHouse : realHouses) {if (realHouse.getSize() > 100) {realHouse.display();} else {System.out.println("NO");}}}
}public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();ProxyHouse proxyHouse = new ProxyHouse();for (int i = 0; i < n; i++) {int size = sc.nextInt();RealHouse realHouse = new RealHouse(size);proxyHouse.addHouse(realHouse);}proxyHouse.display();sc.close();}
}
总结
代理模式在软件设计中有广泛的应用,它通过一个代理对象控制对真实对象的访问,使代码更具灵活性和可维护性。在本例中,我们通过代理模式实现了房屋中介的功能,筛选出符合条件的房子并展示给小明。希望通过这个案例,大家能更好地理解代理模式的概念和应用场景,并在实际开发中灵活应用。