人物:小菜,大鸟
事件:大鸟询问小菜和娇娇约会经过,小菜道出娇娇已经有男朋友了,而且还说娇娇给他分享了她的恋爱经历:高中时期,隔壁班男生卓贾易喜欢娇娇,卓贾易找了娇娇同班男生,同时也是自己好朋友戴励,不时向娇娇送礼物,这样一来二去,娇娇喜欢上了戴励,戴励最终和娇娇在一起,卓贾易最终为他人做了嫁衣。
代理模式:
1.大鸟先让小菜实现卓贾易直接追娇娇,在小菜实现后指出实现的问题:两者不认识,不能让卓贾易直接追娇娇
2. 然后小菜改进代码,写出代理,让代理追娇娇,大鸟继续指出小菜这里代理的问题,并提出了代理模式
3.小菜领悟后,最终通过代理模式,写出了贾卓易通过戴励追娇娇的案例
4.总结了代理模式
大鸟:卓贾易如果直接追娇娇,应该怎么做呢?
小菜的第一次实现(卓贾易直接追娇娇)
追求者类:
@Slf4j public class Pursuit { SchoolGirl mm; public Pursuit(SchoolGirl mm) { this.mm = mm; } public void giveFlowers() { log.info(mm.getName() + "送你鲜花"); } public void giveChocolate() { log.info(mm.getName() + "送你巧克力"); } }
被追求者类:
@Data public class SchoolGirl { private String name; }
客户端代码:
public static void main(String[] args) { SchoolGirl jiaojiao = new SchoolGirl(); jiaojiao.setName("娇娇"); Pursuit zhuojiayi = new Pursuit(jiaojiao); zhuojiayi.giveFlowers(); zhuojiayi.giveChocolate(); }
大鸟:小菜,你这样写:Pursuit zhuojiayi = new Pursuit(jiaojiao) 是指卓贾易直接送礼物给娇娇,但他们是不认识的,这样处理不正确
小菜:那如何处理?
大鸟:将戴励看做是代理
小菜的第二次实现(使用代理追娇娇)
使用代理:
@Slf4j public class Proxy { SchoolGirl mm; public Proxy(SchoolGirl mm) { this.mm = mm; } public void giveFlowers() { log.info(mm.getName() + "送你鲜花"); } public void giveChocolate() { log.info(mm.getName() + "送你巧克力"); } }
客户端代码:
public static void main(String[] args) { SchoolGirl jiaojiao = new SchoolGirl(); jiaojiao.setName("娇娇"); Proxy daili = new Proxy(jiaojiao); daili.giveChocolate(); daili.giveFlowers(); }
大鸟:你这样把追求者Pursuit(追求者)换成了daili(代理),就相当于把卓贾易换成了戴励。也就是说礼物就编程戴励送的了,卓贾易这个人也就不存在了,你需要找追求者和代理相同的地方
小菜:它们都实现了相同的接口
小菜领悟后的第三次实现
代理接口如下:
public interface GiveGift { void giveFlowers(); void giveChocolate(); }
追求者类:
@Slf4j public class Pursuit implements GiveGift { SchoolGirl mm; public Pursuit(SchoolGirl mm) { this.mm = mm; } @Override public void giveFlowers() { log.info(mm.getName() + "送你鲜花"); } @Override public void giveChocolate() { log.info(mm.getName() + "送你巧克力"); } }
代理类:
@Slf4j
public class Proxy implements GiveGift{
Pursuit gg;
public Proxy(SchoolGirl mm) {
gg = new Pursuit(mm);
}
@Override
public void giveFlowers() {
gg.giveFlowers();
}
@Override
public void giveChocolate() {
gg.giveChocolate();
}
}
客户端如下:
public static void main(String[] args) { SchoolGirl jiaojiao = new SchoolGirl(); jiaojiao.setName("娇娇"); Proxy daili = new Proxy(jiaojiao); daili.giveFlowers(); daili.giveChocolate(); }
代理模式
代理模式:为其他对象提供一种代理以控制对这个对象的访问
实现方式:有A,B两个类,B是代理类,定义让A,B有共同实现的接口或抽象类C,A中是具体的方法,比如送花,然后B里面提供方法调用,这样代理就可以代替实体
所用场合:
1.远程代理,也就是为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实。例如:WebService在.NET中,当应用程序的项目中加入一个web引用,引用一个webService,这是会在项目中生成一个WebReference的文件夹和一些文件,这就是代理,使得客户端程序调用代理就可以解决远程访问的问题
2.虚拟代理,是根据需要创建开销很大的对象,通过它们来存放实例化需要很长时间的真实对象。比如打开一个很大的HTML网页,里面可能很多文字和图片,但是你还是可以很快打开这个网页,此时你可以看到文字,但是图片是要一张一张下载才能看到,那些未打开的图片框,就是通过虚拟代理代替了真实的图片,此时代理存储了真实的图片路径和尺寸
3.安全代理,是用来控制真实对象访问时的权限。一般用于对象应该有不同访问权限的时候
4.智能指引,指当调用真实的对象时,代理处理另外一些事。如计算对象的引用次数,当该对象没有引用时,可自动释放
小结:代理模式就是在访问对象时引入一定程度的间接性,因为这种间接性,可以附加很多用途