目录
1.什么是代理模式:
代理模式是一种结构型设计模式,它允许通过创建一个代理对象来控制对其他对象的访问。代理对象充当了客户端与真实对象之间的中介,可以在访问真实对象前后添加额外的逻辑。代理模式常用于需要对对象进行额外控制或管理的情况,例如访问控制、远程访问、延迟加载等。
代理模式通常包括以下几个角色:
- 抽象主题(Working):定义了真实对象和代理对象之间的共同接口。
- 真实主题(Boss):定义了代理对象所代表的真实对象。
- 代理(Assistant):持有对真实主题的引用,并在其方法调用前后执行额外逻辑。
通过使用代理模式,可以实现对真实对象的访问控制,例如在调用真实对象的方法前进行权限验证。代理还可以提供额外的功能,例如记录日志、统计调用次数等。此外,代理模式还可以用于实现远程代理,使得客户端可以通过代理对象访问远程服务器上的对象。
2.代理模式的例子:
与前几篇设计模式的文章相同,我们在了解到代理模式的实现的时候同样先来看个例子:“假如现在你已经上班了,就在这个时候你有事情需要跟老板汇报,但是你们老板非常忙,所以派了他的助理来配合你工作,而这个助理要做的仅仅就是传达老板的意图,整个过程中老板都不需要亲自来找你”。
3.代理模式的实现:
Working(工作接口):
//代理模式, 工作接口
public interface Working {
//工作方法
public void doWork();
}
Boss(老板):
//老板, 实现工作接口, 并重写doWork方法
public class Boss implements Working{
//当助理找到老板的时候老板的回复方法
@Override
public void doWork() {
System.out.println("老板回复助理");
}
}
Assistant(助理):
//助理, 实现工作接口, 并重写工作方法
public class Assistant implements Working{
private Boss boss;
//在构造函数里使用反射方法建立老板与助理的管理
public Assistant() {
try {
this.boss = (Boss) this.getClass().getClassLoader().loadClass("com.team.testdemo.util.代理模式.Boss").newInstance();
}catch (Exception e){
e.printStackTrace();
}
}
public void assistantSay(){
System.out.println("助理汇报工作");
}
@Override
public void doWork() {
this.assistantSay();
//通过反射获取到Boss的实例后,调用老板的doWorking方法
boss.doWork();
}
}
PS:再此loadClass方法里面传入的参数为Java类名,例如:java.lang.object
PS: 在这里的构造函数使用反射的时候记得写在无参构造里,不然会报空指针,因为在加载一个类的时候如果这个类有父类,则优先执行父类无参构造,且父类无参构造只执行一次,只有等父类执行完成后才会执行子类无参构造。
现在我们的类图如下:
Main(主函数):
//代理模式, 主函数
public class Main {
public static void main(String[] args) {
//创建Assistan实例,并调用doWork()方法
new Assistant().doWork();
}
}
⚪输出结果:
助理汇报工作
老板回复助理
3.代理模式的优缺点:
代理模式具有以下优点:
- 职责清晰:代理模式将真实对象与代理对象分离,使得每个对象都具有清晰的职责,增强了代码的可读性和可维护性。
- 控制访问:代理对象可以控制对真实对象的访问,可以根据需要添加访问控制逻辑,例如权限验证、缓存等。
- 提高性能:代理对象可以对真实对象的访问进行优化,例如延迟加载(懒加载)、缓存等,从而提高系统性能。
然而,代理模式也存在一些缺点:
- 增加复杂性:引入代理对象会增加系统的复杂性,需要额外的代码来管理代理与真实对象之间的关系。
- 降低效率:由于代理对象需要额外的处理逻辑,可能导致访问真实对象时的性能降低。
- 增加开发成本:设计和实现代理模式需要额外的开发工作,增加了开发成本和时间。
因此,使用代理模式时需要权衡其优缺点,根据具体场景和需求进行选择。代理模式通常适用于需要对对象进行控制、管理或优化的情况。
4.什么是责任链模式:
责任链模式是一种行为型设计模式,它允许多个对象按照顺序处理同一个请求,直到其中一个对象能够处理该请求为止。责任链模式将请求的发送者和接收者解耦,使得多个对象都有机会处理请求,而无需显式指定接收者。
在责任链模式中,通常会有一个抽象处理者(Person)定义了处理请求的接口,以及一个具体处理者(Minister, DeputyManager, Manager)实现了具体的处理逻辑。每个具体处理者都包含一个指向下一个处理者的引用,形成了一条链。
当客户端发起请求时,请求会沿着责任链依次传递给每个处理者,直到有一个处理者能够处理该请求。每个处理者可以根据自己的逻辑决定是否将请求传递给下一个处理者。
5.责任模式的例子:
在了解到责任链的具体实现的之前,让我们继续来想一个例子:”假如你现在只需要请一天假,这个时候你给你们部长请假就行了,但是当你需要请到2天以上的假,你就需要找你们公司的副经理请假了,若是你请假时间更长可能就需要找到总经理请假了,而这三个人你可以理解为都在一条线上,第一个人处理不了就第二个人处理,若是第二个人也处理不了,那就最上面的人处理,这样这三个人就连起来了,就像一条链子”。
6.责任链模式的实现:
Person(Person抽象类):
//抽象处理类, person
abstract class Person {
//下一个领导
protected Person nextPerson;
//传入下一个领导方法
public void setNextPerson(Person person){
this.nextPerson = person;
}
//请假天数
public abstract void day(Integer integer);
}
Minister(部长类):
//责任链模式, 部长类继承Person方法并重写day()方法
public class Minister extends Person{
@Override
public void day(Integer integer) {
if (integer > 0 && integer <= 2){
System.out.println("部长批假");
}else {
nextPerson.day(integer);
}
}
}
DeputyManager(副经理类):
//责任链模式, 副经理类继承Person方法并重写day()方法
public class DeputyManager extends Person{
@Override
public void day(Integer integer) {
if (integer > 0 && integer <= 5){
System.out.println("副经理来批假");
}else {
nextPerson.day(integer);
}
}
}
Manager(总经理类):
//责任链模式, 总经理类继承Person方法并重写day()方法
public class Manager extends Person{
@Override
public void day(Integer integer) {
if (integer >= 10){
System.out.println("总经理批假");
}
}
}
现在我们类图如下:
Main(主函数):
//责任链模式, 主函数
public class Main {
public static void main(String[] args) {
//创建三个批假人实例
Person minister = new Minister();
Person deputymanager = new DeputyManager();
Person manager = new Manager();
//部长的上面为副经理
minister.setNextPerson(deputymanager);
//副经理的上面为总经理
deputymanager.setNextPerson(manager);
//放入请假天数
minister.day(10);
}
}
⚪输出结果:
总经理批假
7.责任链模式的优缺点:
责任链模式的优点包括:
- 解耦请求发送者和接收者:请求发送者无需知道具体的接收者,而是将请求发送给第一个处理者,由责任链自动传递。
- 可扩展性:可以动态添加或修改处理者,灵活地调整责任链的顺序和结构。
- 简化对象之间的交互:请求发送者只需要与第一个处理者进行交互,无需了解整个处理流程。
然而,责任链模式也有一些缺点:
- 请求可能无法被处理:如果责任链没有正确配置或者没有终止条件,可能导致请求无法被任何处理者处理。
- 性能影响:由于请求需要在责任链中传递,可能会对性能产生一定影响。
- 可能导致系统难以调试和理解:责任链模式中的请求流程可能比较复杂,当责任链较长时,可能会导致系统难以调试和理解。
因此,在使用责任链模式时,需要根据具体场景和需求权衡其优缺点,并合理设计责任链的结构和顺序。
8.总结:
到这里也已经更了十个设计模式了,希望大家在学习新的设计模式的时候也不要忘记以前学过的设计模式,学会温故而知新,反复揣摩,反复实验,不要把知识仅仅停留在理论阶段,用代码说话,最好是自己能够理解到这个思想,最后希望大家在未来都能成为自己心中想要成为的自己。