周六无事,看看java的代理模式
静态代理:
代理模式,抽象的说就是代理者能提供被代理者的某种服务,并对其服务进行一定的封装,并提供自己的一些特殊服务,即完成对象的功能代理
举例说明,例如租房就是一种公共服务,房东就是提供这种服务的具体实例,中介公司就是这种服务的代理,并在房东和房客之间提供一系列的其他服务
代理列举:
Rent.java(租房服务),静态代理可以是接口也可以是抽象类,此处使用接口
package com.lyncc.proxy;
public interface Rent {
public boolean rent(int money);
}
Landlord.java(租房的具体实例,例如xxx房东,实现租房服务)
package com.lyncc.proxy;
public class Landlord implements Rent{
@Override
public boolean rent(int money) {
if(money>4000){
System.out.println("给你一个适合居住的房子");
return true;
}else{
System.out.println("钱有些少,要不再加一点?");
return false;
}
}
}
Agency.java(租房中介,提供一个租房平台,并收取一定的费用,boolean fee 代表房客是否愿意交中介费)
静态代理的核心就是要把具体的代理实例传递进来,这里具体指的是landlord,就是房东,简单的说,如果没有房东委托中介公司,中介公司无法代理租房服务
package com.lyncc.proxy;
public class Agency implements Rent {
private boolean fee;
public Agency(boolean fee){
this.fee = fee;
}
public Landlord landlord;
@Override
public boolean rent(int money) {
if(fee){
System.out.println("愿意交中介费的孩子是好孩子");
if(null == landlord){
landlord = new Landlord();
}
return landlord.rent(money);
}else{
System.out.println("不交中介费,无房可租");
return false;
}
}
}
客户测试端
package com.lyncc.proxy;
import org.junit.Test;
public class Client {
@Test
public void test(){
Agency agency = new Agency(true);
agency.rent(5000);
}
@Test
public void test1(){
Agency agency = new Agency(true);
agency.rent(3000);
}
@Test
public void test2(){
Agency agency = new Agency(false);
agency.rent(3000);
}
}
动态代理,代码中有注释,希望大家一起学习,错了的地方指出
动态代理的原因就是静态代理的缺陷,一个具体实例,如果需要代理就有唯一的代理类为其代理
代码量增加了2倍,大规模编程不方便
代码模型实例就是淘宝代理了旅游店,零食店,提供了旅游,和买零食的服务
Travel.java(旅游服务)
package com.lyncc.dynamic.proxy;
/**
* 旅游就是一种服务,具体实现就是各个旅行社,或者各个地方的旅游
* 对于动态代理对象,不用管是哪个旅行社或者哪个地方的旅游,它只负责提供服务
* @author BazingaLyn
*
*/
public interface Travel {
public void travel(int money);
}
Snack.java(买零食的服务)
package com.lyncc.dynamic.proxy;
/**
* 购买零食也是一种服务消费,例如淘宝有很多的零食店,例如有xiaoy零食店
* 桥林零食店,三只松鼠等等,当你进入淘宝的哪个零食页面,默认就是哪个零食店实例
* 淘宝这种代理只会返回购买的服务,否则就会出现实例化N个对象
* 例如,买家进入桥林零食店
* 后台就要new Qiaolinshop()
* 进入09机械键盘店
* 后台就要new 09keyBoardshop()
* 淘宝后面的卖家数以万计,这样做很不现实
* 即淘宝后台只会返回一个接口,动态代理很容易实现这样的设计理念
* @author BazingaLyn
*
*/
public interface Snack {
public void buy(int money);
}
NanjingTravel.java(旅游的实例,南京旅游)
package com.lyncc.dynamic.proxy;
/**
* 旅游服务的一个实例
* @author BazingaLyn
*
*/
public class NanjingTravel implements Travel{
@Override
public void travel(int money) {
if(money > 50000){
System.out.println("南京兔女郎豪华紫金山5日4夜游,你懂得,O(∩_∩)O~");
}else if(money > 20000){
System.out.println("南京江宁瑞都轻奢店美女陪伴一日游");
}else if(money > 5000){
System.out.println("南京夫子庙一日游");
}else{
System.out.println("南京高校基友陪伴一日游");
}
}
}
QiaolinSnackShop.java(零食店,桥林零食(有看war3的吗?哈哈))
package com.lyncc.dynamic.proxy;
/**
* 零食店的一个实例
* @author BazingaLyn
*
*/
public class QiaolinSnackShop implements Snack{
@Override
public void buy(int money) {
if(money > 500){
System.out.println("送桥林签名");
}else if(money > 200){
System.out.println("送四哥光环");
}else if(money > 100){
System.out.println("包邮");
}else{
System.out.println("你不会只买了一包辣条吧?");
}
}
}
Taobao.java(淘宝商城,代理上述的服务)
package com.lyncc.dynamic.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 淘宝实现动态代理,implement InvocationHandler
* Object 代理具体哪个实例
* fee 是否愿意用支付宝付钱,不愿意不提供服务
* @author BazingaLyn
*
*/
public class Taobao implements InvocationHandler{
public Object obj;
public boolean fee;
public Taobao(Object obj, boolean fee){
this.obj = obj;
this.fee = fee;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//代理商自定义的一些要求
if(fee){
System.out.println("谢谢你先把钱打到支付宝");
method.invoke(obj, args);
}else{
System.out.println("支付宝不愿意打,那你自己去找服务商吧");
}
return null;
}
}
Client.java(买家)
package com.lyncc.dynamic.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import org.junit.Test;
/**
* 买家测试
* @author BazingaLyn
*
*/
public class Client {
/**
* 买家需要旅游服务
*/
@Test
public void test1(){
//进入南京旅游的页面,实例化南京旅游
NanjingTravel nanjingTravel = new NanjingTravel();
//淘宝代理了南京旅游
InvocationHandler handler = new Taobao(nanjingTravel,true);
Class<?> clz = handler.getClass();
//返回了旅游的服务,这很重要,如果返回的是NanjingTravel就很累了,这样就没有意义了
//Proxy.newProxyInstance代理的关键
Travel travel = (Travel)Proxy.newProxyInstance(clz.getClassLoader(), nanjingTravel.getClass()
.getInterfaces(), handler);
//交钱旅游
travel.travel(1000000);
}
@Test
public void test2(){
NanjingTravel nanjingTravel = new NanjingTravel();
InvocationHandler handler = new Taobao(nanjingTravel,false);
Class<?> clz = handler.getClass();
Travel travel = (Travel)Proxy.newProxyInstance(clz.getClassLoader(), nanjingTravel.getClass()
.getInterfaces(), handler);
travel.travel(1000000);
}
@Test
public void test3(){
QiaolinSnackShop qiaolinSnackShop = new QiaolinSnackShop();
InvocationHandler handler = new Taobao(qiaolinSnackShop,true);
Class<?> clz = handler.getClass();
Snack snack = (Snack)Proxy.newProxyInstance(clz.getClassLoader(), qiaolinSnackShop.getClass()
.getInterfaces(), handler);
snack.buy(1000000);
}
}
关于具体的java方式,可以查看jdk的api有具体说明,我也是查看和百度的,认识浅薄,求大神科普