大话设计模式读书笔记(代理模式)

人物:小菜,大鸟

事件:大鸟询问小菜和娇娇约会经过,小菜道出娇娇已经有男朋友了,而且还说娇娇给他分享了她的恋爱经历:高中时期,隔壁班男生卓贾易喜欢娇娇,卓贾易找了娇娇同班男生,同时也是自己好朋友戴励,不时向娇娇送礼物,这样一来二去,娇娇喜欢上了戴励,戴励最终和娇娇在一起,卓贾易最终为他人做了嫁衣。


代理模式:

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.智能指引,指当调用真实的对象时,代理处理另外一些事。如计算对象的引用次数,当该对象没有引用时,可自动释放

小结:代理模式就是在访问对象时引入一定程度的间接性,因为这种间接性,可以附加很多用途

原文地址:https://www.cnblogs.com/wencheng9012/p/13386007.html