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);
        }
    }
}

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

原文地址:https://www.cnblogs.com/Fflyqaq/p/11716309.html