易学设计模式看书笔记(7) - 代理模式

代理模式

1.系统日志记录的例子:给系统中的业务逻辑加上日志

(1):最简单直接的做法

public class Test
{
 private Logger logger = Loger.getLogger(this.getClass().getName());

 public void doLgic(String name){

  logger.log(name + "开始业务逻辑处理...");

  //业务逻辑处理相关程序
  System.out.println("业务逻辑处理相关程序");

  logger.log(name + "业务逻辑处理结束...");
 }
}
有其他的类的业务逻辑也需要记录日志:
public class Test1
{
 private Logger logger = Loger.getLogger(this.getClass().getName());

 public void doLgic(String name){

  logger.log(name + "开始业务逻辑处理...");

  //业务逻辑处理相关程序
  System.out.println("业务逻辑处理相关程序");

  logger.log(name + "业务逻辑处理结束...");
 }
}

这两个类为了记录日志,在处理业务逻辑的代码中加入了有关日志处理的方法,

这些方法加入的模式很相似,混淆了类的单一职责,有什么办法解决这个问题?

(2):静态代理

定义一个有业务逻辑的接口类:
public interface Test
{
 public void doLogic(String name);
}
具体的逻辑处理类:
public class TestImpl implements Test
{
 public void doLogic(){
  System.out.println("业务逻辑处理");
 }
}

日志代理类:
public class TestProxy implements Test
{
 private Logger logger = Loger.getLogger(this.getClass().getName());
 private Test test;
 public TestProxy(Test test){
  this.test = test;
 }

 public void doLogic(String name){
  logger.log("开始业务逻辑处理...");
  //业务逻辑处理
  test.doLogic(name);
  logger.log("业务逻辑处理结束...");
 }
}

调用代理类,实现日志输出:

public class Client
{
 public static void main(String[] args){
  TestProxy testProxy = new TestProxy(new TestImpl());
  testProxy.doLogic("小四");
 }
}

通过业务逻辑的代理类来调用具体的业务逻辑,同样实现了日志的记录,

而且把日志的记录和业务逻辑进行了分离,这是静态代理。

存在问题就是:每个方法都要有一个代理类,如果系统中的每个类都要日志记录,

那代理类的数量很多。解决办法就是动态代理了。

(3):动态代理

基于JDK的动态代理:

public LogProxy implements InvocationHandler
{
 private Logger logger = Loger.getLogger(this.getClass().getName());
 private Object delegate;//代理对象

 public Object bind(Object delegate){
  this.delegate = delegate;
  return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
   delegate.getClass().getInterfaces(),this);
 }

 public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{

  Object result = null;
  try{
   logger.log("开始业务逻辑处理...");
   //业务逻辑处理
   result = method.invoke(delegate,args);
   logger.log("业务逻辑处理结束...");
  }catch(Exception e){
   logger.log(e.toString());
  }

  return result;
 }
}

public class  Client
{
 public static void main(String[] args)
 {
  LogProxy logProxy = new LogProxy();
  Test test = (Test)logProxy.bind(new TestImpl());
  test.doLogin("小五");
 }
}

JDK的动态代理只能针对接口代理,要实现对类的动态代理可以用cglib的动态代理或者其它类库的。

一般推荐的是面向接口编程。

2.动态代理模式简介:

【定义】

代理模式就是给一个对象提供一个代理对象,由这个代理对象控制对

原对象的引用,使代理对象在原对象和客户端之间起到一个中介的作用。

【原理】

代理模式主要由三部分组成:

抽象目标类,具体目标类 和代理类。

【使用时机】

当系统需要对某个对象进行额外的控制时。

易学设计模式看书笔记(7) - 代理模式

时间: 2024-07-28 20:55:40

易学设计模式看书笔记(7) - 代理模式的相关文章

易学设计模式看书笔记(6) - 创建者模式

四.创建者模式 1.摩托车组装系统 觉得这些例子挺适合入门的,容易理解, 看了之后大概是个什么样子的就有了印象. 摩托车 = 车架 + 车轮 + 轮胎 + 发动机. 首先设计摩托车类以及各零件类: 摩托车类: public interface Motorcycle { void build(); } public class Motorcycle1 implements Motorcycle { void build(){ Sysout.out.println("组装摩托车开始..."

易学设计模式看书笔记(2) - 简单工厂模式

本文摘自易学设计模式一书 一.简单工厂模式 1.动物管理系统的例子 public interface Animal{ public void eat(); } public class Tiger implements Animal { public void eat(){ sysout.out.println("老虎会吃"); }; public void run(){ sysout.out.println("老虎会跑"); }; } public class D

易学设计模式看书笔记(4) - 抽象工厂模式

 本文内容来自书上,不懂设计模式,只求混个眼熟. 三.抽象工厂模式 1.动物管理系统的例子 public interface Animal{ public void eat(); } public class Tiger implements Animal { public void eat(){ sysout.out.println("老虎会吃"); }; public void run(){ sysout.out.println("老虎会跑"); }; } pu

易学设计模式看书笔记(3) - 工厂方法模式

二.工厂方法模式 1.动物管理系统的例子 首先,抽象的动物类和具体的动物实现类: public interface Animal{ public void eat(); } public class Tiger implements Animal { public void eat(){ sysout.out.println("老虎会吃"); }; public void run(){ sysout.out.println("老虎会跑"); }; } public

易学设计模式看书笔记(1) - 设计模式的分类

1 创建型模式 单独对对象的创建进行研究,高效的创建对象就是创建型模式讨论的问题.创建型设计模式有6种: 简单工厂模式(simple factory): 工厂方法模式(factory method): 抽象工厂模式(abstract factory): 创建者模式(Builder): 原型模式(Prototype): 单例模式(Singleton). 2 结构型模式 在解决了对象的创建问题之后,对象的组成以及对象之间的依赖关系就成了关注的焦点,因为如何设计对象之间的结构.继承和依赖关系会影响到后

设计模式看书笔记(5) - 三种工厂模式比较

先看三种工厂模式部分主要代码(完整代码在前三篇博客): 简单工厂模式: public class SampleFactory { public static Animal createAnimal(String animalName){ if("Tiger".equals(animalName))){ return new Triger(); }else if("Dolphin".equals(animalName)){ return new Dolphin();

设计模式总结篇系列:代理模式(Proxy)

时代在发展,我们发现,现在不少明星都开始进行微访谈之类的,有越来越多的参与捐赠等.新的一天开始了,首先看下新的一天的日程安排: 1 interface Schedule{ 2 3 public void weiTalk(); 4 5 public void donation(); 6 7 } Schedule接口定义了今天的形成安排,主要包括微访谈和捐款.那么看一下实现此接口的明星类定义: 1 class Star implements Schedule { 2 3 @Override 4 pu

设计模式之第16章-代理模式(Java实现)

设计模式之第16章-代理模式(Java实现) “现在朋友圈真是太让人蛋疼了啊.”“怎么说?”“一堆代理,各种卖东西的,看着好烦人.”“哎,删了呗.”“都是朋友,哪里好意思删啊.”“这倒也是...哎,迫于生计,没办法咯.还好我不玩.”“对了,你不就是代理的鼻祖么,身为代理模式,你作何感想.”“以代理之道还治代理之身啊.” 代理模式之自我介绍 最近出场率超级高,哦不,一直以来出场率都挺高的说的大名鼎鼎的模式,就是我-代理模式是也.有关我的定义如下:Provide a surrogate or pla

《Head First 设计模式》学习笔记——适配器模式 + 外观模式

在ADO.NET中,对于我们从数据库中取出的数据都要放到一个DataSet中,不管你是Access的数据库,还是SQL的数据库,或者是Oracle的数据库都要放到DataSet中..NET中并没有提供如:SqlDataSet.OleDbDataSet.OracleDataSet等,它只提供了一种DataSet就是用SqlDataAdapte等去填充数据:为什么这一个DataSet能存放不同的数据呢?就是有这些适配器来适配.----题记 设计模式 适配器模式:将一个类的接口,转换成客户期待的另一个