Java设计模式之代理模式(属于结构型模式)

Java设计模式之代理模式

定义:所谓代理模式,就是指客户端并不直接调用需要的对象(目标对象),而是使用代理,通过调用代理来间接的调用需要的对象(目标对象)。

代理的分类:

  1. 静态代理(即:代理类与目标类要实现共同的接口或继承相同的父类。)
  2. 动态代理(即:代理类不需要实现接口,但目标类需要实现接口,利用的是JDK中的API动态的在内存找那个构建代理对象。)

场景描述:小李独自去大城市工作,但人生地不熟,想要租房的话,很难靠自己找到房源,但他可以去找中介,告诉中介他的需求。然后中介替小李去找要出租房屋的房东。

静态代理
  1. 先定义一个接口

    public interface House {
        //出租
        public void renting();
    }
    
  2. 房东实现这个接口

    public class LandLord implements House{
    
        @Override
        public void renting() {
            System.out.println("出租房子!");
        }
    
    }
    
  3. 中介也要实现这个接口

    public class RentProxy implements House{
        private LandLord landLord;
        
        public RentProxy(LandLord landLord) {
            this.landLord = landLord;
        }
        @Override
        public void renting() {
            System.out.println("中介开始寻找房源!");
            //获得了房东的租房信息,通过调用房东的renting()方法
            landLord.renting();
            System.out.println("提供了租房信息给租客!");
        }
    }
    
  4. 测试

    public class Test {
        public static void main(String[] args) {
            //租客想要找房东
            LandLord lL = new LandLord();
            //把这条信息告诉中介,让她帮我们去找
            RentProxy rP = new RentProxy(lL);
            
            rP.renting();
        }
    }
    
  5. 运行结果

Java设计模式之代理模式(属于结构型模式)_第1张图片
上面的第3步我觉得应该这样写比较好理解,否则客户都能直接new 一个landLord了,他也可以直接调用landLord.renting()方法:

public class RentProxy implements House{
       private LandLord landLord;
       
       public RentProxy() {
       	   //让代理对象在初始化时创建被代理的对象(LordLord),
       	   //而不是由客户端(test)去创建	
           this.landLord = new LandLord();
       }
       @Override
       public void renting() {
           System.out.println("中介开始寻找房源!");
           //获得了房东的租房信息,通过调用房东的renting()方法
           landLord.renting();
           System.out.println("提供了租房信息给租客!");
       }
   }

上述第4步更改为:

public class Test {
       public static void main(String[] args) {
           //小李直接去找中介
           RentProxy rP = new RentProxy();
        
           rP.renting();
       }
   }
动态代理

将上面的静态代理改为动态代理并增加了提供房东姓名的功能:

  1. 接口

    public interface House {
        //租房
        public void renting();
      	//姓名
      	public void name();
    }
    
  2. 目标类

    public class LandLord implements House{
    
        @Override
        public void renting() {
            System.out.println("出租房子!");
        }
      	@Override
        public void name() {
            System.out.println("小张");
        }
    
    }
    
  3. 动态代理类

    public class ProxyFactory {
        private Object target;
        public ProxyFactory(Object target) {
            this.target = target;
        }
        //给目标对象生成一个代理对象
        public Object getProxyInstance() {
            /*
             * 参数一:指定当前目标对象使用的类加载器(固定方法)
             * 参数二:目标对象实现的接口类型
             * 参数三:事件处理,执行目标
             */
            
            return Proxy.newProxyInstance(target.getClass().getClassLoader(), 
                    target.getClass().getInterfaces(), 
                    new InvocationHandler() {
                        
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println("使用了动态代理");
                            Object result = method.invoke(target, args);
                            return result;
                        }
                    });   
        }
    }
    
  4. 测试

    public class Test2 {
        public static void main(String[] args) {
            //创建目标对象
            House target = new LandLord();
            
            House proxyInstance = (House)new ProxyFactory(target).getProxyInstance();
            proxyInstance.renting();
          	proxyInstance.name();
        }
    }
    
  5. 运行结果

    Java设计模式之代理模式(属于结构型模式)_第2张图片

​ 使用了动态代理,如果房东需要增加新的功能信息,不需要更改代理类的代码。
同样地,我们也可以在创建代理对象时,用代理对象的构造方法创建目标对象。改写方法跟静态代理中的改写一样,这里省略。。。

你可能感兴趣的:(java)