Unity 设计模式之 观察者模式的实例介绍
1、概述:
有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己
2、解决的问题:
将一个系统分割成一个一些类相互协作的类有一个不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。
3、模式中的角色:
3.1 抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
3.2 具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
3.3 抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
3.4 具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
4、模式解读:
4.1 观察者模式的类图

5、 4.2 引申模式:事件实现的类图

1、打开Unity,新建一个空工程,具体如下图

2、在工程中,新建几个脚本,然后双击打开,具体如下图

3、脚本的具体代码和代码内容如下图






4、ISubject 脚本具体内容如下:
/// <summary>
/// 抽象主题
/// </summary>
public interface ISubject {
void Notify();
}
5、Customer 脚本具体内容如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using System;
/// <summary>
/// 声明委托
/// </summary>
public delegate void CustomerEventHandler();
/// <summary>
/// 具体主题
/// </summary>
public class Customer : ISubject {
private string customerState;
public string CustomerState {
get {
return customerState;
}
set {
customerState = value;
}
}
// 声明一个委托事件,类型为 CustomerEventHandler
public event CustomerEventHandler Update;
public void Notify ()
{
if (Update != null){
Console.WriteLine ("通知事件");
// 使用事件来通知给订阅者
Update ();
}
}
}
6、Accountant 脚本具体内容如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
/// <summary>
/// 财务,已经不需要实现抽象的观察者类,并且不用引用具体的主题
/// </summary>
public class Accountant {
private string accountState;
public Accountant(){
}
/// <summary>
/// 开发票
/// </summary>
public void GiveInvoice() {
Debug.Log ("会计师,来开发发票");
accountState = "已开发票";
}
}
7、Cashier 脚本具体内容如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
/// <summary>
/// 出纳,已经不需要实现抽象的观察者类,并且不用引用具体的主题
/// </summary>
public class Cashier {
private string cashierState;
public Cashier() {}
/// <summary>
/// 记账
/// </summary>
public void Recoded() {
Debug.Log ("出纳员,来登记入账");
cashierState = "已入账";
}
}
8、Dilliveryman 脚本具体内容如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
/// <summary>
/// 配送员,已经不需要实现抽象的观察者类,并且不用引用具体的主题
/// </summary>
public class Dilliveryman {
private string dilliverymanState;
public Dilliveryman() {}
/// <summary>
/// 发货
/// </summary>
public void Dilliver() {
Debug.Log ("配送员,来发货");
dilliverymanState = "已发货";
}
}
9、Test 脚本具体内容如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Test : MonoBehaviour {
Customer subject;
// Use this for initialization
void Start () {
//观察对象
subject = new Customer ();
//观察者
Accountant accountant = new Accountant ();
Cashier cashier = new Cashier ();
Dilliveryman dilliveryman = new Dilliveryman ();
//注册事件
subject.Update += accountant.GiveInvoice;
subject.Update += cashier.Recoded;
subject.Update += dilliveryman.Dilliver;
}
// Update is called once per frame
void Update () {
//状态改变,通知观察者
if (Input.GetKeyDown (KeyCode.A)) {
Debug.Log ("客户已付款");
subject.CustomerState = "客户已付款";
subject.Notify ();
}
}
}
10、脚本编译正确,回到Unity界面,在场景中新建一个 GameObject,并把 Test 脚本赋给 GameObject,具体如下图

11、运行场景,然后 按下 A 键,控制台 Console 打印如下图

12、到此,《Unity 设计模式之 观察者模式的实例介绍》讲解结束,谢谢