zoukankan      html  css  js  c++  java
  • Unity---游戏设计模式(12)之组合模式




    概述参考请看 参考博客

    组合模式一般适用于对象的部分-整体层次分明。比如游戏中的文件夹目录结构的管理。

    1、组合模式

    树状结构图

    组合模式例子代码

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 组合模式
    /// </summary>
    public class CompositeMode : MonoBehaviour
    {
        private void Start()
        {
            INode root = new CompositeNode("Character");
    
            INode leftHand = new LeafNode("LeftHand");
            INode body = new CompositeNode("Body");
            INode rightHand = new LeafNode("RightHand");
    
            root.AddChildNode(leftHand, body, rightHand);
    
            INode leftFoot = new LeafNode("LeftFoot");
            INode rightFoot = new LeafNode("RightFoot");
    
            body.AddChildNode(leftFoot, rightFoot);
    
    
            ShowAllNode(root);
        }
    
        /// <summary>
        /// 显示节点和其所有子节点
        /// </summary>
        private void ShowAllNode(INode node)
        {
            Debug.Log(node.Name);
    
            List<INode> childNodeList = node.ChildNodeList;
            if (node == null || childNodeList == null)
            {
                return;
            }
    
            foreach (INode item in childNodeList)
            {
                ShowAllNode(item);
            }
        }
    }
    
    /// <summary>
    /// 节点抽象类
    /// </summary>
    public abstract class INode
    {
        protected string mName;
        public string Name { get { return mName; } }
        protected List<INode> mChildNodeList;
        public List<INode> ChildNodeList { get { return mChildNodeList; } }
    
        public INode(string name)
        {
            mChildNodeList = new List<INode>();
            mName = name;
        }
    
        //添加、移除、获取子节点
    
        public abstract void AddChildNode(INode node);
        //如果我们想可以一次添加多个子节点,就可以这样写
        public abstract void AddChildNode(params INode[] nodes);
    
        public abstract void RemoveChildNode(INode node);
        public abstract INode GetChildNode(int index);
    
    }
    /// <summary>
    /// 叶子节点
    /// </summary>
    public class LeafNode : INode
    {
        public LeafNode(string name)
            :base(name)
        {
        }
    
        //叶子节点无子节点
        public override void AddChildNode(INode node)
        {
            throw new System.NotImplementedException();
        }
    
        public override void AddChildNode(params INode[] nodes)
        {
            throw new System.NotImplementedException();
        }
    
        public override INode GetChildNode(int index)
        {
            throw new System.NotImplementedException();
        }
    
        public override void RemoveChildNode(INode node)
        {
            throw new System.NotImplementedException();
        }
    }
    /// <summary>
    /// 非叶子节点
    /// </summary>
    public class CompositeNode : INode
    {
        public CompositeNode(string name)
        : base(name)
        {
        }
    
        public override void AddChildNode(INode node)
        {
            mChildNodeList.Add(node);
        }
    
        public override void AddChildNode(params INode[] nodes)
        {
            foreach (INode node in nodes)
            {
                mChildNodeList.Add(node);
            }
        }
    
        public override void RemoveChildNode(INode node)
        {
            if (mChildNodeList.Contains(node) == false)
            {
                Debug.LogError(node + "在子节点中不存在");
                return;
            }
            mChildNodeList.Remove(node);
        }
    
        public override INode GetChildNode(int index)
        {
            if ((index>=0 && index<mChildNodeList.Count)==false)
            {
                Debug.LogError(index + "下标不存在");
                return null;
            }
            return mChildNodeList[index];
        }
    }
    

    2、组合模式优缺点

    优点

    1. 降低客户和组合对象的耦合度。
    2. 更容易向组合对象中添加新结构。

    缺点

    1. 设计变复杂

    3、新知识

    3.1 paramas参数

    假如我们现在需要向一个姓名集合中添加三个名字。
    正常写法是这样的:

    public class Test : MonoBehaviour
    {
        private List<string> nameList = new List<string>();
    
        private void Start()
        {
            //向list集合中添加三个名字
            AddName("张三");
            AddName("李四");
            AddName("王五");
        }
    
        private void AddName(string name)
        {
            nameList.Add(name);
        }
    }
    

    这样每当我们添加一个名字都要调用一次AddName方法

    当我们使用paramas参数时:

    public class TestMode : MonoBehaviour
    {
        private List<string> nameList = new List<string>();
    
        private void Start()
        {
            //向list集合中添加三个名字
            //AddName("张三");
            //AddName("李四");
            //AddName("王五");
    
            AddName("张三", "李四", "王五");
        }
    
        private void AddName(string name)
        {
            nameList.Add(name);
        }
        private void AddName(params string[] names)
        {
            foreach (string name in names)
            {
                nameList.Add(name);
            }
        }
    }
    

    就可以一次添加多个名字。
    当不知道参数的数量、或者要添加参数的数量很多时,可以这样使用,非常方便好用。

  • 相关阅读:
    static变量的生命周期
    关于C++的new是否会对内存初始化的问题
    行列式的本质是什么?
    C++本质:类的赋值运算符=的重载,以及深拷贝和浅拷贝
    C++拷贝(复制)构造函数详解
    随机生成指定长度字符字符串(C语言实现)
    【npm】npm install的报错
    【HTTP】http请求url参数包含+号,被解析为空格
    【ngx-ueditor】百度编辑器按下Shift键不触发contentChange事件
    【Angular】No component factory found for ×××.
  • 原文地址:https://www.cnblogs.com/Fflyqaq/p/11716309.html
Copyright © 2011-2022 走看看