设计模式(就) : 结构型模式--代理模式

代理模式是比较常见的一种模式,我们平常接触的比较多,比如正向代理和反向代理。

正向代理的代理服务器是和客户端的网络在一起,由代理服务器转发请求和接受结果,比如有的公司的服务器,会过滤掉对外部网络的访问请求;反向代理的代理服务器接受来自客户端的请求,决定讲请求转发给哪个内部服务器进行处理,反向代理的服务器也可能会过滤掉一些不安全的请求,或者不符合验证条件的请求。

所以代理模式的主要目的是控制对象的访问。

《java与模式》中代理模式有两种实现方式:一种是静态的实现方式,一种是利用jdk的动态的实现方式。

1. 静态的实现方式

示意性代码:

?





1

2

3

4

5

6

7

package
com.javadesignpattern.Proxy.Static;

public abstract class Subject {

    

    abstract
public void request();

}

  


package com.javadesignpattern.Proxy.Static;

public class RealSubject extends Subject{

@Override
public void request() {
// TODO Auto-generated method stub
System.out.println(RealSubject.class + ": request method");
}

}


package com.javadesignpattern.Proxy.Static;

public class ProxySubject extends Subject {

private Subject subject;

public ProxySubject(Subject subject) {
this.subject = subject;
}

public ProxySubject() {

}

public void preRequest() {
System.out.println(ProxySubject.class + ": ProxySubject function");
}

public void postRequest() {
System.out.println(ProxySubject.class + ": postRequest function");
}

@Override
public void request() {
// TODO Auto-generated method stub
preRequest();
if(subject == null){
subject = new RealSubject();
}
subject.request();
postRequest();
}

}


package com.javadesignpattern.Proxy.Static;

public class Client {

public static void main(String[] args){
Subject subject = new ProxySubject();
subject.request();

System.out.println("************************");

Subject subject2 = new ProxySubject(new RealSubject());
subject2.request();
}

}

2. jdk动态代理

实现jdk的动态代理分成几步:

1. 代理类实现InvocationHandler接口,实现invoke方法。

2. Proxy类的newProxyInstance方法,传递三个参数,classloader,
interface和InvocationHandler对象实例。

示意性代码:


package com.javadesignpattern.Proxy.Dynamic;

public interface UserManager {

public void addUser(String userId, String userName);
public void delUser(String userId);
public String findUser(String userId, String userName);
public void modifyUser(String userId, String userName);

}


package com.javadesignpattern.Proxy.Dynamic;

public class UserManagerImpl implements UserManager{

public void addUser(String userId, String userName) {
// TODO Auto-generated method stub
System.out.println("UserManagerImpl.addUser()userId-->"+userId);
}

public void delUser(String userId) {
// TODO Auto-generated method stub
System.out.println("UserManagerImpl.delUser()userId-->"+userId);
}

public String findUser(String userId, String userName) {
// TODO Auto-generated method stub
System.out.println("UserManagerImpl.findUser()userId-->"+userId);
return userName ;
}

public void modifyUser(String userId, String userName) {
// TODO Auto-generated method stub
System.out.println("UserManagerImpl.modifyUser()userId-->"+userId);
}

}


package com.javadesignpattern.Proxy.Dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.text.SimpleDateFormat;

public class LoggerHandler implements InvocationHandler{

Object target;

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("begin time:" +getTime());
try{
Object result = method.invoke(target, args);
System.out.println("success time:" +getTime());
}catch(Exception e){
e.printStackTrace();
System.out.println("failed time:" +getTime());
}
return null;
}

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

public String getTime(){
SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateTime = tempDate.format(new java.util.Date());
return dateTime;
}

}


package com.javadesignpattern.Proxy.Dynamic;

public class Client {

public static void main(String[] args){
LoggerHandler loggerHandle = new LoggerHandler();
UserManager userManager = (UserManager)loggerHandle.newInstance(new UserManagerImpl());
userManager.addUser("001", "Christy");
}

}

可以看到jdk的动态代理被代理的对象必须实现接口。好忧桑啊。解决的办法是我们想到spring的cglib实现的动态代理,cglib是针对类(实际上是继承子真实主题)的代理,但是不能代理final的(final的不能继承嘛~)。

---------动态代理的优点:

接口中声明的多有方法都被转移到调用处理器中一个集中的方法中进行处理(invocationhandle:invoke),这样接口数量比较多的时候,我们就可以灵活处理。这是优于静态代理的地方。

时间: 2024-09-30 06:28:17

设计模式(就) : 结构型模式--代理模式的相关文章

"围观"设计模式(12)--结构型之代理模式(Proxy Pattern)

维基百科 代理模式(英语:Proxy Pattern)是程序设计中的一种设计模式. 所谓的代理者是指一个类可以作为其它东西的接口.代理者可以作任何东西的接口:网络连接.内存中的大对象.文件或其它昂贵或无法复制的资源.----WIKIPEDIA 个人理解 代理模式就是找另外的一个对象作为代理去为你实施请求,代理模式分为两种,一种是静态代理模式,另外一种是动态代理模式,静态代理模式是代理类为其创建一个对象,将需要代理的类的对象赋予代理类中的该对象,让代理类中该对象去代替需要代理的类的对象去执行一定的

设计模式(结构型)之代理模式(Proxy Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(结构型)之享元模式(Flyweight Pattern)>http://blog.csdn.net/yanbober/article/details/45477551 概述 代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时可以通过一个

&quot;围观&quot;设计模式(15)--结构型之桥梁模式(Bridge Pattern)

桥接模式是软件设计模式中最复杂的模式之一,它把事物对象和其具体行为.具体特征分离开来,使它们可以各自独立的变化.事物对象仅是一个抽象的概念.如"圆形"."三角形"归于抽象的"形状"之下,而"画圆"."画三角"归于实现行为的"画图"类之下,然后由"形状"调用"画图".----WIKIPEDIA 个人理解 桥梁模式的核心在于解耦,通过抽象化将具体的事物

&quot;围观&quot;设计模式(14)--结构型之外观模式(Facade Pattern)

外观模式(Facade pattern),是软件工程中常用的一种软件设计模式,它为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易使用.----WIKIPEDIA 个人理解 当一个项目中出现比较杂乱的调用关系时,类与类之间的耦合关系过于复杂,为了降低耦合度,我们可以采用一个公共的接口与其他类发生耦合,这样可以尽量大的降低外界与该系统的耦合度,同时降低了整个系统的复杂度,外观模式相当于一个公共的入口一样,为使用者敞开大门,暴漏一些必要的接口,方便外界进行调用.通俗来讲就是,有多个不同的类

【设计模式】-结构型-7-组合模式

主要角色 抽象构件(Component)角色:它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为.在透明式的组合模式中抽象构件还声明访问和管理子类的接口:在安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝构件完成. 树叶构件(Leaf)角色:是组合中的叶节点对象,它没有子节点,用于实现抽象构件角色中 声明的公共接口. 树枝构件(Composite)角色:是组合中的分支节点对象,它有子节点.它实现了抽象构件角色中声明的接口,它的主要作用是存储和管理子部件,通常包含 A

【设计模式】-结构型-2-适配器模式

主要角色 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口. 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口. 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者. 代码展示 package adapter; //目标接口 interface Target { public void request(); } //适配者接口 class Adaptee { public

【设计模式】-结构型-5-外观模式

主要角色 外观(Facade)角色:为多个子系统对外提供一个共同的接口. 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它. 客户(Client)角色:通过一个外观角色访问各个子系统的功能. 代码展示 package facade; public class FacadePattern { public static void main(String[] args) { Facade f=new Facade(); f.method(); } } //外观角色

&quot;围观&quot;设计模式(30)--结构型设计模式总结(适配器、代理、装饰、外观、桥梁、组合、享元)

设计模式代码下载地址 设计模式代码下载地址 1  适配器模式 在设计模式中,适配器模式(英语:adapter pattern)有时候也称包装样式或者包装(wrapper).将一个类的接口转接成用户所期待的.一个适配使得因接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中.----WIKIPEDIA 个人理解 适配器模式:将两个不一致或者说无法直接使用的类或者接口通过适配器模式进行兼容,使得他们可以在一块使用.适配器模式在之前的项目中我是用于处理数据的不兼容的,对

Java经典23种设计模式之结构型模式(三)------附代理模式、适配器模式、外观模式区别

本文介绍7种结构型模式里的剩下两种:享元模式.代理模式. 一.享元模式FlyWeight 享元模式比较简单且重要,在很多场合都被用到,只不过封装起来了用户看不到.其概念:运用共享内存技术最大限度的支持大量细粒度的对象.这个概念给的有些抽象,说白了就是如果内存中存在某个对象A,如果再次需要使用对象A的时候如果内存中有A这个对象就直接使用它,不要再次new了.如果没有,则重新new一个.基于这个特点,享元模式使用时一般会给待访问对象传递一个Tag,用来标识这个对象,而且要同时使用抽象工厂的方法进行访

设计模式4 结构型模式

设计模式4  结构型模式 目录 代理模式 装饰器 外观模式 适配器模式 代理模式,美国,韩国代理购物 [email protected]:~$ cat main.cpp  #include<iostream> using namespace std; class Item //商品 { public: Item(string kind ,bool fact) { this->kind = kind; this->fact = fact; } string getKind() { r