1.为什么要用代理模式
在开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访问到这些对象,如果直接访问对象给系统带来不必要的复杂性,这时候可以在客户端和目标对象之间增加一层中间层,让代理对象代替目标对象,然后客户端只需要访问代理对象,由代理对象去帮我们去请求目标对象并返回结果给客户端,
2.代理模式的定义与特点
代理模式的定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
代理模式的主要优点有:
- 代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用
- 代理对象可以扩展目标对象的功能
- 代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度,增加了程序的可扩展性
其主要缺点是:
- 代理模式会造成系统设计中类的数量增加
- 在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢
- 增加了系统的复杂度
3.代理模式的实现
我们可以拿热更新举例,当引入ILRuntime启动热更的时候,我们发现在外部是没有办法直接继承Unity中的Monobehaviour挂载在物体上,由于其中的种种限制,我们无法直接在物体挂载Mono实现Update,Start等功能,所以在这里我们可以通过代理模式实现在ILRuntime中的伪挂载
代码实现:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 代理类,代理类执行实际逻辑脚本
/// </summary>
public class MonoProxy : MonoBehaviour
{
/// <summary>
/// 在ILRuntime中可以通过ILRuntime的内置API加载脚本,这里不做演示
/// </summary>
public void Init(string sctiptName)
{
//通过该脚本名称找到外部执行逻辑的脚本
//中介中不应该实现具体逻辑
//根据脚本名字调用脚本
//伪代码,根据脚本名字映射到对应的函数
ILRuntim.Invoke(ScriptName, "Awake");
}
private void Start()
{
ILRuntim.Invoke(ScriptName, "Start");
}
private void Update()
{
ILRuntim.Invoke(ScriptName, "Update");
}
}
/// <summary>
/// 抽象主题类,实际执行逻辑的脚本继承这个类
/// </summary>
public abstract class MonoBase
{
public abstract void Awake();
public abstract void Start();
public abstract void Update();
}
/// <summary>
/// 实际想执行的脚本
/// </summary>
public class ContreteMono : MonoBase
{
public override void Awake()
{
Debug.Log("Awake的函数");
}
public override void Start()
{
Debug.Log("Start的函数");
}
public override void Update()
{
Debug.Log("Update的函数");
}
}
/// <summary>
/// 外部程序入口
/// </summary>
public class Main
{
/// <summary>
/// 伪代码
///挂载代理脚本从而执行真实脚本
/// </summary>
/// <returns></returns>
GameObject go = new GameObject("测试物体");
MonoProxy monoProxy = go.AddComponent("MonoProxy");
MonoProxy.Init("ContreteMono");
}
好了,我们已经的实现了一个简单的代理脚本
如果你想了解更多设计模式,可以参考菜鸟教程