设计模式(一)代理模式-静态代理聚合方式和集成方式比较

代理模式是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

比如买火车票,你一般不直接去火车站购买,而是到附近的售票点。售票点其实就是代理。

静态代理

要实现的接口

public interface Moveable {
	void move();
}
package com.imooc.proxy;

import java.util.Random;

public class Car implements Moveable {

	@Override
	public void move() {
		//实现开车
		try {
			Thread.sleep(new Random().nextInt(1000));
			System.out.println("汽车行驶中....");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}

 

集成方式

package com.imooc.proxy;

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) + "毫秒!");
	}

	
}

集成方式就是直接继承父类,在super.move()加上自己所代理的内容,比如日志等等

聚合方式

package com.imooc.proxy;

public class Car3 implements Moveable {

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

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

}

聚合不是继承而是实现,把car对象做为构造方法的传递对象。之后再调用car的move方法。

两种方法的对比

在集成方式中如果你要再加入日志的功能怎么办?

只能改原来的代码。如

package com.imooc.proxy;

public class Car2 extends Car {

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

	
}

在最前面加

但是如果是聚合模式呢?

只实现日志功能

package com.imooc.proxy;

public class CarLogProxy implements Moveable {

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

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

}

 只实现计算时间功能

package com.imooc.proxy;

public class CarTimeProxy implements Moveable {

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

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

}
package com.imooc.proxy;

public class Client {

	/**
	 * 测试类
	 */
	public static void main(String[] args) {
		Car car = new Car();
		CarLogProxy clp = new CarLogProxy(car);
		CarTimeProxy ctp = new CarTimeProxy(clp);
		ctp.move();
	}

}

这样看,可能一开始看不懂

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

从后看

ctp.move();进入 ctp中的move

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

但是执行到  m.move(); 会去执行 clp的move

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

执行到 m.move(); 会去执行car中的move

@Override
    public void move() {
        //实现开车
        try {
            Thread.sleep(new Random().nextInt(1000));
            System.out.println("汽车行驶中....");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

之后是clp中的

 System.out.println("日志结束....");

最后是

long endtime = System.currentTimeMillis();
        System.out.println("汽车结束行驶....  汽车行驶时间:"
                + (endtime - starttime) + "毫秒!");

可见!

聚合方式对代码的维护性更高,如果我要换计算时间和打印日志的位置,只要

Car car = new Car();

CarTimeProxy ctp = new CarTimeProxy(car);

CarLogProxy clp = new CarLogProxy( ctp);
        
        clp.move();

把他们调换就可以了

猜你喜欢

转载自blog.csdn.net/xu505928168/article/details/90510758
今日推荐