设计模式——12 复合模式(模式的模式)

本文介绍了一个结合多种设计模式的复合模式实例,包括适配器模式、装饰者模式、工厂模式、组合模式、迭代器模式及观察者模式。通过具体代码示例展示了如何使用这些模式来创建和管理鸭子对象。

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

复合模式

综述

  • 模式通常被一起使用,并被组合在同一设计解决方案中
  • 复合模式在一个解决方案中结合两个或多个模式,以解决一般或重复发生的问题

类图

这里写图片描述

复合模式示例

创建多个鸭子对象

public interface IQuackable 
{
    void Quack();
}
public class BlueheadDuck : IQuackable
{
    public void Quack()
    {
        Console.WriteLine("鸭子叫");
    }
}

剩余3个鸭子对象省略

使用适配器模式创建一个会鹅叫的鸭子

/// <summary>
///
/// </summary>
public class Goose
{
    public void Honk() {
        Console.WriteLine("鹅在叫...");
    }
}
/// <summary>
/// 使用适配器模式创建一个会鹅叫的鸭子。
/// </summary>
public class GooseAdapter : IQuackable
{
    Goose goose;

    public GooseAdapter(Goose goose)
    {
        this.goose = goose;
    }

    public void Quack()
    {
        goose.Honk();
    }
}

使用装饰着模式装饰为”能够叫”对象

/// <summary>
/// QuackCounter类为装饰者
/// </summary>
public class QuackCounter : IQuackable
{
    IQuackable _duck;
    private static int _numberOfQuacks;

    public static int NumberOfQuacks
    {
        get
        {
            return _numberOfQuacks;
        }

        set
        {
            _numberOfQuacks = value;
        }
    }

    public QuackCounter(IQuackable duck)
    {
        _duck = duck;
    }

    public void Quack()
    {
        _duck.Quack();
        NumberOfQuacks++;
    }

}

使用工厂模式代替对象的创建

/// <summary>
/// 抽象工厂类
/// </summary>
public abstract class AbstractDuckFactory
{
    public abstract IQuackable CreateBlueheadDuck();
    public abstract IQuackable CreatePinkheadDuck();
    public abstract IQuackable CreateDuckCall();
    public abstract IQuackable CreateRubberDuck();
}
/// <summary>
/// 使用工厂,创建没有被装饰的鸭子
/// </summary>
public class DuckFactory : AbstractDuckFactory
{
    //使用工厂,创建没有被装饰的鸭子
    public override IQuackable CreateBlueheadDuck()
    {
        return new BlueheadDuck();
    }

    //使用工厂,创建没有被装饰的鸭子
    public override IQuackable CreateDuckCall()
    {
        return new DuckCall();
    }

    //使用工厂,创建没有被装饰的鸭子
    public override IQuackable CreatePinkheadDuck()
    {
        return new PinkheadDuck();
    }

    //使用工厂,创建没有被装饰的鸭子
    public override IQuackable CreateRubberDuck()
    {
        return new RubberDuck();
    }
}
/// <summary>
/// 使用工厂和装饰者,创建被装饰的鸭子
/// </summary>
public class CountingDuckFactory : AbstractDuckFactory
{
    //使用装饰者,创建被装饰的鸭子
    public override IQuackable CreateBlueheadDuck()
    {
         return new QuackCounter(new BlueheadDuck());
    }
    //使用装饰者,创建被装饰的鸭子
    public override IQuackable CreateDuckCall()
    {
        return new QuackCounter(new DuckCall());
    }
    //使用装饰者,创建被装饰的鸭子
    public override IQuackable CreatePinkheadDuck()
    {
        return new QuackCounter(new PinkheadDuck());
    }
    //使用装饰者,创建被装饰的鸭子
    public override IQuackable CreateRubberDuck()
    {
        return new QuackCounter(new RubberDuck());
    }
}

使用组合和迭代器模式

/// <summary>
/// 迭代器模式
/// </summary>
public class FlockEnum : IEnumerator
{
    IQuackable[] quackers;
    int index = -1;

    public IQuackable Current
        {
            get
            {
                try
                {
                    return quackers[index];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new IndexOutOfRangeException();
                }
            }
        }

    object IEnumerator.Current
    {
        get
        {
            return Current;
        }
    }

    public FlockEnum(IQuackable[] quackers)
    {
        this.quackers = quackers;
    }

    public bool MoveNext()
    {
        index++;
        return (index < quackers.Count());
        throw new NotImplementedException();
    }

    public void Reset()
    {
        index = -1;
    }
}
/// <summary>
/// 使用组合模式和迭代器模式
/// </summary>
public class Flock : IQuackable, IEnumerable
{
    IQuackable[] quackers;

    public Flock(IQuackable[] quackers)
    {
        this.quackers = quackers;
    }

    public FlockEnum GetEnumerator()
    {
        return new FlockEnum(quackers);
    }

    public void Quack()
    {
        IEnumerator items = quackers.GetEnumerator();

        while (items.MoveNext())
        {
            IQuackable quacker = (IQuackable)items.Current;
            quacker.Quack();
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return (IEnumerator)GetEnumerator();
    }
}

使用观察者模式

public class IQuackableObservable : IObservable<IQuackable>
{
    private List<IObserver<IQuackable>> observers;

    public IQuackableObservable()
    {
        observers = new List<IObserver<IQuackable>>();
    }

    public IDisposable Subscribe(IObserver<IQuackable> observer)
        {
            if (!observers.Contains(observer))
            {
                observers.Add(observer);
            }
            return new Unsubscriber(observers, observer);
        }

    private class Unsubscriber : IDisposable
    {
        private List<IObserver<IQuackable>> _observers;
        private IObserver<IQuackable> _observer;

        public Unsubscriber(List<IObserver<IQuackable>> observers, IObserver<IQuackable> observer)
        {
            this._observers = observers;
            this._observer = observer;
        }

        public void Dispose()
        {
            if (_observer != null && _observers.Contains(_observer))
                _observers.Remove(_observer);
        }
    }

    public void Notify(IQuackable value)
    {
        IEnumerator items = observers.GetEnumerator();

        while (items.MoveNext())
        {
            IObserver<IQuackable> item = (IObserver<IQuackable>)items.Current;
            item.OnNext(value);
            //item.OnNext();
        }



    }
}
public class IQuackableObserver : IObserver<IQuackable>
{
    private IDisposable unsubscriber;


    //通知提供者:某观察者将要接收通知。
    public virtual void Subscribe(IObservable<IQuackable> provider)
    {
        if (provider != null)
        {
            unsubscriber = provider.Subscribe(this);
        }
    }
    public void OnCompleted()
    {
        Console.WriteLine("观察员:OnCompleted");
        this.Unsubscribe();
    }

    public void OnError(Exception error)
    {
        Console.WriteLine("观察员:OnError");
    }

    public void OnNext(IQuackable value)
    {
        //调用鸭子叫
        value.Quack();
    }

    //某观察者将要取消接收通知。
    public virtual void Unsubscribe()
    {
        unsubscriber.Dispose();
    }
}

结果

DuckSimuLator duckSimuLator = new DuckSimuLator();
AbstractDuckFactory duckFactory = new CountingDuckFactory();
duckSimuLator.Simnulate(duckFactory);
internal class DuckSimuLator
{
    internal void Simnulate(AbstractDuckFactory duckFactory)
    {
        //1.使用工厂创建鸭子
        //2.使用装饰者,创建被装饰的鸭子
        IQuackable blueheadDuck = duckFactory.CreateBlueheadDuck();
        IQuackable pinkheadDuck = duckFactory.CreatePinkheadDuck();
        IQuackable duckCall = duckFactory.CreateDuckCall();
        IQuackable rubberDuck = duckFactory.CreateRubberDuck();
        //使用适配器模式创建一个会鹅叫的鸭子。
        IQuackable gooseDuck = new GooseAdapter(new Goose());
        IQuackable[] quacks = { blueheadDuck, pinkheadDuck, duckCall, rubberDuck, gooseDuck };
        //使用组合模式和迭代器模式
        Flock flockOfDucks = new Flock(quacks);

        Console.WriteLine("------鸭子模拟器-------");
        Simnulate(flockOfDucks);

        Console.WriteLine("------观察开始-------");
        //使用观察者模式
        IQuackableObservable provider = new IQuackableObservable();
        IQuackableObserver reporter1 = new IQuackableObserver();
        reporter1.Subscribe(provider);
        provider.Notify(duckFactory.CreateRubberDuck());
        Console.WriteLine("------观察结束-------");

        Console.WriteLine("鸭子叫的次数为:" + QuackCounter.NumberOfQuacks);
    }

    void Simnulate(IQuackable duck)
    {
        duck.Quack();
    }
}

输出

------鸭子模拟器-------
鸭子叫
鸭子叫
鸭鸣器在叫...
橡皮鸭在叫...
鹅在叫...
------观察开始-------
橡皮鸭在叫...
------观察结束-------
鸭子叫的次数为:5

MVC

P419-452

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr___Ray

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值