【设计模式】代理模式

系列文章目录

文章目录


在代理模式这一章节,我们以一个例子展开

小张一直喜欢小李,但是嘞,小张这个人比较害羞,不认识小李而且他不好意思是自己去追小李,这时候他有一个朋友,小王,恰好这个小王认识小李,然后小张每次想送给小李什么东西就都让小王去送,这就是一个简单的代理模式。接下来,我们用代码逐版本分析。

没有代理的代码

这里如果我们的小张直接追求小李的话,此时我们有如下代码:

java 复制代码
	//追求者类
    class Pursuit{
        private SchoolGirl mm;
        public Pursuit(SchoolGirl mm){
            this.mm = mm;
        }
        public void giveDolls(){
            System.out.println("this.mm.getName()" + " " + " 你好,送给你洋娃娃");
        }
        public void giveFlowers(){
            System.out.println("this.mm.getName" + " " + "你好,送给你鲜花");
        }
        public void giveChocolate(){
            System.out.println("this.mm.getName() " + "你好,送给你巧克力");
        }
    }
    //被追求者类
    public SchoolGirl{
        private String name;
        public String getName(){
            return this.name;
        }
        public void SetName(String value){
            this.name = value
        }
    }

    public static void main(String[] args) {
        SchoolGirl girl = new SchoolGirl();
        girl.setName("小李");
        Pursuit boy = new Pursuit(girl);    
        boy.giveChocolate();
        boy.giveDolls();
        boy.giveFlowers();
    }

这里我们可以发现,代码好像是有问题的,这里被追求者小李并不认识小张,这样写的话就相当于他们之间互相认识了,而且是小张直接把东西送个小李了吗?代码表示是这个意思,我们需要用代理的方式来改写代码,此时小王就是代理。

只有代理的代码

代理类代码

java 复制代码
  //代理类
    class Proxy{
        private SchoolGirl mm;
        public Proxy(SchoolGirl mm){
            this.mm = mm;
        }
        public void giveDolls(){
            System.out.println(this.mm.getName() + " , 你好,送给你洋娃娃");
        }
        public void giveFlowers(){
            System.out.println(this.mm.getName() + " ,你好,送给你鲜花");
        }
        public void giveChocolate() {
            System.out.println(this.mm.getName() + " , 你好送给你巧克力");
        }
    }
     public static void main(String[] args) {
        SchoolGirl girl = new SchoolGirl();
        girl.setName("小李");
        Proxy mid = new Proxy(girl);
        mid.giveDolls();
        mid.giveFlowers();
        mid.giveChocolate();
    }

我们来看这份代码,我们把Pursuit(追求者)换成了Proxy(代理),把小张换成了小王,这就使得你的这个礼物变成是小王送的,针对这个事件,我们可以明确知道,礼物确实是小张送的,礼物是他买的,我们在这里把Pursuit(追求者)给忽略了,事实上应该是Pursuit(追求者)通过Proxy(代理)送给SchoolGirl(被追求者)礼物,这才是合理的,我们要如何做呢?

我们发现Pursuit和Proxy都有送礼物的三个接口,只不过Proxy(代理)送的礼物是Pursuit(追求者)买的,实质上是Pursuit送的。既然有相同的方法,也就是说它们实现了相同的接口!

代码最终版

java 复制代码
//送礼物接口
public interface IGiveGift {
    void giveDolls();
    void giveFlowers();
    void giveChocolate();
}
//追求者类
public class Pursuit implements IGiveGift{
    private SchoolGirl mm;
    public Pursuit(SchoolGirl mm){
        this.mm = mm;
    }
    @Override
    public void giveDolls() {
        System.out.println(mm.getName() + "你好,我是小张 , 送你洋娃娃");
    }
    @Override
    public void giveFlowers() {
        System.out.println(mm.getName() + "你好,我是小张 ,送你花");
    }
    @Override
    public void giveChocolate() {
        System.out.println(mm.getName() + "你好,我是小张,送给你巧克力");
    }
}
//被追求者类
public class SchoolGirl {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String value) {
        this.name = value;
    }
}
//代理类
public class Proxy implements IGiveGift {
    private Pursuit gg;
    public Proxy(SchoolGirl mm){
        this.gg = new Pursuit(mm);
    }
    @Override
    public void giveDolls() {
        this.gg.giveDolls();
    }
    @Override
    public void giveFlowers() {
        this.gg.giveFlowers();
    }

    @Override
    public void giveChocolate() {
        this.gg.giveChocolate();
    }
}

在上述代码中,追求者类只是增加了实现送礼物接口一处改动。

代理类,是唯一既认识追求者,有认识被追求者类的类,在初始化过程中,建立了追求者与被追求者的关联,并在实现自己的接口方法时,调用了追求者的同名方法。

这样修改代码后,即使小李不认识小张,但却可以通过代理人得到礼物,效果已经达到,接下来我们看GoF对代理模式是如何描述的。

代理模式

代理模式:为其他对象提供一种代理以控制对这个对象的访问。

java 复制代码
//ISubject接口
 interface ISubject{
     void request();
 }
 //RealSubject类
 class RealSubject implements ISubject{
     @Override
     public void request() {
         System.out.println("真实的请求");
     }
 }
    //代理类
    class Proxy implements ISubject{
     private RealSubject cs;
     public Proxy(){
         
     }
     @Override
     public void request() {
         this.cs.request();
     }
    }

    public static void main(String[] args) {
        Proxy proxy = new Proxy();
        proxy.request();
    }
    

代理模式的应用

代理模式一般应用在一下几种场合

1.远程代理,也就是为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实。

2.虚拟代理,是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。 这样可以达到性能的最大化,比如在打开HTML网页时,里面可能有很多文字和图片,但你还是可以很快就打开他,此时你所看到的是所有的文字,但图片却是一张一张下载后先能看到,那些未打开的图片框,就是通过虚拟代理来替代了真实的图片。此时代理存储了真实图片的路径和尺寸。

3.安全代理,用来控制真实对象访问时的权限。 一般用于对象应该有不同的访问权限的时候。

4.智能指引,是指当调用真实的对象时,代理处理另外一些事。 如计算真实对象的引用次数,或在访问一个实际对象前,检查是否已经锁定它,

代理模式其实就是在访问对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。代理就是真实对象的代表。

总结

以上就是本文全部内容,本文主要向大家介绍了设计模式中的代理模式,通过一个例子引入,最后修改该例代码为代理模式,引出代理模式模版代码。感谢各位能够看到最后,如有问题,欢迎各位大佬在评论区指正,希望大家可以有所收获!创作不易,希望大家多多支持!

最后,大家再见!祝好!我们下期见!

相关推荐
小趴菜不能喝3 小时前
Spring boot3.x整合mybatis-plus踩坑记录
java·spring boot·mybatis
摸鱼仙人~3 小时前
Spring Boot 拦截器(Interceptor)与过滤器(Filter)有什么区别?
java·spring boot·后端
来一杯龙舌兰3 小时前
【Sharding-JDBC】Spring/Spring Boot 集成 Sharding-JDBC,分表策略与 API、YAML 配置实践
java·spring boot·spring
叫我阿柒啊3 小时前
Java全栈开发工程师面试实战:从基础到微服务的完整技术演进
java·spring boot·微服务·前端框架·vue3·全栈开发·面试技巧
华农第一蒟蒻3 小时前
Elasticsearch赋能3D打印机任务统计分析
java·大数据·spring boot·后端·elasticsearch·adb·maven
金銀銅鐵4 小时前
[Java] 验证 HashMap 的扩容时机
java·后端
间彧4 小时前
Java高级语法糖有哪些
java
现在没有牛仔了4 小时前
SpringBoot全局异常处理实战详解
java·spring boot·后端
码农阿豪4 小时前
EasyVoice与cpolar:构建私域有声平台的本地化方案
java·voice