设计模式之代理模式(Proxy Pattern)

一、代理模式概述

Proxy代理模式,它指的是不需要本人亲自完成工作,而是寻找代理人帮助完成,但是代理人能代替本人做的事情是有限的,有一些问题自己无法解决还是必须要找到被代理人解决问题;

为什么需要代理,举个生活的例子,打官司一般都会有代理律师,虽然我们也可以学习法律,但是成本很高,而有了律师以后,我们就不必再关心各种流程细节,但是当律师需要求证信息的时候,仍然需要被代理人配合;

比如,我们在游戏中经常会封装一些Manager,它其实也是一种代理的概念;

二、程序示例

如下是模拟一个带名字的打字机,就是将文字显示到界面上;

为了让代理类和被代理类具有行为的一致性,我们需要定义一个Printable接口,然后两个类都要实现这个接口;

    public interface Printable {
        public abstract void SetPrinterName(String name);
        public abstract String GetPrinterName();
        public abstract void Print(String str);
    }

程序的前提是生成Printer实例是很耗的,因此我们会尽可能延迟到真正使用时才会创建;

Printer类是真正做打印工作的类;

    public class Printer : Printable{
        private String name;
        public Printer() {
            HeavyJob("正在生成Printer实例");
        }
        public Printer(String name) {
            this.name = name;
            HeavyJob("正在生成Printer实例" + name);
        }
        public void SetPrinterName(String name) {
            this.name = name;
        }
        public String GetPrinterName() {
            return this.name;
        }
        public void Print(String str) {
            System.Console.WriteLine(str);
        }

        private void HeavyJob(String msg) {
            System.Console.WriteLine(msg);
            for (int i = 0; i < 5; i++) {
                try
                {
                    Thread.Sleep(1000);
                }
                catch (ThreadInterruptedException e) { }
                System.Console.Write(".");
            }
            System.Console.WriteLine("End");
        }
    }

而PrinterProxy只是代理,因此在需要打印的时候,它还是需要找到它代理的打印实例,然后调用实例的打印方法来完成工作; 

    public class PrinterProxy : Printable{
        private String name;
        private Printer real;
        public PrinterProxy(String name) {
            this.name = name;
        }
        public void SetPrinterName(String name) {
            if (real != null) {
                real.SetPrinterName(name);
            }
            this.name = name;
        }
        public String GetPrinterName() {
            return name;
        }
        public void Print(String str) {
            Realize();
            real.Print(str);
        }

        private void Realize() {
            if (real == null) {
                real = new Printer(name);
            }
        }
    }

client测试代码

            Printable p = new PrinterProxy("Alice");
            System.Console.WriteLine("my name is : " + p.GetPrinterName());
            p.SetPrinterName("Bob");
            System.Console.WriteLine("my name is : " + p.GetPrinterName());
            p.Print("hello world");

三、分析总结

在Proxy中,一般有以下几个角色

Subject,主体,对应上面的Printable,使得代理和被代理之间有统一的接口,由于Subject存在,Client就不必在意它用的究竟是Proxy还是RealSubject;

Proxy,代理人,Proxy会尽量处理来自Client的请求,只有当自己不能处理时,它才会将工作交给RealSubject角色;

RealSubject,只有当Proxy无法胜任工作时才出场;

类图关系如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值