【unity】观察者模式

什么是观察者模式

观察者模式适用于一对多的应用场景。

有若干观察者对象,他们依赖于目标对象。当目标对象执行某操作时,所有观察者对象都会得到通知并自动执行相应操作。

举个例子:在老头环中,只要玩家喝血瓶,那么周围的敌人就会捕获到这个动作,并立刻发动进攻,让你喝多少吐多少

在上述例子里,玩家就是“目标对象”;周围所有的敌人就是“观察者对象”。玩家喝血即“目标对象执行某操作”,而所有敌人都会接收到玩家喝血的广播,然后立刻发动攻击,即“执行对应操作”。

实现手段

在说实现手段前,我还是想强调:设计模式始终是思想,具体的实现手段各不相同。

这里我使用事件来实现,你也可以让目标持有所有观察者的引用来实现等等。

定义一个抽象目标基类 BaseSubject ,其他目标类均继承自它

public abstarct class BaseSubject
{
	public event Action CallObservers;
	
	public void CallAllObservers()
	{
		CallObservers?.Invoke();
	}
}

定义一个抽象观察者基类 BaseObserver ,其他目标类均继承自它

public abstarct class BaseObserver
{
	public abstract void OnEnable();
	
	public abstract void OnDisable();
	
	public abstract void UpdateMyState();
}

某个目标类,继承自抽象目标基类

public class Subject : BaseSubject
{
	private void Start()
	{
		ChangeState();
	}
	
	public void ChangeState()
	{
		Debug.Log("Player(Subject) : Drink to heal myself.");
		CallAllObservers();
	}
}

某个观察者类,继承自抽象观察者基类

public class Observer : BaseObserver
{
	public BaseSubject subject;
	
	public override void OnEnable()
	{
		subject.CallObservers += UpdateMyState;
	}
	
	public override void OnDisable()
	{
		subject.CallObservers -= UpdateMyState;
	}
	
	public override void UpdateMyState()
	{
		Debug.Log("Enemy(Observer) : Attack right now!");
	}
}

结果如下
image

优缺点

优点:

  1. 它降低了对象之间的耦合度,方便使用。
  2. 它建立起了一套触发机制,使得不同的观察者均可以很好地响应目标的广播,方便代码拓展。
  3. 符合迪米特法则(最少知道原则)。

缺点:

  1. 当观察者数量过多时,整体响应时间较长。
  2. 观察者无从得知目标变化的具体内容,它仅仅知道目标发生了变化。
    在老头环里,部分玩家反过来利用了这一点。在玩家装填弩箭时,敌人也会“读指令”,但装填弩箭的前后摇比喝药的前后摇短很多,敌人却无从得知玩家变化的具体内容,仅仅知道玩家卖了个破绽,所以当敌人攻击时,玩家已经可以发动弹反来反击了。
  3. 当观察者与目标间有循环依赖时,可能发生循环调用致使系统崩溃。

注意:

  1. 观察者模式适用于一对多的应用场景。

小结

值得一提的是,观察者模式尤为契合解谜游戏的需求,采取该模式进行设计开发,可以很大程度上降低开发难度。

posted @ 2022-04-04 20:34  AshScops  阅读(749)  评论(0编辑  收藏  举报