代理模式
需求:华华想追蒙蒙却不好意思,就拜托昆昆去送礼物
没有代理的代码
public class Pursuit {
private SchoolGirl mm;
public Pursuit(SchoolGirl mm) {
this.mm=mm;
}
public void giveDolls() {
System.out.println("送你洋娃娃");
}
public void giveFlowers() {
System.out.println("送你鲜花");
}
public void giveChocolate() {
System.out.println("送你巧克力");
}
}
public class SchoolGirl {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Demo1 {
public static void main(String[] args) {
SchoolGirl mengmeng=new SchoolGirl();
mengmeng.setName("蒙蒙");
//但是蒙蒙并不认识华华,这里有问题
Pursuit huahua=new Pursuit(mengmeng);
huahua.giveDolls();
huahua.giveFlowers();
huahua.giveChocolate();
}
}
问题描述:蒙蒙并不认识华华,上面的代码表示的是华华亲自送东西给蒙蒙
只有代理的代码
public class Proxy {
private SchoolGirl mm;
public Proxy(SchoolGirl mm) {
this.mm=mm;
}
public void giveDolls() {
System.out.println("送你洋娃娃");
}
public void giveFlowers() {
System.out.println("送你鲜花");
}
public void giveChocolate() {
System.out.println("送你巧克力");
}
}
public class Demo2 {
public static void main(String[] args) {
SchoolGirl mengmeng=new SchoolGirl();
mengmeng.setName("蒙蒙");
Proxy kunkun=new Proxy(mengmeng);
kunkun.giveDolls();
kunkun.giveFlowers();
kunkun.giveChocolate();
}
}
上面的代码表达的意思是礼物是昆昆送的,事实上应该是华华通过昆昆给蒙蒙送礼物;通过观察可知,Pursuit类和Proxy类都有三个送礼物的方法,只不过Proxy送的礼物是Pursuit买的,既然两者都有相同的方法,意味着他们可以实现同样的接口
符合实际的代码
public interface IGiveGift {
public abstract void giveDolls();
public abstract void giveFlowers();
public abstract void giveChocolate();
}
public class Pursuit implements IGiveGift{
private SchoolGirl mm;
public Pursuit(SchoolGirl mm) {
this.mm=mm;
}
public void giveDolls() {
System.out.println("送你洋娃娃");
}
public void giveFlowers() {
System.out.println("送你鲜花");
}
public void giveChocolate() {
System.out.println("送你巧克力");
}
}
public class Proxy implements IGiveGift{
private Pursuit pursuit;
public Proxy(SchoolGirl mm) {
pursuit=new Pursuit(mm);
}
public void giveDolls() {
pursuit.giveDolls();
}
public void giveFlowers() {
pursuit.giveFlowers();
}
public void giveChocolate() {
pursuit.giveChocolate();
}
}
public class Demo3 {
public static void main(String[] args) {
SchoolGirl mengmeng=new SchoolGirl();
mengmeng.setName("蒙蒙");
Proxy kunkun=new Proxy(mengmeng);
kunkun.giveDolls();
kunkun.giveFlowers();
kunkun.giveChocolate();
}
}
蒙蒙不认识追求她的人华华,但是却可以通过代理人昆昆得到礼物,达到了效果
代理是继承和组合的中庸之道,当我们将一个成员对象(如Pursuit)放在所要构造的类A中,A的子类中暴露了该成员对象的所有方法.如果不想过多的暴露出基类的方法和属性,可以使用代理.在使用代理时可以拥有更多的控制力,因为我们可以选择只提供在成员方法的某个子集.
代理模式的应用
①远程代理,为一个对象再不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实.比如webservice在javaee当中的应用(远程代理的一种形式),当我在应用程序的项目中加入一个web引用,引用一个webservice,此时会在项目中生成一个webreference的文件夹和一些文件,其实它们就是代理,这就使得客户端程序调用代理就可以解决远程访问的问题
②虚拟代理,是根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象,这样就可以达到性能的最优化,比如说你打开一个很大的HTML网页时,里面可能有很多文字和图片,但是你还是可以很快打开它,此时你看到的是所有的文字,而图片却是一张一张下载下来的.那些未打开的图片框,就是通过虚拟代理来代替了真实的图片,此时代理存储了真实图片的路径和尺寸
③安全代理,用来控制真实对象访问时的权限,一般用于对象应该有不同的访问权限的时候
④智能指引,是指当调用真实的对象时,代理处理另外一些事.如计算真实对象的引用次数,这样当该对象没有引用时,可以释放它,或当第一次引用一个持久对象时,将它装入内存;或在访问一个实际对象前,检查是否已经锁定它,以确保其他对象不能改变它.它们都是通过代理在访问一个对象时附加一些内务处理