艾伟_转载:把委托说透(4):委托与设计模式-阿里云开发者社区

开发者社区> 狼人2007> 正文

艾伟_转载:把委托说透(4):委托与设计模式

简介: 委托与很多设计模式都有着千丝万缕的联系,在前面的随笔中已经介绍了委托与策略模式的联系,本节主要来讨论委托与其他两个模式:观察者模式和模板方法模式。 委托与观察者模式 在.NET中,很多设计模式得到了广泛应用,如foreach关键字实现了迭代器模式。
+关注继续查看

委托与很多设计模式都有着千丝万缕的联系,在前面的随笔中已经介绍了委托与策略模式的联系,本节主要来讨论委托与其他两个模式:观察者模式和模板方法模式。

委托与观察者模式

在.NET中,很多设计模式得到了广泛应用,如foreach关键字实现了迭代器模式。同样的,.NET中也内置了观察者模式的实现方式,这种方式就是委托。

观察者模式的一般实现

网上可以找到很多资料介绍观察者模式的实现,我这里介绍一种简单的退化后的观察者模式,即Subject类为具体类,在其之上不再进行抽象。

public class Subject
{
    private List<Observer> observers = new List<Observer>();
    private string state;
    public string State
    {
        set
        {
            state = value;
            NotifyObservers();
        }
        get { return state; }
    }
    public void RegisterObserver(Observer ob)
    {
        observers.Add(ob);
    }
    public void RemoveObserver(Observer ob)
    {
        observers.Remove(ob);
    }
    public void NotifyObservers()
    {
        foreach (Observer ob in observers)
            ob.Update(this);
    }
}
public abstract class Observer
{
    public abstract void Update(Subject subject);
}
public class ConsoleObserver : Observer
{
    public ConsoleObserver(Subject subject)
    {
        subject.RegisterObserver(this);
    }
    public override void Update(Subject subject)
    {
        Console.WriteLine("Subject has changed its state : " + subject.State);
    }
}

调用的方法很简单:

Subject subject = new Subject();
Observer observer = new ConsoleObserver(subject);
subject.State = "Kirin Yao";

Subject类维护一个列表,负责观察者的注册和移除。当其状态发生改变时,就调用NotifyObservers方法通知各个观察者。

观察者模式的委托实现

在.NET中,使用委托可以更简单更优雅地实现观察者模式。在上一篇随笔中,最后的示例其实就是一个观察者模式。MainForm为Subject,SubForm为Observer。当MainForm的状态发生改变时(即点击“传值”按钮时),SubForm作为观察者响应来自MainForm的变化。

与上例对应的,用委托实现的观察者模式的代码大致如下:

namespace DelegateSample
{
    class UpdateEventArgs : EventArgs { }
    class Subject
    {
        private string state;
        public string State 
        {
            get { return state; }
            set 
            {
                state = value;
                OnUpdate(new UpdateEventArgs());
            }
        }
        public event EventHandler<UpdateEventArgs> Update;
        public void ChangeState(string state)
        {
            this.State = state;
            OnUpdate(new UpdateEventArgs());
        }
        private void OnUpdate(UpdateEventArgs e)
        {
            EventHandler<UpdateEventArgs> handler = Update;
            if (handler != null)
                Update(this, e);
        }
    }
    abstract class Observer
    {
        public Subject Subject { get; set; }
        public Observer(Subject subject)
        {
            this.Subject = subject;
            this.Subject.Update += new EventHandler<UpdateEventArgs>(Subject_Update);
        }
        protected abstract void Subject_Update(object sender, UpdateEventArgs e);
    }
    class ConsoleObserver : Observer
    {
        public ConsoleObserver(Subject subject) : base(subject) { }
        protected override void Subject_Update(object sender, UpdateEventArgs e)
        {
            Subject subject = sender as Subject;
            if (subject != null)
                Console.WriteLine("Subject has changed its state : " + subject.State);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Subject subject = new Subject();
            Observer ob = new ConsoleObserver(subject);
            subject.State = "Kirin Yao";
            Console.ReadLine();
        }
    }
}

相比传统的观察者模式的实现方式(在Subject中维护一个Observer列表),使用委托避免了Subject与Observer之间的双向引用,Subject作为主题类,对观察者毫无所知,降低了耦合性,语法上也更加优雅。

委托与模板方法模式

模板方法模式封装了一段通用的逻辑,将逻辑中的特定部分交给子类实现。

public abstract class AbstractClass
{
    public void Arithmetic()
    {
        SubArithmeticA();
        SubArithmeticB();
        SubArithmeticC();
    }
    protected abstract void SubArithmeticA();
    protected abstract void SubArithmeticB();
    protected abstract void SubArithmeticC();
}
public class ConcreteClass : AbstractClass
{
    protected override void SubArithmeticA()
    {
        //...
    }
    protected override void SubArithmeticB()
    {
        //...
    }
    protected override void SubArithmeticC()
    {
        //...
    }
}

然而这种继承方式的模板方法耦合度较高,特别是如果逻辑与其外部实现没有必然的从属关系的时候,用传统的模板方法就显得不那么合适了。

在某种程度上,委托可以看做是一个轻量级的模板方法实现方式,它将逻辑中的特定部分转交给注册到委托的方法来实现。从而替代了继承方式的模板方法模式中,在子类中实现特定逻辑的方式。

public delegate void SubArithmetic();
public class ConcreteClass
{
    public void Arithmetic()
    {
        if (SubArithmetic != null)
            SubArithmetic();
    }
    public SubArithmetic SubArithmetic { get; set; }
}

而SubArithmetic的实现交给外部:

ConcreteClass concrete = new ConcreteClass();
concrete.SubArithmetic = Program.SomeMethod;
concrete.Arithmetic();

咋一看在客户端中编写委托的方法似乎还略显麻烦,但值得注意的是,匿名方法和Lambda表达式为我们提供了更加简便的委托语法。在函数式编程日益盛行的今天,我们应该为.NET提供的这种语言特性而感到庆幸。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
艾伟_转载:把委托说透(4):委托与设计模式
委托与很多设计模式都有着千丝万缕的联系,在前面的随笔中已经介绍了委托与策略模式的联系,本节主要来讨论委托与其他两个模式:观察者模式和模板方法模式。 委托与观察者模式 在.NET中,很多设计模式得到了广泛应用,如foreach关键字实现了迭代器模式。
847 0
iOS开发那些事-iOS常用设计模式–委托模式
<p>对于iOS开发,举例Cocoa框架下的几个设计模式为大家分析。当然,Cocoa框架下关于设计模式的内容远远不止这些,我们选择了常用的几种:单例模式、委托模式、观察者模式、MVC模式。</p> <p><span id="more-129"></span></p> <p>委托模式</p> <p>委托模式从GoF 设计装饰(Decorator)、适配器(Adapter)和模板方法(T
1078 0
iOS设计模式——委托(delegate)
委托(delegate)也叫代理是iOS开发中常用的设计模式。我们借助于protocol(参考博文:objective-c协议(protocol))可以很方便的实现这种设计模式。 什么是代理? 苹果的官方文档给了很清晰的解释: Delegation is a simple and power...
895 0
iOS开发那些事-iOS常用设计模式–委托模式案例实现
<p>书接上回,应用案例</p> <p>我们以UITextFieldDelegate为例来说明一下委托的使用。UITextFieldDelegate是控件UITextField的 委托,控件的委托主要负责响应控件事件或控制其他对象。除了UITextField,WebView、UITableView等控件也有相应的委托对象。</p> <p>打开UITextFieldDelegate的AP
1039 0
IOS委托设计模式(摘自IOS开发指南)
    如何联系我:【万里虎】www.bravetiger.cn 【QQ】3396726884 (咨询问题100元起,帮助解决问题500元起) 【博客】http://www.cnblogs.com/kenshinobiy/
513 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
11673 0
.NET反射、委托技术与设计模式
1 反射技术与设计模式   反射(Reflection)是。NET中的重要机制,通过放射,可以在运行时获得。NET中每一个类型(包括类、结构、委托、接口和枚举等)的成员,包括方法、属性、事件,以及构造函数等。
890 0
+关注
狼人2007
个人对技术的追求:代码少而精捍;思路清晰美观;可扩展好维护;技术驱动商业; 人生格言:只要你有信念,有追求,并且坚持,那你一定比随波逐流,行得远行得正...
3528
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《Nacos架构&原理》
立即下载
《看见新力量:二》电子书
立即下载
云上自动化运维(CloudOps)白皮书
立即下载