静态代理、动态代理

涉及到的设计模式中原则:

单一分配原则:一个类或一个接口唯一项原则,尽量设计出功能单一的接口。

开闭原则:程序对外扩展开放,对修改关闭。换句话说,当需求发生变化时,我们可以通过添加新模块来满足新需求,而不是通过修改原来的实现代码来满足新需求。

依赖倒转原则:高层模块不应该依赖低层模块具体实现,解耦高层与低层,即面向接口编程,当实现发生变化时,只需要提供新的实现类,不需要修改高层模块代码。

 

一、静态代理

/**
 * 	男性生活用品公司
 * 
 * @author Mona
 *
 */
//抽象接口,描述了服务提供者的行为
public interface ManFactory {
	void saleManStuff(String size);
}


/**
 * 	女性生活用品公司
 * 
 * @author Mona
 *
 */
//抽象接口,描述了服务提供者的行为
public interface WomanFactory {
	void saleManStuff(int height);
}

 

public class BbFactory implements WomanFactory{

	public void saleWomanStuffFactory(float height) {
		System.out.println("根据你的需求,为您定制了一个高度为:" + height + "的衣帽间");
	}
}


public class BbFactory implements WomanFactory{

	public void saleWomanStuffFactory(float height) {
		System.out.println("根据你的需求,为您定制了一个高度为:" + height + "的衣帽间");
	}
}

 

import com.proxy.stat.ManFactory;

/**
 * 	代理对象,包含真实的对象,为真实对象的服务进行增强,和真实对象实现同一接口或继承同一父类
 * 
 * @author Mona
 *
 */
public class Lisa implements ManFactory,WomanFactory {

	//被包含的真实对象            目标对象,通过接口来聚合
        public ManFactory factory;
        public WomanFactory wfactory;

	public Lisa(ManFactory factory) {
		super();
		this.factory = factory;
	}
	
	    public void saleManStuff(String size) {
		dosomethingBefore();//前置增强
		factory.saleManStuff(size);
		dosomethindEnd();//后置增强
	}
	
	
	// 售后服务
	private void dosomethindEnd() {
		System.out.println("精美包装,一条龙服务:");
	}

	// 售前服务
	private void dosomethingBefore() {
		System.out.println("根据您的需求,进行市场调研和产品分析!");
	}

    public void saleWomanStuffFactory(float height) {

		......

	}
}

测试:

import com.proxy.dynamic.Lisa;
import com.proxy.stat.AaFactory;
import com.proxy.stat.ManFactory;

public class Client {
	public static void main(String[] args) {
		//有一家海外A公司生产男性生活用品
		ManFactory factory = new AaFactory();
		//lisa代理这个公司的产品
		Lisa lisa = new Lisa(factory);
		//客户来找我做代理
		lisa.saleManStuff("D");


        ......



	}
}

可以很容易的看出:可扩展性和可维护性都很差,随着用户的增加,代码会越来越庞大,不易维护,违反了开闭原则。

 

 

二、动态代理

 

情景:国外有很多公司生产男性、女性生活用品:A,B......Lisa成立了代购公司,顾客只需找Lisa代购商品,即不需要出国自己购买。

/**
 * 	男性生活用品公司
 * 
 * @author Mona
 *
 */
//抽象接口,描述了服务提供者的行为
public interface ManFactory {
	void saleManStuff(String size);
}
public class AaFactory implements ManFactory{
	public void saleManStuff(String size) {
		System.out.println("根据您的需求,为您定制了一个size为:" + size + "的帽子");
	}
}
/**
 * 	女性生活用品公司
 * 
 * @author Mona
 *
 */
public interface WomanFactory {
	void saleWomanStuffFactory(float height);
}
public class BbFactory implements WomanFactory{

	public void saleWomanStuffFactory(float height) {
		System.out.println("根据你的需求,为您定制了一个高度为:" + height + "的衣帽间");
	}
}

代理:

 

参数说明:

loader:      一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
interfaces:  一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
h:           一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个    InvocationHandler对象上


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

public class LisaCompony implements InvocationHandler{

	//被代理的对象
	private Object factory;
	
	
	public Object getFactory() {
		return factory;
	}

	public void setFactory(Object factory) {
		this.factory = factory;
	}


	//通过Proxy获取动态代理的对象
	public Object getProxyInstance() {		//getClass():取得当前对象所属的Class对象,getClassLoader():取得该Class对象的类加载器
																			//类装载器负责从Java字符文件将字符流读入内存,并构造Class类对象
		return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this);//this就是InvocationHandler
	}

	//通过动态代理对象对方法进行增强
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		dosomethingBefore();
		Object ret = method.invoke(factory, args);
		dosomethindEnd();
		return ret;
	}
	
	//售后服务
	private void dosomethindEnd() {
		System.out.println("精美包装,一条龙服务:");
	}
	
	//售前服务
	private void dosomethingBefore() {
		System.out.println("根据您的需求,进行市场调研和产品分析!");
	}
	
}

测试:

import com.proxy.dynamic.BbFactory;
import com.proxy.dynamic.LisaCompony;
import com.proxy.dynamic.WomanFactory;
import com.proxy.stat.AaFactory;
import com.proxy.stat.ManFactory;

public class ClientTest {
	public static void main(String[] args) {
		//日本有个公司生产男性生活用品
		ManFactory aFactory = new AaFactory();
		//日本有个B公司生产女性生活用品
		WomanFactory bFactory = new BbFactory();
		//lis成立了一个代购公司
		LisaCompony liCompony = new LisaCompony();
		//张三来找我代理男性生活物品
		liCompony.setFactory(aFactory);
		//一号员工对这个 行业很熟悉,我委派一号员工为他服务
		ManFactory lisa1 = (ManFactory) liCompony.getProxyInstance();
		//一号员工为他服务,完成代购
		lisa1.saleManStuff("D");
		
		System.out.println("----------------");
		
		//小红要代购女性生活物品
		liCompony.setFactory(bFactory);
		//2号员工对这个 行业很熟悉,我委派2号员工为他服务
		WomanFactory lisa2 = (WomanFactory) liCompony.getProxyInstance();
		//2号员工为他服务,完成代购
		lisa2.saleWomanStuffFactory(1.8f);
		
	}
}

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值