需求:
定义一个UserService接口
package com.njwbhz.march.week2.part0309.userService;
public interface UserService {
void login();
void regist();
}
定义一个UserServiceImpl实现类
package com.njwbhz.march.week2.part0309.userService;
public class UserServiceImpl implements UserService {
@Override
public void login() {
// long startTime = System.currentTimeMillis();
try {
//模拟延时,表示登录需要花费的时间
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行用户登录过程");
// long endTime = System.currentTimeMillis();
// System.out.println("消耗了" + (endTime - startTime) + "毫秒");
}
@Override
public void regist() {
// long startTime = System.currentTimeMillis();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行用户注册过程");
// long endTime = System.currentTimeMillis();
// System.out.println("消耗了" + (endTime - startTime) + "毫秒");
}
}
正常使用
package com.njwbhz.march.week2.part0309.userService;
public class TestUserService {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
userService.login();
// UserService userServiceProxy = new UserServiceProxy(userService);
// userServiceProxy.login();
}
}
现在要给regist和login入口添加监控代码
package com.njwbhz.march.week2.part0309.userService;
public class UserServiceImpl implements UserService {
@Override
public void login() {
long startTime = System.currentTimeMillis();
try {
//模拟延时,表示登录需要花费的时间
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行用户登录过程");
long endTime = System.currentTimeMillis();
System.out.println("消耗了" + (endTime - startTime) + "毫秒");
}
@Override
public void regist() {
long startTime = System.currentTimeMillis();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行用户注册过程");
long endTime = System.currentTimeMillis();
System.out.println("消耗了" + (endTime - startTime) + "毫秒");
}
}
测试效果
经过一段时间的监控,发现系统稳定了,监控代码就不需要了,暂时先注释掉。
package com.njwbhz.march.week2.part0309.userService;
public class UserServiceImpl implements UserService {
@Override
public void login() {
// long startTime = System.currentTimeMillis();
try {
//模拟延时,表示登录需要花费的时间
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行用户登录过程");
// long endTime = System.currentTimeMillis();
// System.out.println("消耗了" + (endTime - startTime) + "毫秒");
}
@Override
public void regist() {
// long startTime = System.currentTimeMillis();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行用户注册过程");
// long endTime = System.currentTimeMillis();
// System.out.println("消耗了" + (endTime - startTime) + "毫秒");
}
}
再经过一段时间,又发现系统慢了,然后又把监控代码放开---去注释
如果业务类非常之多
任务量非常大,修改所有业务类中的代码,维护监控代码--àclass文件发生变化-à停服务器--à更新服务器代码-à重新启动服务器--à测试。。。。。。。。 麻烦
造成麻烦的根本原因:
如何解决重复,现有的方案
(1)封装
数据的封装 + 功能性封装
工具类{
获取开始时间的方法()
获取结束时间的方法(){ 完成差值的计算 }
}
UserServiceImpl{
login(){
获取开始时间的方法()
…….
获取结束时间的方法(){ 完成差值的计算 }
}
regist(){
获取开始时间的方法()
…….
获取结束时间的方法(){ 完成差值的计算 }
}
}
治标不治本。
(2)继承
正确的使用继承场景:
a.is a的关系
b.多个类中公共的属性和方法,可以提取到父类中
此处并不满足继承的条件
(3)多态
建立在继承的基础,
别人都遇到了这样的问题----总结统一的处理模式----代理设计模式。
代理模式:
专门解决:方法内容的重复代码块问题或方法内部核心代码与非核心代码高度耦合的问题。
什么是代理设计模式:代理对象对被代理对象功能的增强。
现实生活中的代理:
律师
房屋中介
卖家:可以自己卖房
中介:可以帮助卖家买房
找买家,带买家看房,贷款,签协议。。。。。。。
中介就是一个代理者角色
卖家委托中介,他是一个被代理者角色
中介可以帮助卖家做更多专业的事情
作为一个买家而言,最终从卖家和中介处买房,都能买到房,认为效果是一样的。---要求代理对象和被代理对象实现同一接口。
代理的具体实现
(1)统一抽取一个接口 代理对象和被代理对象之间的统一接口
package com.njwbhz.march.week2.part0309.sellHouse;
public interface SellAble {
void sell();
}
(2)被代理者 ---卖家
package com.njwbhz.march.week2.part0309.sellHouse;
public class Seller implements SellAble {
@Override
public void sell() {
System.out.println("卖家自己卖房子");
}
}
(3)代理类 ---中介
package com.njwbhz.march.week2.part0309.sellHouse;
public class Agent implements SellAble {
//持有一个被代理对象的引用
private SellAble target;//代理的目标者
public Agent(SellAble target) {
this.target = target;
}
@Override
public void sell() {
sellBefore();//增强的行为
//真正的卖方是由卖家决定的
target.sell();
sellAfter();//增强的行为
}
private void sellBefore() {
System.out.println("中介带客户去看房子");
System.out.println("约卖家一起撮合房价");
}
private void sellAfter() {
System.out.println("中介帮忙做贷款,签协议······");
}
}
(4)整个的买房过程
package com.njwbhz.march.week2.part0309.sellHouse;
public class TestSellable {
public static void main(String[] args) {
SellAble seller = new Seller();
//卖家自己卖房子
// seller.sell();
SellAble agent = new Agent(seller);
agent.sell();
}
}
使用代理优化性能监控代码
package com.njwbhz.march.week2.part0309.userService;
public class UserServiceProxy implements UserService {
//持有被代理引用
private UserService target;
public UserServiceProxy(UserService target) {
this.target = target;
}
@Override
public void login() {
long startTime = getCurrentTime();
//由具体的被代理对象完成
target.login();
long endTime = getCurrentTime();
print(startTime , endTime , "UserServiceImpl" , "login");
}
@Override
public void regist() {
long startTime = getCurrentTime();
//由具体的被代理对象完成
target.regist();
long endTime = getCurrentTime();
print(startTime , endTime , "UserServiceImpl" , "regist");
}
private long getCurrentTime () {
return System.currentTimeMillis();
}
private void print (long startTime , long endTime , String className , String methodName) {
System.out.println(className + "中的" + methodName + "方法用了" + (endTime - startTime)/1000 + "秒");
}
}
package com.njwbhz.march.week2.part0309.userService;
public class UserServiceImpl implements UserService {
@Override
public void login() {
// long startTime = System.currentTimeMillis();
try {
//模拟延时,表示登录需要花费的时间
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行用户登录过程");
// long endTime = System.currentTimeMillis();
// System.out.println("消耗了" + (endTime - startTime) + "毫秒");
}
@Override
public void regist() {
// long startTime = System.currentTimeMillis();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行用户注册过程");
// long endTime = System.currentTimeMillis();
// System.out.println("消耗了" + (endTime - startTime) + "毫秒");
}
}
把原来的UserServiceImpl中监控代码删除掉。
如果不需要监控
package com.njwbhz.march.week2.part0309.userService;
public class TestUserService {
public static void main(String[] args) {
//不需要监控
UserService userService = new UserServiceImpl();
userService.login();
//需要监控
UserService userServiceProxy = new UserServiceProxy(userService);
userServiceProxy.login();
}
}
优缺点
优点:是一种代码重复的解决手段或解耦合的手段。
缺点:为了做代理,额外的新增了类,导致系统中类的泛滥。
新增代理类的方式称为静态代理。
将来会使用动态代理 ----不新增类,程序运行的时候自动创建代理类对象。



