理解静态代理模式:通过《帮爸爸买菜》案例解析Java源码

需积分: 1 0 下载量 144 浏览量 更新于2024-10-15 收藏 2KB RAR 举报
资源摘要信息:"java设计模式之静态代理源码及应用场景分析" 一、代理模式概念及作用 代理模式是一种结构型设计模式,其核心思想是通过创建一个代理类来代表原对象进行操作,同时在客户端和目标对象之间起到中介的作用。代理模式的作用主要体现在以下几个方面: 1. 保护目标对象:代理可以在目标对象执行前进行一些必要的操作,例如安全检查、权限验证等,从而保护目标对象免受直接访问。 2. 增强目标对象:代理可以在调用目标对象方法前后增加额外的功能,例如日志记录、性能监控、事务管理等,而无需修改目标对象的代码。 3. 完全替换目标对象:代理可以提供与目标对象相同的方法接口,但内部实现可能完全不同,甚至可以实现某些特殊的控制逻辑,替代原有对象提供服务。 二、静态代理的特点与实现方式 静态代理是指在程序编译之前就已经确定了代理类与被代理类的关系,其特点和实现方式如下: 1. 被代理对象与代理对象需要实现相同的接口或继承相同的父类,这样才能保证代理对象可以替代被代理对象被外界调用。 2. 代理对象聚合了被代理对象,即在代理类中持有被代理对象的引用。 3. 客户端创建代理对象时,需要同时创建被代理对象,并将被代理对象传入到代理对象中。 4. 当客户端调用代理对象的同名方法时,代理对象会在内部调用被代理对象相应的方法,从而实现对被代理对象行为的增强。 三、具体代码示例分析 本次提供的代码示例为"帮爸爸买菜"的场景,下面将详细解析该场景中的静态代理实现: 1. 定义工具人抽象类(公共抽象),其中包含买菜等方法,这个类是被代理对象和代理对象所共同实现的接口或继承的父类。 ```java public abstract class ToolMan { public abstract void buyFood(); } ``` 2. 创建被代理对象"爸爸",继承工具人抽象类,并实现其中的方法。 ```java public class Dad extends ToolMan { @Override public void buyFood() { System.out.println("爸爸去买菜了"); } } ``` 3. 创建代理对象"儿子",同样继承工具人抽象类。在"儿子"类中,聚合了"爸爸"对象,并在调用买菜方法前后增加了一些其他行为(比如检查菜单),实现对"爸爸"的代理。 ```java public class Son extends ToolMan { private ToolMan dad; public Son(ToolMan dad) { this.dad = dad; } @Override public void buyFood() { System.out.println("儿子先检查了一下菜单"); dad.buyFood(); System.out.println("买完菜后儿子回家做饭了"); } } ``` 4. 最后,在客户端代码(妈妈)中,创建"爸爸"和"儿子"的实例,并通过"儿子"的实例来调用买菜方法,完成对实际买菜行为的代理。 ```java public class Mom { public static void main(String[] args) { ToolMan dad = new Dad(); ToolMan son = new Son(dad); son.buyFood(); } } ``` 通过上述代码,我们可以看到"儿子"代理类在调用"爸爸"的买菜方法前后增加了其他操作,体现了代理模式增强被代理对象的能力。 四、应用场景 静态代理在实际开发中有着广泛的应用,如: 1. 数据库连接池中,代理可以用来管理连接的生命周期、提供连接池服务。 2. 日志记录中,可以创建一个代理类在调用方法前后记录日志。 3. 远程调用时,通过代理类来实现远程方法调用,管理通信细节。 4. 在Spring框架中,AOP(面向切面编程)就大量使用了代理模式。 总结,代理模式是软件设计中非常实用的一种模式,尤其是静态代理,在功能增强、资源管理、安全控制等方面有着重要的应用。了解并掌握静态代理模式的实现和应用,对于提高程序的健壮性和灵活性具有重要意义。

java.lang.IllegalArgumentException: Parameter 'directory' is not a directory at org.apache.commons.io.FileUtils.listFiles(FileUtils.java:293) at org.apache.commons.io.FileUtils.listFiles(FileUtils.java:378) at com.bosssoft.hr.train.j2se.util.UtilsDemo.method4(UtilsDemo.java:133) at Test1.testUtilsDemo4(Test1.java:66) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63) at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329) at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293) at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306) at org.junit.runners.ParentRunner.run(ParentRunner.java:413) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)源码如下:public void method4(){ // 获取目录中的所有文件和子目录 Collection<File> files = FileUtils.listFiles(new File("com/bosssoft/hr/train/j2se/util"), new String[]{"*.java"},true); // 遍历文件和子目录 if (files != null) { for (File file : files) { if (file.isDirectory()) { log.info("Directory: " + file.getName()); } else { log.info("File: " + file.getName()); } } } }

2023-07-14 上传