4.代理模式

4.结构型模式-代理模式


4.1 基础知识

学习难度:3

使用频率:4

总分:7

定义

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

说人话

代理模式可以帮助我们控制对某个对象的访问,实现对象的保护、延迟加载等功能。

结构图

实现步骤

  • 主题接口:定义请求方法。
  • 真实主题类:实现主题接口,实现请求方法。
  • 代理主题类:实现主题接口,定义真实主题对象,实现请求方法,调用真实主题对象进行请求。如果真实主题对象为空,就先实例化。相当于对真实主题接口封装一层。
  • 客户端:实例化代理主题,使用代理主题进行请求。

说明

代理模式在软件开发中被广泛应用,常见的场景包括远程代理、虚拟代理、安全代理等。通过代理对象,我们可以在不直接访问真实对象的情况下,实现对真实对象的控制和管理。


4.2 模版代码

主题接口

//主题接口
public interface ISubject
{
    void Request();
}

真实主题类

// 真实主题
class RealSubject : ISubject
{
    public void Request()
    {
        Console.WriteLine("真实的请求");
    }
}

代理主题类

// 代理主题
class Proxy : ISubject
{
    RealSubject realSubject;
    
    public void Request()
    {
        if (realSubject == null)
        {
            realSubject = new RealSubject();
        }
        Console.WriteLine("代理请求中调用真实请求前");
        realSubject.Request();
        Console.WriteLine("代理请求中调用真实请求后");
    }
}

客户端

class Program
{
    static void Main(string[] args)
    {
        // 使用代理来执行操作
        ISubject proxy = new Proxy();
        
        proxy.Request();
        // 代理请求中调用真实请求前
        // 真实的请求
        // 代理请求中调用真实请求后

    }
}

4.3 CSharp实践

实践需求

使用代理模式,模拟夏洛对马冬梅发起结婚请求,大春作为中间人

结婚请求、追求者、代理人

// 请求结婚接口
interface IMarriage
{
    void RequestMarriage();
}

//追求者
class Boy : IMarriage
{
    private string name;
    public string Name => name;

    public Boy(string name)
    {
        this.name = name;
    }

    public void RequestMarriage()
    {
        Console.WriteLine($"我是{name},和我结婚吧!");
    }
}

//代理人
class Proxy : IMarriage
{
    private string name;
    public string Name => name;
    private Boy boy;
    private Girl girl;

    public Proxy(string name, Boy boy, Girl girl)
    {
        this.name = name;
        this.boy = boy;
        this.girl = girl;
    }

    public void RequestMarriage()
    {
        Console.WriteLine($"我是代理人{name},帮{boy.Name}给{girl.Name}传达信息:");
        boy.RequestMarriage();
    }
}

被追求者

//被追求者
class Girl
{
    private string name;
    public string Name => name;

    public Girl(string name)
    {
        this.name = name;
    }
}

客户端

class Program
{
    static void Main(string[] args)
    {
        //被追求者马冬梅
        Girl maDongMei = new Girl("马冬梅");

        //追求者夏洛
        Boy xiaLuo = new Boy("夏洛");

        //代理人大春
        Proxy daChun = new Proxy("大春", xiaLuo, maDongMei);

        //大春执行请求
        daChun.RequestMarriage();

        // 我是代理人大春,帮夏洛给马冬梅传达信息:
        // 我是夏洛,和我结婚吧!
    }
}

4.4 Unity实践

实践需求

使用代理模式,实现薇恩的创建,并且创建后按下任何键就进行攻击。

英雄行为接口、真实薇恩类和代理薇恩类

//英雄行为接口
public interface IHeroSubject
{
    void Create();
    void Attack();
}

public class VayneReal : IHeroSubject
{
    public GameObject vayneGameObject;

    public void Create()
    {
        vayneGameObject = GameObject.Instantiate(Resources.Load<GameObject>("Lesson13_结构型模式_代理模式/Vayne"),
            Vector3.zero, Quaternion.identity);
    }

    public void Attack()
    {
        vayneGameObject.GetComponent<Animator>().SetTrigger("attack");
    }
}

public class VayneProxy : IHeroSubject
{
    private VayneReal vayneReal;

    public VayneProxy(VayneReal vayneReal)
    {
        this.vayneReal = vayneReal;
    }

    public void Create()
    {
        vayneReal.Create();
    }

    public void Attack()
    {
        vayneReal.Attack();
    }
}

客户端

public class TestProxyPattern : MonoBehaviour
{
    private VayneReal vayneReal;
    private VayneProxy vayneProxy;

    private void Start()
    {
        vayneReal = new VayneReal();
        vayneProxy = new VayneProxy(vayneReal);

        vayneProxy.Create();
    }

    private void Update()
    {
        if (Input.anyKey)
        {
            vayneProxy.Attack();
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏