概述参考请看 参考博客
组合模式一般适用于对象的部分-整体层次分明。比如游戏中的文件夹目录结构的管理。
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、组合模式优缺点
优点
- 降低客户和组合对象的耦合度。
- 更容易向组合对象中添加新结构。
缺点
- 设计变复杂
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);
}
}
}
就可以一次添加多个名字。
当不知道参数的数量、或者要添加参数的数量很多时,可以这样使用,非常方便好用。