文档库 最新最全的文档下载
当前位置:文档库 › c# 自定义事件和委托

c# 自定义事件和委托

c# 自定义事件和委托
c# 自定义事件和委托

在windows 编程中用到最多的就是控件的时间了,微软给我们很好的方式,把注意力放到事件执行方法的设计和编码上,但是但我们真正弄懂了事件的真正出发执行原理的话,对我们的编程的提高真是非常榜的,例如在windows编程中如果我单击了一个button按钮触发了button 的click事件 Button1_Click(){} ,但是有时候我们编程的时候,不但想要触发button 的单击事件,我还想要把其他的时间也要调用下来顺序执行,要实现这种方式,除了在方法最后对其他方法的调用,还可以利用将其他需要顺序执行的方法封装到button的click 事件的委托对象中,这样就能够顺序执行毁掉方法列表中的程序了,而这种方式的实现是以清楚事件触发和委托的调用为前提的。

事件是类和对象向外界发出的消息,事件的执行是通过事件委托的方式,调用我们所准备好的处理方法,而是先消息的响应的。要响应某些事件并针对某些事件执行我们意定的方法,需要做到以下几步:

1、声明事件委托。

2、声明事件。

3、添加事件的触发方法。

4、添加事件的处理程序(响应事件的方法)。

5、将指定的事件处理程序邦定到要处理的事件上(订阅事件)。

6、用户信息操作,并触发事件(调用事件的触发方法)。

7、通过事件委托的回调,执行我们需要的事件处理程序。

下面我们举一个简单的自定义事件处理程序的例子(控制台程序)

nam espace 事件

{

//发布事件的类

public class TestEventSource

{

//定义事件参数类

public class TestEventArgs : EventArgs

{

public readonly char KeyToRaiseEvent;

public TestEventArgs(char keyToRaiseEvent)

{

KeyToRaiseEvent = keyToRaiseEvent;

}

}

//定义delegate

public delegate void TestEventHandler(object sender, TestEventArgs e);

//用event 关键字声明事件对象

public event TestEventHandler TestEvent;

//事件触发方法

protected virtual void OnTestEvent(TestEventArgs e)

{

if (TestEvent != null)

TestEvent(this, e);

}

//引发事件

public void RaiseEvent(char keyToRaiseEvent)

{

TestEventArgs e = new TestEventArgs(keyToRaiseEvent);

OnTestEvent(e);

}

}

//监听事件的类

public class TestEventListener

{

//定义处理事件的方法,他与声明事件的delegate具有相同的参数和返回值类型

public void KeyPressed(object sender, TestEventSource.TestEventArgs e) {

Console.WriteLine("发送者:{0},所按得健为:{1}", sender,

e.KeyToRaiseEvent);

}

//订阅事件

public void Subscribe(TestEventSource evenSource)

{

evenSource.TestEvent += new

TestEventSource.TestEventHandler(KeyPressed);

}

//取消订阅事件

public void UnSubscribe(TestEventSource evenSource)

{

evenSource.TestEvent -= new

TestEventSource.TestEventHandler(KeyPressed);

}

}

//测试类

public class Test

{

public static void Main()

{

//创建事件源对象

TestEventSource es = new TestEventSource();

//创建监听对象

TestEventListener el = new TestEventListener();

//订阅事件

Console.WriteLine("订阅事件\n");

el.Subscribe(es);

//引发事件

Console.WriteLine("输入一个字符,再按enter键");

string s = Console.ReadLine();

es.RaiseEvent(s.ToCharArray()[0]);

//取消订阅事件

Console.WriteLine("\n取消订阅事件\n");

el.UnSubscribe(es);

//引发事件

Console.WriteLine("输入一个字符,再按enter健");

s = Console.ReadLine();

es.RaiseEvent(s.ToCharArray()[0]);

}

}

}

程序执行结

订阅事件

输入一个字符,再按enter键

aaaa

发送者:事件.TestEventSource,所按得健为:a

取消订阅事件

输入一个字符,再按enter健

TestEventSource类。他就相当于windows控件类一样,是事件的源,里面包含有事件的声明,以及存储调用参数的事件参数类,以及事件的触发方法。

TestEventListener类。他提供了事件处理程序,并实现了事件处理程序和事件对象的邦定,当然时间处理程序可以放在别处,跟邦定程序(订阅事件)放在一起便于理解和调用Test 类,实例化自定义事件的事件源对象,并调用TestEventListener类中的Subscribe(es);方法进行事件对象和事件处理程序的邦定(订阅事件),调用TestEventSource类中的RaiseEvent(char keyToRaiseEvent)引发对象,并有对象所指定的委托回调处理事件。完成整个自定义事件。

其中RaiseEvent(char keyToRaiseEvent) 就相当于m ain()一样是自定义事件的执行入口,从这个法开始---〉调用事件委托----〉查找订阅事件程序找到事件所封装的方法集----〉由委托回调事件处理程序并传递参数---〉执行事件处理程序。

C#里的委托和事件实现Observer

C#里的委托和事件实现Observer 一、委托的简介 1、委托的声明: delegate HandlerName ([parameters]) 例如: public delegate void PrintHandler(string str); 委托声明定义了一种类型,它用一组特定的参数以及返回类型来封装方法。对于静态方法,委托对象封装要调用的方法。对于实例方法,委托对象同时封装一个实例和该实例上的一个方法。如果您有一个委托对象和一组适当的参数,则可以用这些参数调用该委托。 2、委托的使用: using System; public class MyClass { public static void Main() { PrintStr myPrinter = new PrintStr(); PrintHandler myHandler = null; myHandler += new PrintHandler(myPrinter.CallPrint); // 将委托链接到方法,来实例化委托 if(myHandler!=null) myHandler("Hello

World!"); // 调用委托,相当于匿名调用委托所链接的方法 Console.Read(); } } public delegate void PrintHandler(string str); // 声明委托类型 public class PrintStr { public void CallPrint(string input) { Console.WriteLine(input); } } 在C#中使用委托方法: ·创建委托所使用的方法必须和委托声明相一致(参数列表、返回值都一致) ·利用 +=、-=来进行委托的链接、取消链接或直接使用https://www.wendangku.net/doc/7615613185.html,bine和Delegate.Remove方法来实现 ·可以使用MulticastDelegate的实例方法GetInvocationList()来获取委托链中所有的委托

C#委托及事件

C#委托及事件 在C#中,委托(delegate)是一种引用类型,在其他语言中,与委托最接近的是函数指针,但委托不仅存储对方法入口点的引用,还存储对用于调用方法的对象实例的引用。 简单的讲委托(delegate)是一种类型安全的函数指针,首先,看下面的示例程序,在C++中使用函数指针。 首先,存在两个方法:分别用于求两个数的最大值和最小值。 int Max(int x,int y) { return x>yx:y; } int Min(int x,int y) { return x } 上面两个函数的特点是:函数的返回值类型及参数列表都一样。那么,我们可以使用函数指针来指代这两个函数,并且可以将具体的指代过程交给用户,这样,可以减少用户判断的次数。 下面我们可以建立一个函数指针,将指向任意一个方法,代码如下所示: 建立一个委托类型,并声明该委托可以指向的方法的签名(函数原型)delegate void MyDelegate(int a,int b); 2.建立一个委托类的实例,并指向要调用的方法 用委托类实例调用所指向的方法 int c=md(4,5); 下面通过实例来演示C#中委托的使用。

案例操作020601:利用委托实现方法的 动态调用 首先,添加如下控件: 两个RadioButton,分别用来让用户选 择求最大值以及求最小值 二个TextBox,用来输入两个操作数 一个TextBox,用来显示运算结果 一个Button,用来执行运算 界面如下图所示: 下一步,在窗口中添加两个方法:Max,Min,这两方法的代码如下: int Max(int x,int y) { return x>yx:y; } int Min(int x,int y) { return x } 窗口中的代码,如下图所示:

C#委托事件详解

C# 中的委托和事件 引言 委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在。本文中,我将通过两个范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.Net Framework中的委托和事件、委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论。 将方法作为方法的参数 我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语: public void GreetPeople(string name) { // 做某些额外的事情,比如初始化之类,此处略 EnglishGreeting(name); } public void EnglishGreeting(string name) { Console.WriteLine("Morning, " + name); } 暂且不管这两个方法有没有什么实际意义。GreetPeople用于向某人问好,当我们传递代表某人姓名的name参数,比如说“Jimmy”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再次传递name参数,EnglishGreeting则用于向屏幕输出“Morning, Jimmy”。

现在假设这个程序需要进行全球化,哎呀,不好了,我是中国人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法: public void ChineseGreeting(string name){ Console.WriteLine("早上好, " + name); } 这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据: public enum Language{ English, Chinese } public void GreetPeople(string name, Language lang){ //做某些额外的事情,比如初始化之类,此处略 swith(lang){ case Language.English: EnglishGreeting(name); break; case Language.Chinese: ChineseGreeting(name); break; } } OK,尽管这样解决了问题,但我不说大家也很容易想到,这个解决方案的可扩展性很差,如果日后我们需要再添加韩文版、日文版,就不得不反复修改枚举和GreetPeople()方法,以适应新的需求。 在考虑新的解决方案之前,我们先看看 GreetPeople的方法签名:

仲恺软件设计模式实验指导书

设计模式实验指导 一、实验目的 使用合理的UML建模工具(ROSE或者Visio)和任意一种面向对象编程语言实现几种常用的设计模式,加深对这些模式的理解,包括简单工厂模式、工厂方法模 式、抽象工厂模式、单例模式、适配器模式、组合模式、装饰模式、外观模式、、命令模式、迭代器模式、观察者模式、策略模式等12种模式。 二、实验内容 根据以下的文档描述要求,使用合理的UML建模工具(ROSE或者Visio)和任意一种面向对象编程语言实现以下设计模式,包括根据实例绘制相应的模式结构图、编写模式实现代码,运行并测试模式实例代码。 (1)、简单工厂模式 使用简单工厂模式模拟女娲(Nvwa)造人(Person),如果传入参数M,则返回一个Man对象,如果传入参数W,则返回一个Woman对象,请实现该场景。现需要增加一个新的Robot类,如果传入参数R,则返回一个Robot对象,对代码进 行修改并注意女娲的变化。 (2)、工厂方法模式 海尔工厂(Haier)生产海尔空调(HaierAirCondition),美的工厂(Midea)生产美的空调(MideaAirCondition) 。使用工厂方法模式描述该场景,绘制类图并编程实现。 (3)、抽象工程模式 电脑配件生产工厂生产内存、CPU等硬件设备,这些内存、CPU的品牌、型号并不一定相同,根据下面的“产品等级结构-产品族”示意图,使用抽象工厂模式实现电脑配件生产过程并绘制相应的类图,绘制类图并编程实现。

(4)、单例模式 用懒汉式单例实现在某系统运行时,其登录界面类LoginForm只能够弹出一个,如果第二次实例化该类则提示“程序已运行”。绘制类图并编程实现。 提示:不要求做界面,用类模拟界面就可以了。 (5)、组合模式 使用组合模式设计一个杀毒软件(AntiVirus)的框架,该软件既可以对某个文件夹(Folder)杀毒,也可以对某个指定的文件(File)进行杀毒,文件种类包括文本文件TextFile、图片文件ImageFile、音频视频文件MediaFile。绘制类图并编程实现。 (6)、适配器模式 现有一个接口DataOperation定义了排序方法sort(int[]) 和查找方法search(int[], int),已知类QuickSort的quickSort(int[])方法实现了快速排序算法,类BinarySearch 的binarySearch(int[], int)方法实现了二分查找算法。现使用适配器模式设计一个系统,在不修改源代码的情况下将类QuickSort和类BinarySearch的方法适配到DataOperation接口中。绘制类图并编程实现。(要求实现快速排序和二分查找) (7)、装饰模式 某图书管理系统中,书籍类(Book)具有借书方法borrowBook()和还书方法returnBook() 。现需要动态给书籍对象添加冻结方法freeze()和遗失方法lose()。使用装饰模式设计该系统,绘制类图并编程实现。 (8)、外观模式 在电脑主机(Mainframe)中,只需要按下主机的开机按钮(on()),即可调用其他硬

唯一看明白额委托与事件讲解

一、在控制台下使用委托和事件 我们都知道,C#中有“接口”这个概念,所谓的“接口”就是定义一套标准,然后由实现类来具体实现其中的方法,所以说“接口,是一组类的抽象”。同样道理,我们可以将“委托”理解为“方法的抽象”,也就是说定义一个方法的模板,至于这个方法具体是怎么样的,就由方法自己去实现。 我们知道接口的最大好处就是可以实现多态,同理,“委托”是可以实现方法的多态,当我们想调用某个具体方法的时候,我们不直接调用这个方法,而是去调用这个委托。当然,我们必须在具体方法和委托之间建立某种关联。 下面我们来看例子。 首先,我们定义一个委托: public delegate void SaySomething(string name); 这跟抽象方法的语法格式很相似,只是多了一个关键字delegate。既然是对方法的一种抽象,那么我们最关注的当然就是方法的返回值以及方法的参数了。所以上面红色的部分就是我们定义出来的一个规矩,如果某个方法想委托我去做事,那么请你遵循我的规矩,就是返回值为void,参数为一个字符串。我们这个委托的含义是,当某个人来了,就向他说点东西。 好,既然我们已经定义了这个规矩,下面我们就定义具体的方法了。 public void SayHello(string name) { Console.WriteLine("Hello," + name + "!"); } public void SayNiceToMeetYou(string name) { Console.WriteLine("Nice to meet you," + name + "!"); } 我们这里一共定义了两个方法,一个是向某人说Hello,另一个是向某人说Nice to meet you。我们看到,这里定义的两个方法的返回值和参数跟我们前面定义的“委托”是一致的。 接下来,我们来看事件。 public event SaySomething come;

模式总结

设计模式总结 一、创建型模式 简单工厂 简单工厂最大优点在于工厂类中包含了必要的逻辑判断(switch),根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。 工厂方法 工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 工厂方法模式实现时,客户端要觉定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行。你想要加功能,本来是改工厂类的,而现在时修改客户端。 抽象工厂 抽象工程模式(Abstract Factory),提供一个创建一系列相关或相互依赖对象的接口,而无需制定它们具体的类。 原型模式 原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。(拷贝对象的引用地址《浅表副本》)。.NET在System命名空间中提供了ICloneable接口(里面唯一的方法Clone()),只要实现这个接口就可以完成原型模式。 建造者模式 建造者模式(Builder),将一个复杂对象的构造过程与它的表示分离,使得同样的构造过程可以创建不同的表示。

如果使用建造者模式,那么用户就只需建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。——抽象不应该依赖细节,细节应该依赖于抽象。建造者模式主要用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。 单例模式 单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。 二、行为型模式 观察者模式 观察者模式(Observer),定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生改变时,会通知所有观察者对象,使它们能自动更新自己。 当一个对象的改变需要同时改变其他对象的时候,而且他不知道具体有多少对象有待改变,应该考虑使用观察者模式。观察者模式所做的工作其实就是在解除耦合,让耦合的双方都依赖于抽象,而不依赖于具体,从而使得各自的变化都不会影响另一边的变化。 模板方法模式 模板方法模式(TemplateMethod),定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构可重复定义该算法的某些特定的步骤。 模板方法模式是通过把不变行为搬移到超类,去除子类中德重复代码来体现它的优势。模板方法模式就是提供了一个很好的代码复用平台。 状态模式 状态模式(State),当一个对象的内在状态发生改变时允许改变其行为,这个对象看起来像是改变了其类。

委托事件1

委托 定义委托的语法和定义方法比较相似,只是比方法多了一个关键字delegate,我们都知道方法就是将类型参数化,所谓的类型参数化就是说该方法接受一个参数,而该参数是某种类型的参数,比如int、string等等;而委托是将方法参数化,说了上面的那个类型参数化之后,相信你也能猜到方法参数化的意思了,对,就是将方法作为一个参数传到一个委托中。 首先来看看声明委托的语句: public deletate void MyDelegate(); public:访问修饰符delegate:关键字void:返回类型MyDelegate:委托名称( ):参数列表 看到声明大家会想了,为什么该委托的返回值,参数列表要这样的,我不能返回一个string,一个int么?我不能给委托加几个参数么?答案是:当然可以,但委托的定义是相对于方法来说的,因为得你的委托最终是要来注册方法的,而你的方法是具有某种签名的,所以你要给怎样签名的方法来声明一个委托,该委托就要和该方法具有同等的签名,就类似于你用一个int 类型的变量去接受一个string类型的值,显然是不行的(个人理解).... * 委托只要定义就可以了,我们并不需要关心他的实现 委托的使用 注册委托有两种方法: 第一种:直接将方法赋值[=]或者用“+=”给一个委托==>委托名=[+=] 方法名 第二种:委托本质也是一个类,只是一个特殊的类,所以我们也可以实例化一个委托对象通过委托构造函数来注册委托==》委托名对象名= new 委托名(方法名)

了解了委托的声明和使用,我们就可以来看小例子来加深理解了 首先看看界面: 界面上就是简单的四个按钮两个属于委托,两个属于事件,都是一个用来执行,一个用来干扰,以便于来理解委托事件 然后看后台代码,首先我定义了一个Test类,声明委托,实例了委托,还声明了事件,写了个方法用来触发事件,代码如下: 1public class Test 2 { 3//声明一个委托 4public delegate void MyDelegate(); 5 6//创建一个委托实例 7public MyDelegate myDel; 8//声明一个事件 9public event MyDelegate EventMyDel; 10 11//事件触发机制(必须和事件在同一个类中) 外界无法直接用EventMyDel()来触发事件 12public void DoEventMyDel() 13 { 14 EventMyDel(); 15 } 16 }

设计模式实验三

CENTRAL SOUTH UNIVERSITY 《软件体系结构》实验报告 实验名称设计模式实验二 学生姓名 学生学号XXX 专业班级软件工程1007班 指导教师刘伟 完成时间2012年12月25日

实验三设计模式实验二 一、实验目的 熟练使用PowerDesigner和任意一种面向对象编程语言实现几种常见的设计模式,包括外观模式、代理模式、职责链模式、命令模式、迭代器模式、观察者模式、策略模式和模板方法模式,理解每一种设计模式的模式动机,掌握模式结构,学习如何使用代码实现这些模式,并学会分析这些模式的使用效果。 二、实验内容 使用PowerDesigner和任意一种面向对象编程语言实现外观模式、代理模式、职责链模式、命令模式、迭代器模式、观察者模式、策略模式和模板方法模式,包括根据实例绘制模式结构图、编写模式实例实现代码,运行并测试模式实例代码。 (1) 外观模式 某软件公司为新开发的智能手机控制与管理软件提供了一键备份功能,通过该功能可以将原本存储在手机中的通信录、短信、照片、歌曲等资料一次性全部拷贝到移动存储介质(例如MMC卡或SD卡)中。在实现过程中需要与多个已有的类进行交互,例如通讯录管理类、短信管理类等,为了降低系统的耦合度,试使用外观模式来设计并编程模拟实现该一键备份功能。 (2) 代理模式 在某应用软件中需要记录业务方法的调用日志,在不修改现有业务类的基础上为每一个类提供一个日志记录代理类,在代理类中输出日志,如在业务方法method()调用之前输出“方法method()被调用,调用时间为2010-10-10 10:10:10”,调用之后如果没有抛异常则输出“方法method()成功调用”,否则输出“方法method()调用失败”。在代理类中调用真实业务类的业务方法,使用代理模式设计该日志记录功能的结构,绘制类图并编程模拟实现。 (3) 职责链模式 某企业的SCM(Supply Chain Management,供应链管理)系统中包含一个采购审批子系统。该企业的采购审批是分级进行的,即根据采购金额的不同由不同层次的主管人员来审批,主任可以审批5万元以下(不包括5万元)的采购单,副董事长可以审批5万元至10万元(不包括10万元)的采购单,董事长可以审批10万元至50万元(不包括50万元)的采购单,50万元及以上的采购单就需要开董事会讨论决定。试使用职责链模式设计并实现该系统。 (4) 命令模式 某软件公司欲开发一个基于Windows平台的公告板系统。系统提供一个主菜单(Menu),在主菜单中包含了一些菜单项(MenuItem),可以通过Menu类的addMenuItem()方法增加菜单项。菜单项的主要方法是click(),每一个菜单项包含一个抽象命令类,具体命令类包括

设计模式上机实验二实验报告

设计模式实验二 实验报告书 专业班级软件0703 学号24 姓名吉亚云 指导老师刘伟 时间2010年4月24日 中南大学软件学院

实验二设计模式上机实验二 一、实验目的 使用PowerDesigner和任意一种面向对象编程语言实现几种常用的设计模式,加深对这些模式的理解,包括装饰模式、外观模式、代理模式、职责链模式、命令模式、迭代器模式、观察者模式、状态模式、策略模式和模板方法模式。 二、实验内容 使用PowerDesigner和任意一种面向对象编程语言实现装饰模式、外观模式、代理模式、职责链模式、命令模式、迭代器模式、观察者模式、状态模式、策略模式和模板方法模式,包括根据实例绘制相应的模式结构图、编写模式实现代码,运行并测试模式实例代码。 三、实验要求 1. 正确无误绘制装饰模式、外观模式、代理模式、职责链模式、命令模式、迭代器模式、观察者模式、状态模式、策略模式和模板方法模式的模式结构图; 2. 使用任意一种面向对象编程语言实现装饰模式、外观模式、代理模式、职责链模式、命令模式、迭代器模式、观察者模式、状态模式、策略模式和模板方法模式,代码运行正确无误。 四、实验步骤 1. 使用PowerDesigner绘制装饰模式结构图并用面向对象编程语言实现该模式; 2. 使用PowerDesigner绘制外观模式结构图并用面向对象编程语言实现该模式; 3. 使用PowerDesigner绘制代理模式结构图并用面向对象编程语言实现该模式; 4. 使用PowerDesigner绘制职责链模式结构图并用面向对象编程语言实现该模式; 5. 使用PowerDesigner绘制命令模式结构图并用面向对象编程语言实现该模式; 6. 使用PowerDesigner绘制迭代器模式结构图并用面向对象编程语言实现该模式; 7. 使用PowerDesigner绘制观察者模式结构图并用面向对象编程语言实现该模式; 8. 使用PowerDesigner绘制状态模式结构图并用面向对象编程语言实现该模式; 9. 使用PowerDesigner绘制策略模式结构图并用面向对象编程语言实现该模式; 10. 使用PowerDesigner绘制模板方法模式结构图并用面向对象编程语言实现该模式。 五、实验报告要求 1. 提供装饰模式结构图及实现代码; 2. 提供外观模式结构图及实现代码; 3. 提供代理模式结构图及实现代码; 4. 提供职责链模式结构图及实现代码;

C#委托与事件以及应用

这些很重要在MVC EF4.1 里都会有很多拉姆达表达式的影子在做组件开发用户控件开发事件的运用一定也是少不了的稍微深入点儿的说用于两个对象之间的通讯用来解耦用委托事件是很不错的选择而设计模式里的观察者模式也是基于委托事件的应用还有做winform 开发的里的线程WPF SL 的异步调用等都是有这委托的影子的所以这个还是很重要的。也是一定要掌握的~ 希望通过这篇文章能让大家更加了解委托以及如何运用~ 一.委托以及延伸 先看下MSDN 的介绍吧~------ delegate 通俗的说委托就是可以实现把方法做为变量来传递 1.先写个最简单的委托的用法 静态的和非静态方法的 结果会输出 您好wlf

Hello wlf 这是最原始的委托 2. 进化为匿名方法 声明完委托后还要声明方法是不是很麻烦如果不声明方法用匿名方法可以帮我们看 代码减少了很多吧~ 3.再进化为拉姆达表达式 上面的虽然简单了不少但是还能更简单的用拉姆达表达式~ 看这就是拉姆达表达式的演变一定要会这个~ 因为在EF LINQ 等有很多用拉姆达表达式的~ 4.用Action 和Func继续简化 上面的代码以及很简单了但是还有个很不爽的一点~ 要声明委托!可以不声明么?当然可以~ 先看MSDN介绍Action和Func 通俗的讲这两个都是用来帮你声明委托 Action 用于帮你声明没用返回值的委托Func则是有返回值的最后一个参数为返回值

看~ 以前的版本总是要声明一个HelloWorld 的委托现在只有两行代码就可以了下面顺便掩饰了有返回值的func 的例子。第一个参数是传递 参数的类型第二个是返回值的类型~ 这里说下这俩函数都有16个重载~ 所以多个参数是没问题的~ 5.说说委托的好处 委托的好处应用文章开始已经说了很多了这里就拿文章开头的例子体会下委托的好处 当我们再多一种语言来问好时只需增加一种Action 即可而不需要改动sayHello 方法否则这里将充满了if else 的判断 6.工作里的应用 再LINQ 或EF 里都有个很重要的数据刷选的功能WHERE 它的参数就是Func 直接上代码自己看注释~

23种模式详解

总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 其实还有两类:并发型模式和线程池模式。用一个图片来整体描述一下: 二、设计模式的六大原则 1、开闭原则(Open Close Principle)

开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。 2、里氏代换原则(Liskov Substitution Principle) 里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。—— From Baidu 百科 3、依赖倒转原则(Dependence Inversion Principle) 这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。 4、接口隔离原则(Interface Segregation Principle) 这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。还是一个降低类之间的耦合度的意思,从这儿我们看出,其实设计模式就是一个软件的设计思想,从大型软件架构出发,为了升级和维护方便。所以上文中多次出现:降低依赖,降低耦合。 5、迪米特法则(最少知道原则)(Demeter Principle) 为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。 6、合成复用原则(Composite Reuse Principle) 原则是尽量使用合成/聚合的方式,而不是使用继承。 三、Java的23中设计模式 从这一块开始,我们详细介绍Java中23种设计模式的概念,应用场景等情况,并结合他们的特点及设计模式的原则进行分析。 1、工厂方法模式(Factory Method) 工厂方法模式分为三种:

你可能不知道的陷阱:C#委托和事件的困惑

你可能不知道的陷阱:C#委托和事件的困惑 . 问题引入 通常,一个C 语言学习者登堂入室的标志就是学会使用了指针,而成为高手的标志又是“玩转指针”。指针是如此奇妙,通过一个地址,可以指向一个数,结构体,对象,甚至函数。最后的一种函数,我们称之为“函数指针”(和“指针函数”可不一样!)就像如下的代码: 1 2 3 int func(int x); /* 声明一个函数 */ int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func 函数的首地址赋给指针f */ C 语言因为函数指针获得了极强的动态性,因为你可以通过给函数指针赋值并动态改变其行为,我曾在单片机上写的一个小系统中,任务调度机制玩的就是函数指针。 在.NET 时代,函数指针有了更安全更优雅的包装,就是委托。而事件,则是为了限制委托灵活性引入的新“委托”(之所以为什么限制,后面会谈到)。同样,熟练掌握委托和事件,也是C#登堂入室的标志。有了事件,大大简化了编程,类库变得前所未有的开放,消息传递变得更加简单,任何熟悉事件的人一定都深有体会。 但你也知道,指针强大,高性能,带来的就是危险,你不知道这个指针是否安全,出了问题,非常难于调试。事件和委托这么好,可是当你写了很多代码,完成大型系统时,心里是不是总觉得怪怪的?有当年使用指针时类似的感觉? 如果是的话,请看如下的问题: 1. 若多次添加同一个事件处理函数时,触发时处理函数是否也会多次触发? 2. 若添加了一个事件处理函数,却执行了两次或多次”取消事件“,是否会报错? 3. 如何认定两个事件处理函数是一样的? 如果是匿名函数呢? 4. 如果不手动删除事件函数,系统会帮我们回收吗? 5. 在多线程环境下,挂接事件时和对象创建所在的线程不同,那事件处理函数中的代码将在哪个线程中执行? 6. 当代码的层次复杂时,开放委托和事件是不是会带来更大的麻烦? 列下这些问题,下面就让我们讨论这些”尖酸刻薄“的问题。 二. 事件订阅和取消问题 我们考虑一个典型的例子:加热器,加热器内部加热,在达到温度后通知外界”加热已经完成“。 尝试写下如下测试类:

(完整版)软件设计架构试卷

一、选择题(每题2分,共24分) 1.以下关于构造函数的说法,其中错误的是( B ) A.构造函数的函数名必须与类名相同 B.构造函数可以指定返回类型 C.构造函数可以带有参数 D.构造函数可以重载 2.类的构造函数是在( B )调用的。 A. 类创建时 B. 创建对象时 C. 删除对象时 D. 不自动调用 3.在以下关于方法重载的说法,其中错误的是( D ) A.方法可以通过指定不同的返回值类型实现重载 B.方法可以通过指定不同的参数个数实现重载 C.方法可以通过指定不同的参数类型实现重载 D.方法可以通过指定不同的参数顺序实现重载 4.在定义类时,如果希望类的某个方法能够在派生类中进一步进行改进,以处理不同的派生类的需要,则应该将该方法声明为( D ) A.sealed B.public C.virtual D.override 5.( D )表示了对象间的is-a的关系。 A. 组合 B. 引用 C. 聚合 D. 继承 6.关于单一职责原则,以下叙述错误的是( C )。 A.一个类只负责一个功能领域中的相应职责 B.就一个类而言,应该有且权有一个引起它变化的原因 C.一个类承担的职责越多,越容易复用,被复用的可能性越大 D.一个类承担的职责过多时需要将职责进行分离,将不同的职责封装在不同的类中 7.某系统通过使用配置文件,可以在不修改源代码的情况下更换数据库驱动程序,该系统满足( B ) A. 里氏代换原则 B. 接口隔离原则 C. 单一职责原则 D. 开闭原则 8.一个软件实体应尽可能少地与其他软件实体发生相互作用,这样,当一个模块修改时,就会尽量少的影响其他模块,扩展会相对容易。这是( A )的定义。 A. 迪米特法则 B. 接口隔离原则 C. 里氏代换原则 D. 合成复用原则 9.当我们想创建一个具体的对象而又不希望指定具体的类时,可以使用( A )模式。 A.创建型 B.结构型 C行为型 D.以上都可以 10.在观察者模式中,表述错误的是( C )

设计模式考试复习题(含答案)14542

一、1. 设计模式一般用来解决什么样的问题: A.同一问题的不同表相 2. 下列属于面向对象基本原则的是: C.里氏代换 3. Open-Close原则的含义是一个软件实体:A.应当对扩展开放,对修改关闭. 4. 当我们想创建一个具体的对象而又不希望指定具体的类时,使用(A)模式。A.创建型 5. 要依赖于抽象不要依赖于具体。即针对接口编程不要针对实现编程:(D)依赖倒转原则 6. 依据设计模式思想,程序开发中应优先使用的是( A )关系实现复用。A, 委派 7. 设计模式的两大主题是( D ) D.系统复用与系统扩展 8. 单体模式中,两个基本要点(AB)和单体类自己提供单例A .构造函数私有 B.唯一实例 9. 下列模式中,属于行为模式的是( B ) B观察者 10. “不要和陌生人说话”是( D )原则的通俗表述 D.迪米特 1. 软件体系结构是指一个系统的有目的的设计和规划,这个设计规划既不描述活动,也不描述系统怎样开发,它只描述系统的组成元素及其相互的交互协作。 2.一个UML模型只描述了一个系统要做什么,它并没告诉我们系统是怎么做。 3.接口是可以在整个模型中反复使用的一组行为,是一个没有属性而只有方法的类。 4.多重性指的是,某个类有多个对象可以和另一个类的一对象关联。 5.当一个类的对象可以充当多种角色时,自身关联就可能发生。 6.在泛化关系中,子类可以替代父类。后前者出现的可以相同地方。反过来却不成立。 7.最通常的依赖关系是一个类操作的形构中用到了另一个类的定义。 8.组成是强类型的聚集,因为聚集中的每个部分体只能属于一个整体。 9.实现的符号和继承的符号有相似之处,两者的唯一差别是实现关系用虚线表示,继承关系用实线表示。 10. 设计模式中应优先使用对象组合而不是类继承。 1.适配器模式属于创建型模式结构型( F ) 2.在设计模式中,“效果”只是指“原因和结果”( T ) 3.设计模式使代码编制不能真正工程化( T ) 4.面向对象语言编程中的异常处理,可以理解为责任链模式(T ) 5.反模式就是反对在软件开发过程中使用设计模式分析:反模式用来解决问题的带有共性的不良方法(F ) 1.什么是设计模式?设计模式目标是什么? 答:设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解,保证代码可靠性。 2.设计模式中一般都遵循的原则有什么? 答:开闭原则、根据场景进行设计原则、优先组合原则、包容变化原则 3.“Gang of Four”针对“创建优秀面向对象设计”建议了哪些策略? 答:针对接口编程、优先使用对象组合而不是类继承,找到并封装变化点。 4.面向对象系统中功能复用的两种最常用技术是什么? 答:类继承和对象组合,类继承允许你根据其他类的实现来定义一个类的实现。父类的内部细节对子类可见。 类继承是在编译时刻静态定义的,且可直接使用,类继承可以较方便地改变被复用的实现。对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接口。 5.只根据抽象类中定义的接口来操纵对象有什么好处? 答:1)客户无须知道他们使用对象的特定类型,只须对象有客户所期望的接口。 2)客户无须知道他们使用的对象是用什么类来实现的,他们只须知道定义接口的抽象类。 五、应用题(分值15) 公司架构:经理、工程师、技师和后勤人员都是公司的雇员,经理管理工程师、技师和后勤人员。高层经理领导较低级别的经理。典型层次图如下:可以使用哪种设计模式实现公司的层级关系?并说明为什么? 组合模式,第一,其公司关系架构为树形结构;第二,其表示了部分-整体关系(自己扩展)

java实验策略模式观察者模式和组合模式

实验二策略模式、观察者模式和组合模式 一、实验目的: (1)学习和掌握策略模式; (2)学习和掌握观察者模式; (3)学习和掌握组合模式; (4)学习和掌握使用这些模式解决实际问题; 二、实验内容 1. 请使用策略模式实现下列编程要求:已知几何形状家族有圆形、矩形、椭圆形、三角形等形状。请用Java语言定义一个抽象类MyShape表示形状这样概念,MyShape抽象类中提供了计算面积、周长、显示形状信息的抽象方法,然后分别定义它的子类MyCircle(圆形)、MyRectangle(矩形)、MyEllipse(椭圆形)、MyTriangle(三角形)等特定几何形状。并绘制这些定义的几何家族的所有形状。 2.请用观察者模式实现功能:学校发布信息,学生可以订阅,老师可以订阅,行政人员也可以订阅。提示:定义主题接口,观察者接口,定义Notice、学生、老师和行政人员类,定义测试类。其中Notice类实现主题接口,老师、学生和行政人员实现观察者接口。思考,如果要求实现学生和老师均可以订阅多个信息,即除了订阅学校发布信息,也可以订阅所属系发送的信息,请编程实现。 3.定义一个游戏地图。地图是由每个方块拼合起来。地图上有墙等障碍物,也有可以通行的基本图元构成。请使用组合模式,绘制一个游戏地图,地图的内容自行定义,也可以类似图3形式:

图3游戏地图 4.已知有一个二维数组数据如图1所示,请结合策略模式、观察者模式和组合模式实现一个MVC结构的应用程序。要求:如果用户移动滑块,可以修改二维数组的值,并在运行的用户界面中显示出来。其中,饼状图和柱状图中的区域分布为二位数组每一维的总和。运行结果如图4和图5所示。 60 50 90 90 40 30 10 20 70 图4 数据模型 图5运行结果

中南大学软件体系结构设计模式实验二全解

《软件体系结构》 实验报告 项目名称设计模式实验2 专业班级 学号_________________ 姓名___________________ 实验成绩: 批阅教师:

实验3设计模式实验二 实验学时: 4 每组人数: 1 实验类型: 3 (1 : 基础性 2: 综合性 3: 设计性 4 :研究性) 实验要求: 1 (1 : 必修 2: 选修 3: 其它) 实验类别: 3 (1 : 基础 2: 专业基础 3: 专业 4:其它) 、实验目的 熟练使用 PowerDesigner 和任意一种面向对象编程语言实现几种常见的行为型设计模 式,包括职责链模式、命令模式、观察者模式和策略模式, 理解每一种设计模式的模式动机, 掌握模式结构,学习如何使用代码实现这些模式。 、实验内容 1. 某企业的SCM (Supply Chain Management ,供应链管 理)系统中包含一个采购审批子 系统。该企业的采购审批是分级进行的, 即根据采购金额的不同由不同层次的主管人员来审 批,主任可以审批 5万元以下(不包括 5万元)的采购单,副董事长可以审批 5万元至10 万元(不包括10万元)的采购单,董事长可以审批 10万元至50万元(不包括50万元)的 采购单,50万元及以上的采购单就需要开董事会讨论决定。如下图所示: 试使用职责链模式设计并模拟实现该系统。 2. 房间中的开关是命令模式的一个实例,现用命令模式来模拟开关的功能,可控制对 象包括电灯和电 风扇,绘制相应的类图并编程模拟实现。 3. 某软件公司欲开发一个基于 Windows 平台的公告板系统。系统提供一个主菜单 (Menu ),在主菜单中包含了一些菜单项 (Menultem ),可以通过 Menu 类的addMenultem ()方 法增加菜单项。菜单项的主要方法是 click (),每一个菜单项包含一个抽象命令类,具体命令 类包括 OpenCommand (打开命令),CreateCommand (新建命令),EditCommand (编辑命令)等, 命令类具有一个 execute ()方法,用于调用公告板系统界面类 (BoardScreen )的open ()、 create 。、 采购人员 采购单 金额V 5万元 5万元w 金额V 10万元10万元w 金额V 50万元 金额》50万元 主任 副董事长 董事长 董事会

C#委托与事件

我们抛弃各种C#参考书中桀骜难懂的事件与委托概念,设想一个情景来理解事件与委托的使用:有一家IT公司,董事长不希望自己的雇员在上班时间玩游戏,但又不可能每时每刻都盯着每个雇员,因此,他希望使用一种新的方式实现监视雇员的效果:如果有雇员违反规定,某个设备或专门的监查人员将自动发出一个消息通知他,董事长只需要在事情发生时进行处理。 因此,这个用例实际上是两种类型——董事长类与雇员类——之间的交互,下面的代码将给读者展示如何使用委托与事件机制实现这种交互: 首先,我们需要在董事长类与雇员类之间定义一个委托类型,用于传递两者之间的事件,这个类型就是一个监视设备或专门负责打小报告的监查人员: public delegate void DelegateClassHandle(); 定义一个委托的过程类似方法的定义,但它没有方法体。定义委托一定要添加关键字delegate。由于定义委托实际上相当一个类,因此可以在定义类的任何地方定义委托。另外,根据委托的可见性,也可以添加一般的访问修饰符,如public、private和protected。 委托的返回值类型为void,这并非表示委托类型本身带有返回值,该返回值类型是指委托的目标函数类型,即它委托的一个事件处理函数返回值是void类型。 新建一个雇员类Employee,其代码如下: public class Employee { public event DelegateClassHandle PlayGame; public void Games() { if (PlayGame != null) { PlayGame(); } } } 雇员类Employee代码中定义了一个DelegateClassHandle类型的事件PlayGame,它的定义方式也很特殊,首先必须使用关键字event,表示PlayGame是一个事件,同时还必须声明该事件的委托类型为DelegateClassHandle,即将来由该类型的委托对象负责通知事件。 如果有雇员开始玩游戏,它将执行Games方法,而只要该方法一被调用,就会触发一个事件PlayGame,然后董事长就会收到这个事件的消息——有人在玩游戏了。 董事长类代码如下,他有一个方法Notify用于接收消息: public class Admin { public void Notify() {

设计模式考点

设计模式题库--自编版 选择题 1、设计模式具有()的优点。 A、提高系统性能 B、降低软件规模和复杂度 C、减少代码开发工作量 D、提升软件设计的质量 2、在面向对象软件的开发中,采用设计模式()。 A、可以减少在设计和过程中需要创建的实例对象的数量 B、可以保证程序的运行速度达到最优值 C、可以复用相似问题的相同解决方案 D、允许在非面向对象程序设计语言中使用面向对象的概念 3、()都是行为型设计模式。 A、组合模式、适配者模式和代理模式 B、观察者模式、职责链模式和策略模式 C、原型模式、建造者模式和单例模式 D、迭代器模式、命令模式和桥接模式 4.开闭原则是面向对象的可复用设计的基石,开闭原则是指一个软件实体应当对()开放,对()关闭;里氏代换原则是指任何()可以出现的地方,()一定可以出现;依赖倒置原则就是依赖于(),而不要依赖于(),或者说要针对接口编程,不要针对实现编程。 ①A、修改B、扩展C、分析D、设计 ②A、修改B、扩展C、分析D、设计

③A、变量B、常量C、基类对象D、子类对象 ④A、变量B、常量C、基类对象D、子类对象 ⑤A、程序设计语言 B、建模语言C、实现D、抽象 ⑥A、程序设计语言 B、建模语言C、实现D、抽象 5.关于单一责原则,以下叙述错误的是()。 A、一个雷只负责一个功能领域中的相应职责。 B、就一个类而言,应该有且仅有一个引起它变化的原因。 C、一个类承担的职责越多,越容易复用,被复用的可能性越大。 D、当一个类承担的职责过多时,需要将职责进行分离,将不同的职责封装 在不同的类中。 6.以下关于面向对象设计的的叙述中,错误的是()。 A、高层模块不应该依赖于低层模块。 B、抽象不应该依赖于细节。 C、细节可以依赖于抽象。 D、高层模块无法不依赖于低层模块。 7.在系统设计中应用迪米特法则,以下叙述有误的是()。 A、在类的划上,一个尽量创建松耦合的类,类的耦合度越低,复用越容易。 B、如果两个类之间不必彼此直接通信,那么这两个类就不应该发生直接的 相互作用。 C、在对其他类的引用上,一个对象对其他对象的引用应该降到最低。 D、在类的设计上,只要有可能,一个类型应该尽量设计成抽象类或接口,且成员变量和成员函数的访问权限最好设置为公开的。

相关文档