美文网首页
设计模式之代理模式一

设计模式之代理模式一

作者: 小白小白啦 | 来源:发表于2018-08-05 14:43 被阅读9次

本文主要参考慕课网视频学习,在此记录一下,个人感觉讲的非常棒。随着对spring框架的了解,代理模式在其中发乎了很大作用,要想更好的理解spring的核心之一AOP需要对代理模式有一些了解。
代理模式我个人理解就是通过一个对象A去访问另外一个对象B,而不是直接去访问B,为什么不直接访问B呢?因为有时候我们需要在访问B之前做一些代码逻辑判断,比如spring框架中的面向切面编程,我需要判断用户是否登录才能访问a,b,c,d这四个函数,就可以通过切面实现,并且没有破坏a,b,c,d函数的代码,只需要在每一个函数上面加一个注解或者通过正则表达式进行判断。

静态代理: 代理和被代理对象在代理之前是确定的。他们都实现相同的接口或者继承相同的抽象类

静态代理

以汽车行驶,记录汽车行驶时间为例子进行讲解,首先创建一个Movable接口。

public interface Moveable {
    void move();
}

创建一个Car实现类

import java.util.Random;

/**
 * Create by fengguofei
 * Date: 2018/8/5
 * Time: 13:39
 */
public class Car implements Moveable{

    @Override
    public void move() {
        long starttime = System.currentTimeMillis();
        System.out.println("汽车开始行驶。。。");
        //实现开车
        try {
            Thread.sleep(new Random().nextInt(1000));
            System.out.println("汽车行驶中。。。");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long endtime = System.currentTimeMillis();
        System.out.println("汽车结束行驶。。。 汽车行驶时间:" + (endtime - starttime) + "毫秒!");
    }
}

创建一个测试Client类

public class Client {
    public static void main(String[] args) {
        Car car = new Car();
        car.move();
    }
}

输出

汽车开始行驶。。。
汽车行驶中。。。
汽车结束行驶。。。 汽车行驶时间:621毫秒!

可以看到实现了汽车行驶时间的记录
通过继承实现代理
创建一个Car2继承Car,然后删除Car里面有关计时的代码,放到Car2里面。
修改Car类代码

public class Car implements Moveable{

    @Override
    public void move() {
//        long starttime = System.currentTimeMillis();
//        System.out.println("汽车开始行驶。。。");
        //实现开车
        try {
            Thread.sleep(new Random().nextInt(1000));
            System.out.println("汽车行驶中。。。");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
//        long endtime = System.currentTimeMillis();
//        System.out.println("汽车结束行驶。。。 汽车行驶时间:" + (endtime - starttime) + "毫秒!");
    }
}

创建Car2

public class Car2 extends Car{
    @Override
    public void move(){
        long starttime = System.currentTimeMillis();
        System.out.println("汽车开始行驶。。。");
        super.move();
        long endtime = System.currentTimeMillis();
        System.out.println("汽车结束行驶。。。 汽车行驶时间:" + (endtime - starttime) + "毫秒!");
    }
}

修改Client类代码

public class Client {
    public static void main(String[] args) {
//        Car car = new Car();
//        car.move();

        Moveable m = new Car2();
        m.move();
    }
}

输出

汽车开始行驶。。。
汽车行驶中。。。
汽车结束行驶。。。 汽车行驶时间:906毫秒!

通过Car2里面的super.move实现了对Car的代理。
使用聚合方式
创建Car3

public class Car3 implements Moveable {

    private Car car;

    public Car3(Car car) {
        super();
        this.car = car;
    }

    @Override
    public void move() {
        long starttime = System.currentTimeMillis();
        System.out.println("汽车开始行驶。。。");
        car.move();
        long endtime = System.currentTimeMillis();
        System.out.println("汽车结束行驶。。。 汽车行驶时间:" + (endtime - starttime) + "毫秒!");;
    }
}

修改Client类代码

public class Client {

    public static void main(String[] args) {
//        Car car = new Car();
//        car.move();

          //使用集成方式
//        Moveable m = new Car2();
//        m.move();

        //使用聚合方式实现
        Car car = new Car();
        Moveable m = new Car3(car);
        m.move();
    }
}

输出

汽车开始行驶。。。
汽车行驶中。。。
汽车结束行驶。。。 汽车行驶时间:652毫秒!

聚合方式我感觉就是两个类实现同一个接口,Car类实现move功能,然后通过构造函数把Car类注入到Car3中,在调用Car类move时做一些处理,从而实现了代理功能。

继承方式和聚合方式那个好一点呢?答案是聚合方式

功能叠加.png
如果我们需要在Move上实现时间处理、权限、日志等功能。比如需要实现先输出时间,再输出日志就需要创建一个Car4继承Car,如果我想先输出日志,再输出时间呢?就需要在创建一个Car5继承Car,只是顺序颠倒一下,就需要在创建一个,如果功能多的话,就需要创建很多类,太麻烦了。使用聚合就不会有这种问题出现。
直接上代码,看了就懂了。
创建一个时间代理类CarTimeProxy
public class CarTimeProxy implements Moveable {
    private Moveable m;

    public CarTimeProxy(Moveable m) {
        super();
        this.m = m;
    }

    @Override
    public void move() {
        long starttime = System.currentTimeMillis();
        System.out.println("汽车开始行驶。。。");
        m.move();
        long endtime = System.currentTimeMillis();
        System.out.println("汽车结束行驶。。。 汽车行驶时间:" + (endtime - starttime) + "毫秒!");;
    }
}

创建一个日志代理类CarLogProxy

public class CarLogProxy implements Moveable {
    private Moveable m;

    public CarLogProxy(Moveable m) {
        super();
        this.m = m;
    }

    @Override
    public void move() {
        System.out.println("日志开始。。。");
        m.move();
        System.out.println("日志结束。。。");;
    }
}

修改Client代码

public class Client {

    public static void main(String[] args) {
//        Car car = new Car();
//        car.move();

          //使用集成方式
//        Moveable m = new Car2();
//        m.move();

        //使用聚合方式实现
//        Car car = new Car();
//        Moveable m = new Car3(car);
//        m.move();

        Car car = new Car();
        CarTimeProxy ctp = new CarTimeProxy(car);
        CarLogProxy clp = new CarLogProxy(ctp);
        clp.move();
    }
}

输出

日志开始。。。
汽车开始行驶。。。
汽车行驶中。。。
汽车结束行驶。。。 汽车行驶时间:843毫秒!
日志结束。。。

上面是先输出日志,再输出时间。如果我想先输出时间,再输出日志呢?
只需要修改一下顺序即可

   Car car = new Car();
   CarLogProxy clp = new CarLogProxy(car);
   CarTimeProxy ctp = new CarTimeProxy(clp);
   ctp.move();

输出

汽车开始行驶。。。
日志开始。。。
汽车行驶中。。。
日志结束。。。
汽车结束行驶。。。 汽车行驶时间:510毫秒!

在后面一篇文章进行JDK动态代理和cglib动态代理的讲解。
设计模式之代理模式二

相关文章

  • 设计模式之代理模式

    设计模式之代理模式 10分钟看懂动态代理设计模式(升级篇)-对这篇动态代理模式的思路整理 仿JDK实现动态代理逻辑...

  • 代理模式

    设计模式之代理模式 什么是代理模式? 指的事代理对象为其他对象提供代理以控制对被...

  • 设计模式之代理模式2

    设计模式之代理模式运用 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对...

  • Java设计模式之代理模式

    Java设计模式之代理模式 代理模式 静态代理 动态代理 为什么需要代理 通过代理,我们能够不用知道委托人是谁,而...

  • Java代理模式之JDK动态代理

    了解什么是动态代理模式,可参考Java设计模式之代理模式 简介 JDK动态代理是java.lang.reflect...

  • 设计模式之代理模式

    设计模式之代理模式 简介 代理模式是结构型设计模式。 当无法或不想直接访问某个对象或访问某个对象存在困难时可以通过...

  • 设计模式之代理模式

    设计模式之代理模式 1.代理模式的定义 为其他对象提供一种代理以控制对这个对象的访问. 2.代理模式的使用场景 当...

  • 设计模式之代理模式

    title: 设计模式之代理模式date: 2018-08-15 20:25:42tags: 设计模式 笔记 Ja...

  • java设计模式之代理模式(静态代理)

      今天给大家分享的是java设计模式之代理模式中的静态代理模式,动态代理模式将在后面文章中给出。如有不足,敬请指...

  • Android 代理模式

    Android 设计模式系列文章 Android 23种设计模式 前言 代理模式可能是我们平时开发中最常见的模式之...

网友评论

      本文标题:设计模式之代理模式一

      本文链接:https://www.haomeiwen.com/subject/parbvftx.html