设计模式学习笔记——代理(Proxy)模式

设计模式学习笔记——代理(Proxy)模式

@(设计模式)[设计模式, 代理模式, proxy]

基本介绍

代理模式可以简单的看作是有个中间人代替你进行工作,当中间人完成不了时,才会由你出马完成。

代理案例

类图

代理案例类图

实现代码

Printable接口

package com.pc.proxy.example;

/**
 * 可打印接口
 * Created by Switch on 2017/3/31.
 */
public interface Printable {
    /**
     * 设置名字
     *
     * @param name 名字
     */
    void setPrinterName(String name);

    /**
     * 获取名字
     *
     * @return 名字
     */
    String getPrinterName();

    /**
     * 显示文字
     *
     * @param string 文字
     */
    void print(String string);
}

Printer类

package com.pc.proxy.example;

/**
 * 打印类
 * Created by Switch on 2017/3/31.
 */
public class Printer implements Printable {
    /**
     * 名字
     */
    private String name;

    public Printer() {
        this.heavyJob("正在生成Printer的实例");
    }

    public Printer(String name) {
        this.name = name;
        this.heavyJob("正在生成Printer的实例(" + this.name + ")");
    }

    @Override
    public void setPrinterName(String name) {
        this.name = name;
    }

    @Override
    public String getPrinterName() {
        return this.name;
    }

    @Override
    public void print(String string) {
        System.out.println("===" + this.name + "===");
        System.out.println(string);
    }

    /**
     * 工作
     *
     * @param msg 消息
     */
    private void heavyJob(String msg) {
        System.out.print(msg);
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.print(".");
        }
        System.out.println("结束。");
    }
}

PrinterProxy类

package com.pc.proxy.example;

/**
 * 打印代理类
 * Created by Switch on 2017/3/31.
 */
public class PrinterProxy implements Printable {
    /**
     * 名字
     */
    private String name;
    /**
     * 本人
     */
    private Printer real;

    public PrinterProxy(String name) {
        this.name = name;
    }

    @Override
    public synchronized void setPrinterName(String name) {
        if (this.real != null) {
            this.real.setPrinterName(name);
        }
        this.name = name;
    }

    @Override
    public String getPrinterName() {
        return this.name;
    }

    @Override
    public void print(String string) {
        this.realize();
        this.real.print(string);
    }

    /**
     * 生成本人
     */
    private synchronized void realize() {
        if (this.real == null) {
            this.real = new Printer(this.name);
        }
    }
}

测试类

package com.pc.proxy.example.test;

import com.pc.proxy.example.Printable;
import com.pc.proxy.example.PrinterProxy;
import org.junit.Test;

/**
 * PrinterProxy Tester.
 *
 * @author Switch
 * @version 1.0
 */
public class ProxyTest {

    /**
     * 测试代理模式
     */
    @Test
    public void testProxy() {
        Printable p = new PrinterProxy("Alice");
        System.out.println("现在的名字是" + p.getPrinterName() + "。");
        p.setPrinterName("Bob");
        System.out.println("现在的名字是" + p.getPrinterName() + "。");
        p.print("Hello, World.");
    }

} 

运行结果

现在的名字是Alice。
现在的名字是Bob。
正在生成Printer的实例(Bob).....结束。
===Bob===
Hello, World.

代理模式中的角色

Subject(主体)

Subject角色定义了使Proxy角色和RealSubject角色之间具有一致性的接口。由于存在Subject角色,所以Client角色不必在意它所使用的究竟是Proxy角色还是RealSubject角色。在案例中,由Printable接口扮演此角色。

Proxy(代理人)

Proxy角色会尽量处理来自Client角色的请求。只有当自己不能处理时,它才会将工作交给RealSubject角色。Proxy角色只有在必要时才会生成RealSubject角色。Proxy角色实现了在Subject角色中定义的接口(API)。在案例中,由PrinterProxy类扮演此角色。

RealSubject(实际的主体)

“本人”RealSubject角色会在“代理人”Proxy角色无法胜任工作时出场。它与Proxy角色一样,也实现了在Subject角色中定义的接口(API)。在案例中,由Printer类扮演此角色。

Client(请求者)

使用Proxy模式的角色。在GoF书中,Client角色并不包含在Proxy模式中。在案例中,由测试类扮演此角色。

类图

代理模式类图

GitHub:DesignPatternStudy

——————参考《图解设计模式》

猜你喜欢

转载自blog.csdn.net/q547550831/article/details/70155608
今日推荐