IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 【设计模式】Unity3D 观察者模式 -> 正文阅读

[游戏开发]【设计模式】Unity3D 观察者模式

行为型模式–观察者模式

提示:个人学习总结,如有错误,尽请指正



一、观察者模式是什么?

让代码宣称有趣的事情发生了,而不必关心到底是谁接受了通知。

事件与其他对象行为的解耦,如成就系统在什么时候响应成就,如果不小心就把代码写在很多奇怪的地方,而我们要做的就是让物理代码去声称“不知道有谁感兴趣,但是这个事情发生了”,成就系统接收到声称再去处理;再如社区通知打疫苗,居民打疫苗不应该由社区调用,而是居民收到通知后自己决定。


二、UML图

//TODO


三、抽象类实现(抽象通知者依赖抽象观察者)

1.抽象被观察者

它有两个任务。首先,它有一个列表,保存默默等它通知的观察者;然后就是发送通知

using System.Collections.Generic;
public abstract class Notifier
{
    private IList<Observer> observers = new List<Observer>();
    //添加观察者
    public void Attach(Observer observer)
    {
        observers.Add(observer);
    }
    //移除观察者
    public void Detach(Observer observer)
    {
        observers.Remove(observer);
    }
    public void Notify()
    {
        foreach (var item in observers)
        {
            item.Update();
        }
    }
}

2.抽象观察者

为所有具体观察者定义一个接口,在得到通知时更新自己
抽象观察者一般用一个抽象类或者接口实现,更新接口通常包含一个Update方法(更新方法)

public abstract class Observer 
{
    public abstract void Update();
}

3.具体通知者

内部状态改变时,给所有登记过的观察者发出通知。
广播

public class Radio : Notifier
{
    private string state;
    public string State { get; set; }
}

4.具体观察者

具体观察者可以保存一个指向具体主题对象的引用

using UnityEngine;
//射手
public class Shooter : Observer
{
    private Radio radio;

    public Shooter (Radio radio)
    {
        this.radio = radio;
    }

    public override void Update()
    {
        Debug.Log("shoot now!");
    }

    public Radio Subject
    {
        get{ return radio; }
        set{ radio = value; }
    }
}

5.客户端

添加观察者,发送通知

using UnityEngine;
public class ObserveGame : MonoBehaviour
{
    private void Start()
    {
        Radio radio = new Radio();
        radio.Attach(new Shooter(radio, "1"));
        radio.Attach(new Shooter(radio, "2"));
        radio.State = "boom";
        radio.Notify();
    }
}

四、事件委托实现(抽象通知者不依赖抽象观察者)

1.具体观察者

using UnityEngine;
//射手1
public class Shooter1
{
    private Notifier notifier;
    private string name;
    public Shooter1 (Notifier Notifier ,string Name)
    {
        this.notifier= Notifier ;
        this.name = Name;
    }

    public void shootTheRed()
    {
        Debug.Log(" I will shoot the red one!");
    }
}

using UnityEngine;
//射手1
public class Shooter2
{
    private Notifier notifier;
    private string name;
    public Shooter2 (Notifier Notifier ,string Name)
    {
        this.notifier= Notifier ;
        this.name = Name;
    }

    public void shootTheGreen()
    {
        Debug.Log(" I will shoot the green one!");
    }
}

2.通知者接口

不再依赖抽象观察者

interface Notifier 
{
	void Notify();
	string State{ get; set; }
}

3.具体通知者

使用delegate关键字

public class NotifyRadio : INotifer
{
    private string action;
    public delegate void Update();
    public Update update;
    public string State
    {
        get { return action; }
        set { action = value; }
 
    }

    public void Notify()
    {
        update();
    }
}

4.客户端

多播委托

using UnityEngine;
public class OberveManager : MonoBehaviour
{
    NotifyRadio notifyRadio = new NotifyRadio();
    void Start()
    {
        Shootor1 one = new Shootor1(notifyRadio, "1");
        Shootor2 two = new Shootor2(notifyRadio, "2");
        notifyRadio.update += one.shootTheRed;
        notifyRadio.update += two.shootTheGreen;
    }
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.C))
        {
            notifyRadio.Notify();
        }
    }
}

五、好处与坏处

1.好处

1.表示层和数据逻辑层的分离,让耦合的双方都依赖于抽象,而不是依赖于具体。
2.满足“开闭原则”的要求,增加新的具体观察者无须修改原有系统代码

2.坏处

1.耗时?

发送通知只需简单地遍历列表,调用一些虚方法。只要这些方法不是特别耗时,否则这点消耗可以忽略。

2.观察者模式是同步的,你需要小心地在观察者中混合线程和锁。如果观察者试图获得被观察者拥有的锁,游戏就进入死锁了。在多线程引擎中,你最好使用事件队列来做异步通信。


六、适用场景

1.一个对象发生改变需要同时改变其它类
2.链式触发机制,疫情模拟(A传B,B传C)

1.大话设计模式
2.游戏设计模式
3.观察者模式

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 19:10:32  更:2022-04-22 19:12:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/16 21:47:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码