中介者模式

来源:互联网 发布:淘宝图片怎么拍 编辑:程序博客网 时间:2024/06/04 22:47

顾名思义,当多个对象需要互相调用对方的时候,我们可以使用一个中介对象来封装这种行为。比如班上的同学要问对方要qq号,如果是两两问对方要,就是这种网状结构。


我们建一个qq群,同学想要别人的qq号只要在群里找就好了,这就是中介者模式。


中介者模式的好处(也可能是坏处):

当我们想要改变各对象交互方式的时候,更改中介类就好了,这样降低了耦合性,使代码结构更清晰,但是一旦中介类更改,对所有用到中介类的对象都会有影响。

Unity举例:

比如我们要实现主角和npc如果距离小于10就掉血。不用中介者模式是这样写的:

public  class  NPC:MonoBehaviour{public  void ReduceBlood(){}public  void CaculateBlood(Transform  charactor){float tmpDistance = Vector3.Distance (transform.position,charactor.transform.position);if (tmpDistance < 10) {ReduceBlood ();}}}public  class  Charactor:MonoBehaviour{public  void ReduceBlood(){}public  void  CaculateBlood(Transform NPC){float tmpDistance = Vector3.Distance (transform.position,NPC.transform.position);if (tmpDistance < 10) {ReduceBlood ();}}}


使用中介者模式:

using UnityEngine;using System.Collections;//中介者模式,在角色前方距离5,左右距离3米的范围内角色可以攻击public class ActorBase:MonoBehaviour{public virtual void ReduceBlood(){} }public class Character:ActorBase{public override void ReduceBlood(){}}public class Enemy:ActorBase{public override void ReduceBlood(){}}public class AttackAgent: MonoBehaviour{/// <summary>/// Caculates the distance./// </summary>/// <param name="attacked">Attacked.</param>/// <param name="attack">Attack.</param>public  void  CaculateDistance(ActorBase  attacked, ActorBase attack){float tmpDistance = Vector3.Distance(attacked.transform.position, attack.transform.position);if (tmpDistance < 10.0f) {attacked.ReduceBlood ();}}/// <summary>/// 计算是否在攻击范围内/// </summary>/// <returns><c>true</c>, if attack was caculated, <c>false</c> otherwise.</returns>/// <param name="attack">Attack.攻击者</param>/// <param name="attacked">Attacked.被攻击者</param>public bool CaculateAttack(GameObject attack, GameObject attacked){//攻击者和被攻击者之间的向量,attack.transform.right即(1, 0, 0),attack.transform.forward即(0, 0, 1)Vector3 vec = attacked.transform.position - attack.transform.position;float  rightDis = Vector3.Dot(vec, attack.transform.right.normalized);//点乘上攻击者右方向向量,也就是求出右边的距离float  leftDis = Vector3.Dot(vec, -attack.transform.right.normalized);//左边的距离float forwordDis = Vector3.Dot(vec, attack.transform.forward.normalized);//与攻击者前方向量点乘,若小于0说明在其后方if (rightDis<=3 && leftDis<=3 && forwordDis>=0 && forwordDis<=5){return true;}return false;}}

0 0
原创粉丝点击