标签:
一个代理类可以代理多个Subject,因此一个Proxy 具体代理的是哪个RealSubject
Proxy的优点:
在网络设置中,我们可以通过自己设置代理服务器的IP地址获得代理服务(配置代理),也就是在使用代理服务时我们是知道代理的存在的,这种代理模式一般分为两种:
它要求就是客户端只能访问代理角色,而不能访问真实的角色
既然是例讲,我们当然会缔造一个场景:
常见的办公室场景就可以描述这个代理模式,比如作为一个工程师,你需要全神贯注额关注你的项目,很多非技术问题完全可以由前台代办,比如记录一下Schedule什么的,那么前台充当的就是一个代理。
/***
* 主题的抽象接口,用来定义代理和实体的方法
*/
interface Subject2 {
void answerPhone ( );
void planSchedule( );
void remind( );
}
/***
* 工程师实体,用来实现具体的逻辑,但是只能通过代理,不能直接创建
*/
class Engineer implements Subject2{
private String name=null;
public Engineer ( Subject2 subject , String name ) throws Exception {
if( subject == null ){
throw new Exception("不能创建真实角色工程师");
}else{
this.name = name;
}
}
@Override
public void answerPhone() {
System.out.println("Hello, this is llin(lichen)");
}
@Override
public void planSchedule() {
System.out.println("I may set this business Monday");
}
@Override
public void remind() {
System.out.println("Oh! I have to do it now!");
}
}
/**
* 创建代理,提供对工程师方法的调用的对象(不能逾越而直接和工程师交流)
*/
class ForegroundProxy implements Subject2{
private Subject2 subject = null;
public ForegroundProxy( String name ){
try{
subject = new Engineer ( this , name );
}catch ( Exception e ){
e.printStackTrace();
}
}
@Override
public void answerPhone() {
subject.answerPhone();
}
@Override
public void planSchedule() {
subject.planSchedule();
}
@Override
public void remind() {
subject.remind();
}
}
public class ProxyTest {
public static void main ( String [] args ){
Subject2 subject = new ForegroundProxy("llin");
subject.answerPhone();
subject.planSchedule();
subject.remind();
}
}
结果如下:
一般的思维都是通过代理找到真实的角色(前台->工程师),但是强制的代理是要突出强制,你必须通过真实角色查找到代理角色,否则不能访问,就像你要找魏总,不能找安总的秘书把,而且往往魏总往往留下的是自己的名片,但是往往你联系的和联系你的也往往是魏总的秘书…就酱,那么就根据(秘书->经理),我们来例讲强制代理
既然说是秘书,就不像是前台那样只是转接电话了,还会做一些其他的工作,我们也藉此机会,阐述一下代理模式的另外一些功能:
import java.util.StringTokenizer;
/**
* Created by liulin on 16-5-5.
*/
interface Subject3{
void agreeDecision();
void planSchedule();
void answerPhone( String askInfo );
}
class Boss implements Subject3{
Subject3 proxy = null;
@Override
public void agreeDecision() {
if( this.isProxy()){
System.out.println("I agree on it!");
}else{
prompt();
}
}
@Override
public void planSchedule() {
if( this.isProxy()){
System.out.println("I plan to feed my cat!");
}else{
prompt();
}
}
@Override
public void answerPhone( String askInfo ) {
if( this.isProxy()){
if( !checkMessage(askInfo)){
System.out.println("You sure call to me ?");
return;
}
System.out.println("Hello, this is boss...!");
}else{
prompt();
}
}
public Subject3 getProxy(){
this.proxy = new Secretary(this);
return this.proxy;
}
//检查当前调用方法的对象是否是代理对象
private boolean isProxy () {
if( this.proxy == null ){
return false;
}else{
return true;
}
}
//判断电话是否是真的找魏总的
private boolean checkMessage ( String message ){
StringTokenizer st = new StringTokenizer( message );
boolean yes = false;
while ( st.hasMoreTokens()){
String temp = st.nextToken();
if( temp.equalsIgnoreCase("weizong")){
yes = true;
}
}
return yes;
}
//不直接和外界接触
private void prompt ( ){
System.out.println("Please reserve with my secretary!");
}
}
class Secretary implements Subject3{
private Subject3 boss=null;
public Secretary( Subject3 boss ){
this.boss = boss;
}
@Override
public void agreeDecision() {
this.boss.agreeDecision();
}
@Override
public void planSchedule() {
this.boss.planSchedule();
}
@Override
public void answerPhone(String askInfo) {
this.boss.answerPhone(askInfo);
}
}
public class ProxyTest1 {
public static void main ( String [] args ){
Subject3 subject = new Boss().getProxy();
subject.answerPhone("I want to chat with Weizong");
subject.planSchedule();
subject.agreeDecision();
subject.answerPhone("I want to chat with hanzong");
}
}
结果如下:
- 切面代表一个普遍存在的共有的功能
- AOP技术是建立在Java的反射和动态代理机制上
- 将公共方法接入到接入点
我们利用上面的秘书和经理的场景来讲解Dynamic Proxy
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Created by liulin on 16-5-6.
*/
interface People{
void answerPhone();
}
interface Advice{
void prompt();
}
class BeforeAdvice implements Advice{
private String message=null;
BeforeAdvice ( String message ){
this.message = message;
}
@Override
public void prompt() {
System.out.println( message );
}
}
class MyInvocationHandler implements InvocationHandler {
//被代理的对象
private Object target = null;
//通过构造函数构造一个对象
public MyInvocationHandler ( Object target ){
this.target = target;
}
//类似责任链模式的Handler处理方式
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke( target , args );
}
}
//我们可以通过写动态代理类在不修改之前的前提下实现代理逻辑,而且可以不在意具体的接口(反射机制实现)
class DynamicProxy<T>{
private static List<Advice> advices = new ArrayList();
//初始话advices建议列表
static{
advices.add(new BeforeAdvice("Someone have business to you"));
}
public static <T> T newProxyInstance ( ClassLoader classLoader , Class<?>[] interfaces , InvocationHandler h){
//在代理前通知
Iterator it = advices.iterator();
while ( it.hasNext()){
Advice advice = (Advice)it.next();
advice.prompt();
}
return (T) Proxy.newProxyInstance( classLoader , interfaces , h );
}
}
class Weizong implements People{
@Override
public void answerPhone() {
System.out.println("This is manager Wei!");
}
}
public class ProxyTest2 {
public static void main ( String [] args ){
People boss = new Weizong();
//设置对代理的处理者
InvocationHandler handler = new MyInvocationHandler(boss);
//设置动态代理
People secretary = DynamicProxy.newProxyInstance( boss.getClass().getClassLoader(),
boss.getClass().getInterfaces(),
handler);
//如果秘书换职位,接口不再是老板,而是工程师,那么只需要修改参数即可,不需要修改代码
secretary.answerPhone();
}
}
Spring的AOP编程的依赖注入就是通过动态代理实现的,动态代理就是代理模式的最好的应用
Java 设计模式(八) Proxy(代理)模式及Spring引申
标签:
原文地址:http://blog.csdn.net/qq_24451605/article/details/51330236