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

组合模式(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

猜你喜欢

转载自blog.csdn.net/hhh314159/article/details/129376920
今日推荐