Unity-GUI设计模式-基于观察者模式的设计

在最近的项目工程中。用到了观察者模式。记录一下。

首先,展示一下观察者与被观察者的接口
被观察者IObviewer接口,定义了三个函数。
1.添加观察者 addViewer()
2.删除观察者 deleteViewer()
3.广播 broadCast()
Unity-GUI设计模式-基于观察者模式的设计

观察者IViewer接口,定义了三个函数。
1.观察者接收广播后的操作 updae()

Unity-GUI设计模式-基于观察者模式的设计

====然后,给出一个实例:
当我在场景Baseboard中定义好新的底板模型,并且存入xml中后,
1:需要返回到主场景MainScene中
2:需要在主场景的下拉框中,显示:我之前定义好的底板模型。

由于两个场景不互通。只有static静态的数据才可以被获取。
【1】首先要设置状态onRebackFromInsBaseBoard,从InsBaseBoard场景跳转回来之后设定非空。

public class DataCatche : MonoBehaviour {


    /// <summary>
    /// 我从InsBaseBoard回来之后,只有从那个场景跳转会MainScene时才会设定非空
    /// </summary>
    public static int onRebackFromInsBaseBoard = -1;

}

【2】在按下保存底板类型button后,改变onRebackFromInsBaseBoard,返回主界面

       //按下button的函数中写:
        DataCatche.onRebackFromInsBaseBoard = int.Parse(baseboard_type);
        SceneManager.LoadScene("MainScene");

============ 【被观察者】MainInitManager================
在localManger下创建delayInit,挂上MainInitManager的脚本,
【3】MainInitManager实现了,在第三帧中加载数据

(1)加载观察者列表 addViewer(CustomController.Instance);

(2)第三帧 StartCoroutine(delayInit());

(3)获取两个参数:要显示的底板的id 以及 下拉框的value。

(4)向观察者们广播

         ViewInfo info = new ViewInfo();
        info.arg1 = value+"";
        info.arg3 = reData;
        broadCast(info);

(2) 重新加载loadxml:ConfigFile.Instance.LoadXml();
因为在跳转之后,更新xml是只更新【ROM】的数据,但是动态加载的【RAM】数据(static)没有被更新。所以需要重新加载loadXML


public class MainInitManager : MonoBehaviour, IObviewer
{
    public Dropdown Baseboard_Type;
    /// <summary>
    /// 存储观察者
    /// </summary>
    List<IViewer> viewList = new List<IViewer>();
	// Use this for initialization
	void Start () {

        addViewer(CustomController.Instance);//加载观察者

        StartCoroutine(delayInit()); //第三帧
        
	}
    IEnumerator delayInit(){
        yield return new WaitForSeconds(Time.deltaTime);

        ConfigFile.Instance.LoadXml();//重新加载loadxml

        List<string> Baseboard_tempList = new List<string>();

        if (DataCatche.onRebackFromInsBaseBoard != null && DataCatche.onRebackFromInsBaseBoard!=-1 )
        {
            Debug.Log(DataCatche.onRebackFromInsBaseBoard);
            //从存有baseboard的字典里面获取id对应属性

            foreach (BaseboardData element in BaseboardData.Baseboard_dic.Values)
            {
                Baseboard_tempList.Add(element.id);
            }

            BaseboardData reData ;
            int value = getDdValue(DataCatche.onRebackFromInsBaseBoard + "", Baseboard_tempList, out reData);
            //value 是返回的option的value“0,1,2,3”
            //reData是字典中baseBoard_id对应的BaseboardData

            ViewInfo info = new ViewInfo();
            info.arg1 = value+"";
            info.arg3 = reData;


            broadCast(info);

        }
    }

	void Update () {
		
	}
    //调用接口的函数 
        public void addViewer(IViewer view)
    {
        viewList.Add(view);
    }

    public void deleteViewer(IViewer view)
    {
        viewList.Remove(view);
    }

    public void broadCast(ViewInfo info)
    {
        foreach (IViewer view in viewList)
        {
            view.update(info);
        }
    }
}

getDdValue函数:获取value 以及BaseboardData


//获取value 以及BaseboardData
    public static int getDdValue(string baseBoard_id, List<string> opTions, out BaseboardData data)
    {

        data = BaseboardData.Baseboard_dic[baseBoard_id];

        for(int i =0;i<opTions.Count;i++)
        {
          if (opTions[i] == baseBoard_id)
            {
                return i;
            }
        }
       
        return 0;

        
    }

onRebackOption函数:更新下拉框的value

    public void onRebackOption(BaseboardData _reData, int _value)
    {

        MainSceneCustomPage page = (MainSceneCustomPage)MainScenePage.stackDic["MainSceneCustomPage"];

        //找到下拉框资源

        Baseboard_Type = page.baseboard_Dropdown;
        //在存列表的字典中,找到在config文件中的“下拉框”子节点对应列表;

        List<string> Baseboard_tempList = new List<string>();
        Baseboard_Type.value = _value;


     
     

   


       




    }
	

============ 【观察者】CustomController================ ```
加载onClickCustom()
接收广播的参数
更新下拉框的value

 public void update(ViewInfo info)
    {

        MainFuncPage.Instance.onClickCustom();
        int value = int.Parse(info.arg1);


        BaseboardData data = (BaseboardData)info.arg3;
        Debug.Log("接受的参数:" + value);
        //
        setDropDownView(page.baseboard_Dropdown, value+1);




    }
        public void setDropDownView(Dropdown dn,int value)
    {
        dn.value = value;
    
    }