用Unity写设计模式-组合模式

组合模式介绍

  • 定义

将对象组合成树形结构以表示“部分-整体”的层次结构,
使得用户对单个对象和组合对象的使用具有一致性。

组合模式

  • Component 组件(DrawingElement)

在组合中声明对象的接口。
为所有类的公共接口实现默认行为,视情况而定。
声明一个用于访问和管理其子组件的接口。
(可选)定义了一个接口,用于在递归结构中访问组件的父组件,并在合适的情况下实现它。

  • Leaf 叶(PrimitiveElement)

表示合成中的叶子对象。 一片叶子没有孩子。
为组合中的原始对象定义行为。

  • Composite 复合(CompositeElement)

定义有子组件的行为。
存储子组件。
在组件接口中实现子操作。

  • Client 客户机(CompositeApp)

通过Component接口操作组合中的对象。

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class CompositeStructure : MonoBehaviour
{
	void Start ( )
    {
        // Create a tree structure
        Composite root = new Composite("root");
        root.Add(new Leaf("Leaf A"));
        root.Add(new Leaf("Leaf B"));

        Composite comp = new Composite("Composite X");
        comp.Add(new Leaf("Leaf XA"));
        comp.Add(new Leaf("Leaf XB"));

        root.Add(comp);
        root.Add(new Leaf("Leaf C"));

        // Add and remove a leaf
        Leaf leaf = new Leaf("Leaf D");
        root.Add(leaf);
        root.Remove(leaf);

        // Recursively display tree
        root.Display(1);

    }
}

/// <summary>
/// The 'Component' abstract class
/// </summary>
abstract class Component
{
    protected string name;

    // Constructor
    public Component(string name)
    {
        this.name = name;
    }

    public abstract void Add(Component c);
    public abstract void Remove(Component c);
    public abstract void Display(int depth);
}

/// <summary>
/// The 'Composite' class
/// </summary>
class Composite : Component
{
    private List<Component> _children = new List<Component>();

    // Constructor
    public Composite(string name)
      : base(name)
    {
    }

    public override void Add(Component component)
    {
        _children.Add(component);
    }

    public override void Remove(Component component)
    {
        _children.Remove(component);
    }

    public override void Display(int depth)
    {
        Debug.Log(new String('-', depth) + name);

        // Recursively display child nodes
        foreach (Component component in _children)
        {
            component.Display(depth + 2);
        }
    }
}

/// <summary>
/// The 'Leaf' class
/// </summary>
class Leaf : Component
{
    // Constructor
    public Leaf(string name)
      : base(name)
    {
    }

    public override void Add(Component c)
    {
        Debug.Log("Cannot add to a leaf");
    }

    public override void Remove(Component c)
    {
        Debug.Log("Cannot remove from a leaf");
    }

    public override void Display(int depth)
    {
        Debug.Log(new String('-', depth) + name);
    }
}

在这里插入图片描述
在这里插入图片描述

组合模式案例1

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;


//这个真实世界的代码演示了Composite模式,
//用于构建一个由原始节点(线、圆等)和Composite组成的
//图形树结构节点(组成更复杂元素的绘图元素组)。

namespace CompositePatternExample1
{
    public class CompositePatternExample1 : MonoBehaviour
    {
        void Start()
        {
            // Create a tree structure 
            CompositeElement root =
              new CompositeElement("Picture");
            root.Add(new PrimitiveElement("Red Line"));
            root.Add(new PrimitiveElement("Blue Circle"));
            root.Add(new PrimitiveElement("Green Box"));

            // Create a branch
            CompositeElement comp =
              new CompositeElement("Two Circles");
            comp.Add(new PrimitiveElement("Black Circle"));
            comp.Add(new PrimitiveElement("White Circle"));
            root.Add(comp);

            // Add and remove a PrimitiveElement
            PrimitiveElement pe =
              new PrimitiveElement("Yellow Line");
            root.Add(pe);
            root.Remove(pe);

            // Recursively display nodes
            root.Display(1);

        }
    }


    /// <summary>
    /// The 'Component' Treenode
    /// </summary>
    abstract class DrawingElement
    {
        protected string _name;

        // Constructor
        public DrawingElement(string name)
        {
            this._name = name;
        }

        public abstract void Add(DrawingElement d);
        public abstract void Remove(DrawingElement d);
        public abstract void Display(int indent);
    }

    /// <summary>
    /// The 'Leaf' class
    /// </summary>
    class PrimitiveElement : DrawingElement
    {
        // Constructor
        public PrimitiveElement(string name)
          : base(name)
        {
        }

        public override void Add(DrawingElement c)
        {
            Debug.Log("Cannot add to a PrimitiveElement");
        }

        public override void Remove(DrawingElement c)
        {
            Debug.Log("Cannot remove from a PrimitiveElement");
        }

        public override void Display(int indent)
        {
            Debug.Log(new String('-', indent) + " " + _name);
        }
    }

    /// <summary>
    /// The 'Composite' class
    /// </summary>
    class CompositeElement : DrawingElement
    {
        private List<DrawingElement> elements =
          new List<DrawingElement>();

        // Constructor
        public CompositeElement(string name)
          : base(name)
        {
        }

        public override void Add(DrawingElement d)
        {
            elements.Add(d);
        }

        public override void Remove(DrawingElement d)
        {
            elements.Remove(d);
        }

        public override void Display(int indent)
        {
            Debug.Log(new String('-', indent) +
              "+ " + _name);

            // Display each child element on this node
            foreach (DrawingElement d in elements)
            {
                d.Display(indent + 2);
            }
        }
    }
}

组合模式案例2

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace CompositePatternExample2
{
    public class CompositePatternExample2 : MonoBehaviour
    {
        void Start()
        {
            SongComponent industrialMusic = new SongGroup("Industrial Music", "Industrial music is a genre of experimental music that draws on transgressive and provocative themes. The term was coined in the mid-1970s with the founding of Industrial Records by Genesis P-Orridge of Throbbing Gristle and Monte Cazazza; on Throbbing Gristle's debut album The Second Annual Report, they coined the slogan \"industrial music for industrial people\".");
            SongComponent heavyMetalMusic = new SongGroup("Heavy Metal Music", "Heavy metal is a genre of rock music[1] that developed in the late 1960s and early 1970s, largely in the United States and the United Kingdom.[2] With roots in blues rock and psychedelic rock,[3] the bands that created heavy metal developed a thick, massive sound, characterized by highly amplified distortion, extended guitar solos, emphatic beats, and overall loudness. Heavy metal lyrics and performance styles are often associated with masculinity, aggression, and machismo.[3]");
            SongComponent dubstepMusic = new SongGroup("Dubstep Music", "Dubstep /ˈdʌbstɛp/ is a genre of electronic dance music that originated in South London, England. It emerged in the late 1990s as a development within a lineage of related styles such as 2-step garage, broken beat, drum and bass, jungle, dub and reggae.[2] In the UK the origins of the genre can be traced back to the growth of the Jamaican sound system party scene in the early 1980s.[2][3] The music generally features syncopated drum and percussion patterns with bass lines that contain prominent sub bass frequencies.");

            SongComponent everySong = new SongGroup("Song List", "Every Song available");
            everySong.Add(industrialMusic);
            industrialMusic.Add(new Song("Head Like a Hole", "NIN", 1990));
            industrialMusic.Add(new Song("headhunter", "front 242", 1988));
            // see: here we are adding a group into a group and build up the hierarchy!!!!
            industrialMusic.Add(dubstepMusic);
            dubstepMusic.Add(new Song("Centipede", "Knife Party", 2012));
            dubstepMusic.Add(new Song("Tetris", "doctor P", 2011));

            everySong.Add(heavyMetalMusic);
            heavyMetalMusic.Add(new Song("War Pigs", "Black Sabath", 1970));
            heavyMetalMusic.Add(new Song("Ace of spades", "Motorhead", 1980));

            DiscJockey crazyLarry = new DiscJockey(everySong);
            crazyLarry.GetSongList();
        }
    }


    public abstract class SongComponent
    {
        public virtual void Add(SongComponent component) { }
        public virtual void Remove(SongComponent component) { }
        public virtual SongComponent Get(int index) { return null; }

        public abstract void DisplaySongInformation();
    }


    public class SongGroup : SongComponent
    {
        protected List<SongComponent> components = new List<SongComponent>();
        public string groupName { get; protected set; }
        public string groupDescription { get; protected set; }

        public SongGroup(string name, string description)
        {
            this.groupName = name;
            this.groupDescription = description;
        }

        public override void Add(SongComponent component)
        {
            components.Add(component);
        }

        public override void Remove(SongComponent component)
        {
            components.Remove(component);
        }

        public override SongComponent Get(int i)
        {
            return components[i];
        }

        public override void DisplaySongInformation()
        {
            Debug.Log(groupName + " - " + groupDescription);

            // now iterate through all groups inside this group
            IEnumerator iterator = components.GetEnumerator();
            while (iterator.MoveNext())
            {
                SongComponent songComponent = (SongComponent)iterator.Current;
                songComponent.DisplaySongInformation();
            }
        }
    }

    public class Song : SongComponent
    {
        public string songName { get; protected set; }
        public string bandName { get; protected set; }
        public int releaseYear { get; protected set; }

        public Song(string name, string band, int year)
        {
            this.songName = name;
            this.bandName = band;
            this.releaseYear = year;
        }

        public override void DisplaySongInformation()
        {
            Debug.Log("Song of " + songName + " - " + bandName + " : " + releaseYear);
        }
    }


    public class DiscJockey
    {
        protected SongComponent songList;

        public DiscJockey(SongComponent songList)
        {
            this.songList = songList;
        }

        public void GetSongList()
        {
            songList.DisplaySongInformation();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值