动态代理和空对象的结合会产生什么样的火花?动态代理提供了将实现了某一接口或继承自某一超类的子类提供统一的代理机制,从而实现对某一些类功能的增强。而空对象类则是对某一为的NULL类实例实现的行为方式,这样就可以与非NULL统一起来,使对象的使用更方便。
//:typeinfo/util/Null.java
1 package typeinfo.util; 2 3 /** 4 * 空对象接口 5 * @author LYL 6 * 7 */ 8 public interface Null {}
//:typeinfo/util/Operation.java
1 package typeinfo.util; 2 3 public interface Operation { 4 String description(); 5 void command(); 6 }
//:typeinfo/util/Robot.java
1 package typeinfo.util; 2 3 import java.util.List; 4 5 public interface Robot { 6 String name(); 7 String model(); 8 List<Operation> operations(); 9 /*** 10 * 嵌套类,用于对实现了Robot接口的对象进行测试 11 * @author LYL 12 * 13 */ 14 class Test{ 15 public static void test(Robot r){ 16 if(r instanceof Null){ 17 System.out.println("Null Robot"); 18 } 19 System.out.println("Robot name:"+r.name()); 20 System.out.println("Robot model:"+r.model()); 21 System.out.println("Robot operations: "); 22 23 for(Operation operation : r.operations()){ 24 System.out.println(operation.description()); 25 operation.command(); 26 } 27 28 } 29 } 30 }
//:typeinf/SnowRemovalRobot.java
1 /** 2 * 3 */ 4 package typeinfo; 5 6 import java.util.Arrays; 7 import java.util.List; 8 9 import typeinfo.util.Operation; 10 import typeinfo.util.Robot; 11 12 /** 13 * @author LYL 14 * 15 */ 16 public class SnowRemovalRobot implements Robot { 17 private String name; 18 public SnowRemovalRobot(String name){ 19 this.name=name; 20 } 21 /* (non-Javadoc) 22 * @see typeinfo.util.Robot#name() 23 */ 24 @Override 25 public String name() { 26 return this.name; 27 } 28 29 /* (non-Javadoc) 30 * @see typeinfo.util.Robot#model() 31 */ 32 @Override 33 public String model() { 34 return "SnowBot 1"; 35 } 36 37 /* (non-Javadoc) 38 * @see typeinfo.util.Robot#operations() 39 */ 40 @Override 41 public List<Operation> operations() { 42 //通过匿名类,创建机器人的操作列表 43 return Arrays.asList( 44 new Operation(){ 45 @Override 46 public String description() { 47 return name+" can shovel snow"; 48 } 49 @Override 50 public void command() { 51 System.out.println(name+" shoveling snow"); 52 }}, 53 new Operation(){ 54 @Override 55 public String description() { 56 return name+" can chip ice"; 57 } 58 @Override 59 public void command() { 60 System.out.println(name+"chipping ice"); 61 } 62 }, 63 new Operation(){ 64 @Override 65 public String description() { 66 return name+" can clear roof"; 67 } 68 69 @Override 70 public void command() { 71 System.out.println(name+" clearing roof"); 72 } 73 }); 74 } 75 76 public static void main(String args[]){ 77 //测试验证 78 Robot.Test.test(new SnowRemovalRobot("除雪一号")); 79 } 80 }
//:typeinfo/NullRobot.java
1 /** 2 * 3 */ 4 package typeinfo; 5 6 import java.lang.reflect.InvocationHandler; 7 import java.lang.reflect.Method; 8 import java.lang.reflect.Proxy; 9 import java.util.Collections; 10 import java.util.List; 11 12 import typeinfo.util.Robot; 13 import typeinfo.util.Operation; 14 15 import typeinfo.util.Null; 16 17 /*** 18 * NullRobot执行处理器。 19 * @author LYL 20 * 21 */ 22 class NullRobotHandler implements InvocationHandler{ 23 private String nullTypeName; 24 private NRobot proxied=new NRobot(); 25 /** 26 * 创建一 27 * @param type 28 */ 29 public NullRobotHandler(Class<? extends Robot> type){ 30 nullTypeName=type.getSimpleName()+" Null Robot"; 31 } 32 @Override 33 public Object invoke(Object proxy, Method method, Object[] args) 34 throws Throwable { 35 //执行空对象 36 return method.invoke(proxied, args); 37 } 38 /** 39 * 空的Robot类 40 * 内部类,外面不会用到,另一方面是可以很方便地使用外转类的域和方法 41 * @author LYL 42 * 43 */ 44 private class NRobot implements Null,Robot{ 45 public String model(){return nullTypeName;} 46 public String name(){ return nullTypeName;} 47 48 public List<Operation> operations(){ 49 return Collections.emptyList(); 50 } 51 } 52 } 53 54 /** 55 * 56 * @author LYL 57 * 58 */ 59 public class NullRobot { 60 /** 61 * 动态生成指定Robot类的空对象 62 * @param type 63 * @return 64 */ 65 public static Robot newNullRobot(Class<? extends Robot> type){ 66 return (Robot)Proxy.newProxyInstance(Robot.class.getClassLoader(), 67 new Class[]{Null.class,Robot.class}, 68 new NullRobotHandler(type)); 69 } 70 public static void main(String args[]){ 71 //创建一个Robot数组,其中有一个是Null对象 72 Robot[] robots={ 73 new SnowRemovalRobot("除雪二号"), 74 newNullRobot(SnowRemovalRobot.class), 75 }; 76 System.out.println(robots.length); 77 for(Robot robot : robots){ 78 Robot.Test.test(robot); 79 } 80 } 81 }