首先实现一个学生考试的场景。
package com.skymr.pattern.proxypat;
public interface IStudent {
/**
* 考试
*/
public void examine();
}
package com.skymr.pattern.proxypat;
import java.util.Random;
public class StudentA implements IStudent{
@Override
public void examine() {
System.out.println("学生正在考试");
try {
Thread.sleep((new Random().nextInt(5) + 2) * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
问怎样计算examine方法耗时多少?可以在examine方法内部前后使用System.currentTimeMillis()计算时间差获得。但如果不能修改StudentA的代码呢(StudentA在jar中).
两种方式:
1.继承后重写方法
package com.skymr.pattern.proxypat;
/**
* 以继承方式实现代理功能(计算方法耗时)
* @author skymr
*
*/
public class StudentC extends StudentA{
@Override
public void examine() {
long start = System.currentTimeMillis();
super.examine();
long end = System.currentTimeMillis();
System.out.println("耗时:"+(end-start));
}
}
2.聚合
package com.skymr.pattern.proxypat;
/**
* 以聚合方式实现代理功能(计算方法耗时)
*
* @author skymr
*
*/
public class StudentB implements IStudent{
private IStudent student;
public StudentB(IStudent student){
this.student = student;
}
@Override
public void examine() {
long start = System.currentTimeMillis();
student.examine();
long end = System.currentTimeMillis();
System.out.println("耗时:"+(end-start));
}
}
那哪种方式好呢?聚合方式好,继承方式不灵活
假设我们这样的代理功能:计算耗时(A)、日志(B),权限检查(C),为此聚合与继承分别实现类为A1,A2 ,B1 B2, C1 C2,但现在需要将A功能与B功能组合起来,比如先A再B,聚合方式它不需要再写新的类了,而继承方式呢,却必须添加新类;它们的差别其实在于继承方式不能动态修改继承自谁。