星光下的学者

导航

 

代理模式:

优点:

  • 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程。
  • 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
  • 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则。

缺点:

  • 类的个数容易过多,增加复杂度
  • 增加了系统的抽象性和理解难度
  • 抽象产品只能生产一种产品,此弊端可使用抽象工厂模式解决。

应用场景:

  • 客户只知道创建产品的工厂名,而不知道具体的产品名。如 TCL 电视工厂、海信电视工厂等。
  • 创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
  • 客户不关心创建产品的细节,只关心产品的品牌

静态代理:

  三要素:一接口(功能方法),一真实,一代理

举例如下:

  接口:Sell——具备功能方法-卖车

  真实类/被代理类:生产汽车的厂家——CarOfFactory

  代理类:汽车代理商——AgentOfCar

接口类:

package com.proxy.dao;

public interface Sell {
    public void sellCar();
}

真实类/被代理类/工厂

package com.proxy.dao;

public class CarOfFactory implements Sell{

    @Override
    public void sellCar() {
        System.out.println("我生产的汽车很棒");
    }
}

代理类/代理商:

package com.proxy.dao;

public class AgentsOfCar implements Sell {

    CarOfFactory cars;

    public AgentsOfCar(CarOfFactory cars) {
        this.cars = cars;
    }

    @Override
    public void sellCar() {
        cars.sellCar();

    }
}

 

开始调用/顾客购车:

package com.proxy.dao;

public class Customers {

    public static void main(String[] args) {

        CarOfFactory BC = new CarOfFactory();
        AgentsOfCar seller = new AgentsOfCar(BC);
        seller.sellCar();
    }
}

结果如下:

 

动态代理:

   区别:

    静态代理类:由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。

    动态代理类:在程序运行时,运用反射机制动态创建而成

动态代理与静态代理在代码上的区别就在代理类的处理上

动态代理代理类:代理类需要继承InvocationHandler接口。重点有二:

  1,需要自己写一个反射方法(如下例子中写的是getInvoke()方法),作用是用于动态生成代理类需传入3个参数

    ①代理实例接口的类加载器  (代理类里的实例类 的加载器,此处是FangDong 的加载器,this可换成FangDong ),动态获取其加载器。

    ②代理实例接口(动态获取FangDong的接口)

    ③InvocationHandler :this指的是InvocationHandler 

  如此便可动态获取代理实例的 类加载器和接口,以及动态代理接口。如此成功生成代理类及代理对象。

  2,重写invoke()方法,前置方法与后置方法的实质,在下面代理类中有解释

package com.rent.room;

public interface Rent {

    public void visit();
    public  void pay();
}

 

package com.rent.room;

public class Owner implements Rent {
    @Override
    public void visit() {
        System.out.println("这房子好漂亮");
    }

    @Override
    public void pay() {
        System.out.println("交钱入住,合作愉快");

    }
}package com.rent.room
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Agent implements InvocationHandler {

    Owner FangDong = new Owner();

    public Agent(Owner fangDong) {
        FangDong = fangDong;
    }

  //method:代理实例上调用的接口方法 objects:包含传入代理实例上方法调用的参数值的对象数组
  //放在invoke()之前的,是前置方法,在invoke()之前执行,
XuanChuan();

  //放在invoke()之后的,是后置方法,在invoke()之后执行,TiCheng();
    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {

        XuanChuan();
        method.invoke(FangDong,objects);
        TiCheng();
        return null;
    }

    private void TiCheng() {
        System.out.println("老板快发工资!");
    }

    private void XuanChuan() {
        System.out.println("快来看房子!");
    }

    public Object getInvoke(){
        return Proxy.newProxyInstance(FangDong.getClass().getClassLoader(),FangDong.getClass().getInterfaces(),this);
    }
}

 

ackage com.rent.room;

public class DynamicProxyTest {
    public static void main(String[] args) {

        Owner LaoWang = new Owner();
        Agent XiaoLi = new Agent(LaoWang);
        //动态获得代理对象
        Rent rr = (Rent)XiaoLi.getInvoke();

        //调用代理对象的方法
        rr.visit();
        System.out.println("=================================");
        rr.pay();
    }
}

 

 

 

posted on 2021-02-05 00:02  我觉得我还能挣扎一下  阅读(69)  评论(0编辑  收藏  举报