[设计模式] 行为设计模式-组合模式

组合模式是一种结构型设计模式,用于表示部分-整体的层次结构,使得客户端可以统一处理单个对象和对象组合。文章通过文件系统和游戏物品系统的例子展示了如何使用组合模式创建树形结构,允许以相同方式处理文件、文件夹及游戏中不可再分的物品(叶子节点)与可以包含其他物品的容器(如背包,武器库,容器节点)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成树形结构来表示“部分-整体”的层次结构。组合模式使得客户端可以以统一的方式处理单个对象和对象组合,从而使得在树形结构中处理对象更加简单和灵活。

组合模式包括以下角色:

  • 抽象组件(Component):定义了组合中叶子节点和容器节点的公共接口。
  • 叶子节点(Leaf):表示组合中的叶子节点对象,它没有子节点。
  • 容器节点(Composite):表示组合中的容器节点对象,它有子节点,并且可以添加、删除子节点。

组合模式的优点包括:

  • 统一处理对象和对象组合,使得客户端使用更加简单。
  • 灵活性好,可以随时增加或删除树形结构中的对象。
  • 可以方便地处理具有递归结构的数据。

简单的

假设我们要设计一个文件系统,包括文件夹和文件两种对象,其中文件夹可以包含文件和其他文件夹,而文件不能包含任何其他对象。我们可以使用组合模式来实现文件系统的设计。具体实现可以参考以下代码:


// 抽象组件
public abstract class FileSystemComponent
{
    protected string name;
    public FileSystemComponent(string name)
    {
        this.name = name;
    }

    public abstract void Print();
}

// 叶子节点:文件
public class File : FileSystemComponent
{
    public File(string name) : base(name) { }

    public override void Print()
    {
        Debug.Log("File: " + name);
    }
}

// 容器节点:文件夹
public class Folder : FileSystemComponent
{
    private List<FileSystemComponent> children = new List<FileSystemComponent>();

    public Folder(string name) : base(name) { }

    public void Add(FileSystemComponent component)
    {
        children.Add(component);
    }

    public void Remove(FileSystemComponent component)
    {
        children.Remove(component);
    }

    public override void Print()
    {
        Debug.Log("Folder: " + name);
        foreach (var component in children)
        {
            component.Print();
        }
    }
}
// 客户端代码
public class Client
{
    public void Run()
    {
        Folder root = new Folder("Root");
        Folder folder1 = new Folder("Folder1");
        Folder folder2 = new Folder("Folder2");
        File file1 = new File("File1");
        File file2 = new File("File2");
        File file3 = new File("File3");

        root.Add(folder1);
        root.Add(file1);
        folder1.Add(file2);
        folder1.Add(folder2);
        folder2.Add(file3);

        root.Print();
    }
}

更复杂的

假设有一个游戏中的物品系统,每个物品都有自己的属性,比如名称、描述、图标等,而且可能会有不同的类型,比如武器、防具、道具等。这些物品还可以放在背包中,背包本身也可以被视为一个物品,而且背包里面可能会有其他的物品,因此物品系统中的物品可以组合成一个树形结构。我们可以使用组合模式来实现这个系统。

  • 定义一个抽象类 Item,它表示物品,其中包含了物品的基本属性和方法,比如名称、描述、图标等,以及一个 AddItem 和 RemoveItem 方法,用于添加和移除子物品:
public abstract class Item
{
    public string Name { get; set; }
    public string Description { get; set; }
    public Texture2D Icon { get; set; }

    public virtual void Use() { }

    public virtual void AddItem(Item item) { }

    public virtual void RemoveItem(Item item) { }
}
  • 定义一个 Leaf 类,它表示叶子节点,也就是不可以再继续添加子物品的物品,比如道具和装备:

public class Leaf : Item
{
    public override void Use()
    {
        Debug.Log($"Using {Name}");
    }
}
  • 定义一个 Composite 类,它表示容器节点,也就是可以添加和移除子物品的物品,比如背包和武器库:

public class Composite : Item
{
    private List<Item> _items = new List<Item>();

    public override void Use()
    {
        Debug.Log($"Opening {Name}");

        foreach (var item in _items)
        {
            item.Use();
        }
    }

    public override void AddItem(Item item)
    {
        _items.Add(item);
    }

    public override void RemoveItem(Item item)
    {
        _items.Remove(item);
    }
}
  • 我们可以使用这些类来创建具体的物品,比如:

var potion = new Leaf { Name = "Potion", Description = "Restore some health" };
var sword = new Leaf { Name = "Sword", Description = "A sharp weapon" };
var armor = new Leaf { Name = "Armor", Description = "Provides some protection" };

var backpack = new Composite { Name = "Backpack", Description = "A container for items" };
backpack.AddItem(potion);
backpack.AddItem(sword);

var warehouse = new Composite { Name = "Warehouse", Description = "A storage for weapons and armors" };
warehouse.AddItem(sword);
warehouse.AddItem(armor);
  • 我们就可以像操作一个普通的物品一样操作背包和仓库了,比如:

backpack.Use(); // Output: Opening Backpack\nUsing Potion\nUsing Sword
warehouse.Use(); // Output: Opening Warehouse\nUsing Sword\nUsing Armor

warehouse.AddItem(backpack);
warehouse.Use(); // Output: Opening Warehouse\nUsing Sword\nUsing Armor\nOpening Backpack\nUsing Potion\nUsing Sword
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值