欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

静态代理、动态代理

程序员文章站 2022-06-10 20:49:57
...
ddd

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

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

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

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

 

一、静态代理

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


/**
 * 	女性生活用品公司
 * 
 * @author Mona
 *
 */
//抽象接口,描述了服务提供者的行为
public interface WomanFactory {
	void saleManStuff(int 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 + "的衣帽间");
	}
}

代理:


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);
		
	}
}