设计模式系列——代理模式

Posted 花括号MC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式系列——代理模式相关的知识,希望对你有一定的参考价值。

原创:花括号MC(微信公众号:huakuohao-mc)。关注JAVA基础编程及大数据,注重经验分享及个人成长。

代理模式和日常生活中的代理是一个意思,即创建一个代理类,代替真实的业务类完成核心的业务场景。代理模式可以隐藏真实的业务类细节,代理类甚至还可以在核心业务开始和结束时,执行一些记录操作,类似我们经常使用的AOP

举个例子

我们有个加载图片并展示的功能,不希望把加载图片的细节对外展示,并且希望统计每次加载图片一共花费了多少时间,这个时候我们可以考虑使用代理模式。

先看一下UML图:

再来看一下具体代码是怎么实现的

public interface Image 
    void display();

真正的完成核心业务的类

public class RealImage implements Image 

    private String fileName;

    public RealImage(String fileName) throws InterruptedException 
        this.fileName = fileName;
        loadFromDisk(fileName);
    

    @Override
    public void display() 
        System.out.println("Displaying " + fileName);
    

    private void loadFromDisk(String fileName) throws InterruptedException 
        System.out.println("Loading " + fileName);
        Thread.sleep((long) (Math.random()*100));
    

代理类,除了完成主要业务逻辑,还增加了加载图片的时间统计功能。

public class ProxyImage implements Image 

    private RealImage realImage;
    private String fileName;

    public ProxyImage(String fileName) 
        this.fileName = fileName;
    

    @Override
    public void display() throws InterruptedException 
        if (realImage == null)
            long startTime = System.currentTimeMillis();
            realImage = new RealImage(fileName);
            long endTime = System.currentTimeMillis();
            long spendTime = endTime - startTime;
            System.out.println("加载图片花费了: " + spendTime );
        
        realImage.display();
    

看一下客户端如何使用

public class ProxyPatternDemo 
    public static void main(String[] args) throws InterruptedException 
        //使用代理类
        Image image = new ProxyImage("test_10mb.jpg");

        //图片被加载并统计加载时间,所有细节全部被隐藏
        image.display();
        System.out.println("");
    

总结

代理模式是结构型模式之一,日常使用的频率比较高,最典型的应用就是AOP,日志记录等功能。

本文参考:

 https://www.tutorialspoint.com/design_pattern/proxy_pattern.htm

推荐阅读

1. Java并发编程那些事儿(十)——最后的总结

2. 程序员应该掌握的常用网络问题定位工具

3. Awk这件上古神兵你会用了吗

4. 手把手教你搭建一套ELK日志搜索运维平台


·END·
 


设计模式系列 - 代理模式

通过创建现有对象的对象,以便向外界通过访问接口,这种模式我们称之为代理模式

介绍

代理模式属于结构型模式,通过在对象与对象之间添加一个代理中间层来到达对目标对象的间接访问。

类图描述

技术分享图片

由上图可知,我们通过定义一个基本接口来约束业务行为,然后定义具体的业务实现该接口,最后通过定义一个代理类来协调上层和具体业务实体之间的访问,从而使上层也能访问到下层对象。

代码实现

1、创建接口

public interface IImage
{
    void Display();
}

2、实现接口

public class RealImage : IImage
{
    private string fileName;
    public RealImage(string fileName)
    {
        this.fileName = fileName;
        LoadFromDisk();
    }

    public void Display() => Console.WriteLine($"Displaying:{fileName}");
    private void LoadFromDisk() => Console.WriteLine($"Loading:{fileName}");
}

3、定义代理类

public class ProxyImage : IImage
{
    private RealImage realImage;
    private string fileName;
    public ProxyImage(string fileName)
    {
        this.fileName = fileName;
    }

    public void Display()
    {
        if (realImage == null)
        {
            realImage = new RealImage(fileName);
        }
        realImage.Display();
    }
}

4、上层调用

class Program
{
    static void Main(string[] args)
    {
        IImage image = new ProxyImage("test.png");
        image.Display();

        //继续访问时不会创建新对象
        image.Display();

        Console.ReadKey();
    }
}

总结

当上层访问下次对象时,由于业务的需要,我们需要对下层对象进行一个处理,这个时候可以考虑使用代理模式来解决,这个模式带来的好处是保证了现有底层对象不变的情况下进行了访问控制。

以上是关于设计模式系列——代理模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式系列——代理模式

Spring系列设计模式之代理模式

深入理解JavaScript系列(31):设计模式之代理模式

Spring入门系列代理模式和AOP

《设计模式系列》- 代理模式

《设计模式系列》- 代理模式