C#观察者模式


观察者模式实现

C#中提供了委托(delegate)机制,实现观察者的通知机制。而在许多大型运用中,大量的事件通知而导致大量的委托事件,对于代码的可维护性和可阅读性来说都是沉重的伤害。谁也不愿意看到大段大段的委托定义。以及每次通知都需要调用不同的委托,引发的烦恼。

这里使用C#的Action类,模拟Cpp11的std::bind方法,来完成对观察者模式的实现。有效避免大量委托的出现,从而使代码更简洁,更加的内聚,模块间耦合度更低。

这里给出观察者模式的泛型定义

public abstract class ISubject<Observer>
    {
        public ISubject() { }
        ~ISubject()
        {
            m_dictObserver.Clear();
            m_setObserver.Clear();
        }

        public enum Level_Observer
        {
            Level1,
            Level2,
            Level3,
            Level4,
            Level5,
            Level6,
            Level7,
            Level8,
            Level9,
        }

        public void Regist(Observer observer, Level_Observer lvl = Level_Observer.Level5)
        {
            if (!m_setObserver.Add(observer)) return;
            if(m_dictObserver.ContainsKey(lvl))
            {
                m_dictObserver[lvl].Add(observer);
            }
            else
            {
                m_dictObserver.Add(lvl, new HashSet<Observer>());
                m_dictObserver[lvl].Add(observer);
            }
            m_dictObserver = m_dictObserver.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value);
        }

        public void UnRegist(Observer observer)
        {
            if (m_dictObserver.Count == 0) return;
            foreach(var pair in m_dictObserver)
            {
                if(pair.Value.Remove(observer))
                {
                    m_setObserver.Remove(observer);
                    break;
                }
            }
        }

        protected void NotifyEvent(Action<Observer> action)
        {
            foreach(var pair in m_dictObserver)
            {
                foreach(var obs in pair.Value)
                {
                    action(obs);
                }
            }
        }

        private Dictionary<Level_Observer, HashSet<Observer>> m_dictObserver = new Dictionary<Level_Observer, HashSet<Observer>>();
        private HashSet<Observer> m_setObserver = new HashSet<Observer>();
    }

使用实例

public interface ObeserverTest
    {
        void Print();
        void PrintX(int x);
    }
    public class A : ISubject<ObeserverTest>
    {
        public A() {}
        
        public void Notify()
        {
            NotifyEvent((ObeserverTest x)=> { x.Print(); });
            NotifyEvent((ObeserverTest x) => { x.PrintX(222); });
        }
    }

    public class B : ObeserverTest
    {
        public B() {}
        
        public virtual void Print()
        {
            Console.WriteLine("Print()");
        }

        public virtual void PrintX(int x)
        {
            Console.WriteLine("Print({0})", x);
        }
    }

    public class C : ObeserverTest
    {
        public C() { }

        public virtual void Print()
        {
            Console.WriteLine("C Print()");
        }

        public virtual void PrintX(int x)
        {
            Console.WriteLine("C Print({0})", x);
        }
    }

    class Program {
		static void Main(string[] args) {
            A a = new A();
            B b = new B();
            C c = new C();
            a.Regist(b);
            a.Regist(b);
            a.Regist(c, A.Level_Observer.Level2);
            a.Notify();
            a.UnRegist(b);
            Console.ReadLine();
		}
	}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值