静态代理、动态代理
程序员文章站
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);
}
}
上一篇: 线程间通信
下一篇: vs2017使用中遇到的问题