设计模式学习之代理模式学习(一)

关于设计模式想必学习过Java语言的人都知道吧,当时对其进行深入学习的的人应该不是很多。在我看来设计方面的知识相比于框架应用配置等知识要有意思的多,并且设计模式的对一个程序员的编程思想提升有着很大的帮助。但是设计模式有二十三种,想要全部掌握还是要花点时间的,但如果是只学习常用的几种设计模式还是相对容易的。下面是我学习代理模式的一些心得。

问题引出

     什么是代理模式,为什么要用代理模式。

现在有一个场景模拟:有一个tank类,他实现了Moveable接口,Moveable接口中有一个move方法,tank类重写move方法。那么现在问题来了,我要想要知道坦克move方法的执行时间怎么办。我想马上就有人会想到在move方法执行前获得一下系统时间,然后在执行后再获得一下系统时间,两个时间相减就能得到move方法的执行时间了。没错这种方法的确能解决刚刚的问题,但是同样带来了另外的问题那就是需要修改源码,这是相当不友好的,在没有源码的前提下还不能实现。那要怎么实现才比较合理了,没错就是代理。讲到这我想我不需要说代理的定义是什么了吧,请看下面代码。

Tank类的源代码:

import java.util.Random;

public class Tank implements Moveable{

    @Override
    public void move() {
        System.out.println("moving......");

        try {
            Thread.sleep(new Random().nextInt(10000));
        } catch (InterruptedException e) {

            e.printStackTrace();
        }

    }

}

方法一

定义一个类继承Tank类并且重写Tank的move方法,在move方法中加入上述逻辑。

 * 方法一
 * @author admin
 *
 */
public class Tank2 extends Tank{

    @Override
    public void move() {
        long start = System.currentTimeMillis();
        super.move();
        long end = System.currentTimeMillis();
        System.out.println("time="+(end-start));

    }

}

方法二

定义一个Tank3类实现了Moveable接口,同时Tank3内有个Moveable类型成员变量。重写move方法并在逻辑代码中间调用Tank的move方法。具体代码如下:

/**
 * 方法二
 * @author admin
 *
 */
public class Tank3 implements Moveable{

    private Moveable tank;

    public Tank3(Moveable tank) {
        this.tank = tank;
    }

    @Override
    public void move() {
        long start = System.currentTimeMillis();
        tank.move();
        long end = System.currentTimeMillis();
        System.out.println("time="+(end-start));

    }

}

测试程序:

/**
 * 对于Java代理设计模式的学习
 * 问题:想要知道tank类中的move方法运行的时间
 * 方法一:编写一个类继承tank类,然后在这个类中重写move方法。加上开始时间
 * 和结束时间然后相减。
 * 方法二:编写一个类,里面有一个成员属性是tank类类型,并且实现Moveable
 * 接口。同样重写move方法,并在方法里调用tank中的move方法,并加上相应的
 * 逻辑。(常用,聚合的方式是比继承要好得多,不会出现类爆炸。)
 * @author admin
 *
 */
public class Client {
    public static void main(String[] args) {
        Tank2 tank = new Tank2();
        tank.move();

        Tank3 tank1 = new Tank3(new Tank());
        tank1.move();
    }

}

到此两种实现方法都已给出,那么我们的任务完成了吗,还没有,既然是学习,那么我们就要深入一点。这里给出了两种实现方式,那么哪种实现方式要好了?推荐使用方法二,

我想可能很多人就不服了,为什么啊?

对于上述问题,我们再来模拟一个场景:现在我们完成计算move运行时间的逻辑,那么问题来了,你的老板要你在move方法执行前后加上一个日志操作。使用方法一就是在创建一个类继承Tank类,并重写move方法加上日志逻辑。方法二是创建一个新的类实现Moveable接口,有个成员变量是Moveable类型成员变量。重写move方法并在日志逻辑代码中间调用成员变量的move方法。这里就有人会有疑问了,感觉没区别啊,都是要创建一个新的类。是的,到现在为止表面上是没有区别。那么现在我们老板又给了我们新的要求,他要我们在实现时间计算的同时加上日志,并且是时间执行在前面,日志执行在后面。使用方法一就是再次创建一个新的类完成两次逻辑。好,老板又改主意了这次他要求日志执行在前,时间计算在后,这时你又要创建一个新的类来完成新的逻辑。哇,好麻烦啊,如果,要求的功能更多,就出现类爆炸了。

那么方法二是怎么实现的呢?

假设你现在有了时间逻辑和日志逻辑两个类,现在要完成时间加日志的组合我们只要修改Client程序就行了,不需要再创建新的类了(好舒服)

public class Client {
    public static void main(String[] args) {
        Tank tank1 = new Tank();

        Tank2 tank2 = new Tank2(tank1 );//使用方法二完成的时间计算的类 这里就不给出实现来了

        Tank3 tank3 = new Tank3(tank2 );//使用方法二完成的日志逻辑的类 这里就不给出实现来了
        tank3 .move();
    }

}

应为Tank2和Tank3都实现了Movea接口,所以在创建Tank3的时候我们能把Tank2对象传进去。这样就可以把功能组合起来了。如果在创建Tank2时传Tank3就是先日志后时间。各位看都区别了吧,整整少写 了两个类。所以说哪种方式要好,相信大家已经心知肚明了吧。那么到此我们的问题解决了吧。我想说的是还没有,刚刚解决的只是各个功能之间相互组合的问题,但是我们发现每增加一个新的功能我还是要增加一个代理类,这多麻烦啊,我们能不能只生成一个,或者让程序动态的给我们生成呢?当然可以,请关注我后续的博文

设计模式学习之代理模式学习(二)—动态代理

原文地址:https://www.cnblogs.com/huangliang11/p/9277923.html

时间: 2024-08-07 21:16:34

设计模式学习之代理模式学习(一)的相关文章

设计模式学习--------12.代理模式学习

场景: 福尔摩斯一直想送礼物给花生,但是羞于直接赠送,于是想到让房东太太去帮忙送礼物.编程如何实现呢? 定义: 为其他对象提供一种代理以控制对这个对象的访问. 角色: Proxy:代理对象.有下列功能: 实现与具体的目标对象一样的接口,这样就可以使用代理来代替具体的目标对象. 持有一个具体目标对象的引用,可以在需要时调用具体的目标对象. 可以控制对目标对象的访问,并可以负责创建和删除它. package com.kris.study; public class Proxy implements

设计模式学习之代理模式(Proxy)

一.代理模式的初衷 不想让客户端直接访问具体实现接口,客户端不应该直接访问具体实现,一般会涉及到以下四个对象 业务接口:定义客户端访问的接口,是实现类和代理类都需要实现的 实现类:实现了业务接口,真正的实现是在这里 代理类:同样实现了业务接口,一般都会关联一个实现类的实例,由它来调用实现类 客户端:顾名思义,使用者,与代理类打交道,甚至都不知道具体实现类的存在. 二.代理模式设计图 三.代理模式的简单实现代码 BizInterface.java package com.lipan.designp

设计模式学习之--代理模式

代理模式,顾名思义,意思和我们日常生活中的代理差不多,举一个最简单的例子,我们知道,我们的火车站购票有很多的火车票代售点,这个火车票代售点可以代替我们的火车站的售票处让我们买票,当然,代售点相比于火车站售票点又可以提供电话订票和提前预定,这样,火车票代售点就基本可以实现火车站售票点的基本功能,同时还可以提供相对于火车站售票点其他的功能.那么,我们的设计模式中的代理模式就是这个意思. 在我们的程序中,许多类的方法中我们总需要一些额外的共同的功能,比如日志和性能优化操作,如果在所有 这些类中都加入这

java代理模式学习

Java动态代理模式 1. 代理:一个角色代表别一个角色来完成某些特定的功能. 比如:生产商,中间商,客户这三者这间的关系 客户买产品并不直接与生产商打交道,也不用知道产品是如何产生的,客户只与中间商打交道,而中间商就可以对产品进行一些包装,提供一些售后的服务. 代理模式有三个角色: 1. 抽象主题角色 2. 代理主题角色 3. 实际被代理角色 其它类通过访问代理主题角色来访问实际被代理角色. 2. 下面我们来个一个静态代理的实现. 我以一个坦克为例. 抽象主题角色:Moveable Java代

设计模式之动态代理模式

设计模式之动态代理模式 代理模式: Provide a surrogate or placeholder for another object to controlaccess to it(为其他对象提供一种代理以控制对这个对象的访问).使用代理模式创建代理对象,让代理对象控制目标对象的访问(目标对象可以是远程的对象.创建开销 大的对象或需要安全控制的对象),并且可以在不改变目标对象的情况下添加一些额外的功能. 代理模式相关内容详见本人之前文章:http://www.cnblogs.com/zh

设计模式(2)_代理模式 ————— 控制对象访问

设计模式(2)_代理模式 ----- 控制对象访问 一.动机 需求 现在有这样一个需求:有一个出版社,该出版社有一个工厂,专门用来生产制造图书,该工厂里有很多台生产制造图书的机器.每个机器有自己的位置坐标,用 int表示,机器的状态,{正在工作,暂停,故障},已经印刷了多少页图书.在出版社 在工厂 厂长的电脑屏幕上,可以随时打印出任何一台机器的报告信息(report infomation). 下来 我们用代码实现这个需求: PrinterMachine.java package com.crg;

【设计模式】Proxy 代理模式

[设计模式]Proxy 代理模式 1.代理模式的定义 代理模式:为另一个对象提供一个替身或占位符以控制对这个对象的访问. 2.静态代理 首先我们通过案例来引出为什么我们需要使用代理模式. 我们给出如下一个接口Moveable 和该接口的实现类: Moveable.java package com.proxy; public interface Moveable { void move(); } Tank.java package com.proxy; import java.util.Rando

设计模式学习之代理模式

代理模式,可以分为两种,一种是静态代理,一种是动态代理. 两种代理从虚拟机加载类的角度来讲,本质上都是一样的,都是在原有类的行为基础上,加入一些多出的行为,甚至完全替换原有的行为.在我们平时写代码的过程中,代理模式可以说是随处可见,所以,本篇博客就将给大家介绍代理模式. 基本概念 代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口. UML图 Subject:抽

设计模式之代理模式学习

代理模式是一种结构型模式,通常源于下边的情况:人们对于复杂的软件系统经常有一种处理手法,即添加一个间接层,从而对系统获得一种更为灵活,满足特定须要的解决方式.比例如以下图中,B有安全控制或者是缓存控制.B中存在A根本不须要知道的控制方式.A直接使用B,结构上复杂,实现也不方便.A直接使用B的方式,控制不够灵活,可能要用到A根本不知道的方式.添加一个间接层,从而对系统获得更为灵活.满足特定须要的解决方式.假如A须要调用B三次,B比方处理远程的另外一个进程,C做为B的代理人.A和C处于一个地址空间,