2008年4月3日

乐在其中设计模式(C#)系列文章索引

感谢原作者的整理:)以下转自http://www.cnblogs.com/webabcd/archive/2008/04/02/1134658.html
乐在其中设计模式(C#)系列文章索引


作者:webabcd


介绍
类图加实例的方式介绍设计模式(C#)


创建型模式(Creational Pattern)
1、乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)
介绍
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

2、乐在其中设计模式(C#) - 建造者模式(Builder Pattern)
介绍
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

3、乐在其中设计模式(C#) - 原型模式(Prototype Pattern)
介绍
用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。

4、乐在其中设计模式(C#) - 工厂方法模式(Factory Method Pattern)
介绍
定义一个用于创建对象的接口,让子类决定将哪一个类实例化。Factory Method使一个类的实例化延迟到其子类。

5、乐在其中设计模式(C#) - 单例模式(Singleton Pattern)
介绍
保证一个类仅有一个实例,并提供一个访问它的全局访问点。


结构型模式(Structural Pattern)
6、乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)
介绍
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

7、乐在其中设计模式(C#) - 桥接模式(Bridge Pattern)
介绍

将抽象部分与它的实现部分分离,使它们都可以独立地变化。

8、乐在其中设计模式(C#) - 组合模式(Composite Pattern)
介绍
将对象组合成树形结构以表示“部分-整体”的层次结构。它使得客户对单个对象和复合对象的使用具有一致性。

9、乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)
介绍
动态地给一个对象添加一些额外的职责。就扩展功能而言,它比生成子类方式更为灵活。

10、乐在其中设计模式(C#) - 外观模式(Facade Pattern)
介绍
为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

11、乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)
介绍
运用共享技术有效地支持大量细粒度的对象。

12、乐在其中设计模式(C#) - 代理模式(Proxy Pattern)
介绍
为其他对象提供一个代理以控制对这个对象的访问。


行为型模式(Behavioral Pattern)
13、乐在其中设计模式(C#) - 责任链模式(Chain of Responsibility Pattern)
介绍
为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。

14、乐在其中设计模式(C#) - 命令模式(Command Pattern)
介绍
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。

15、乐在其中设计模式(C#) - 解释器模式(Interpreter Pattern)
介绍
给定一个语言,定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。

16、乐在其中设计模式(C#) - 迭代器模式(Iterator Pattern)
介绍
提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。

17、乐在其中设计模式(C#) - 中介者模式(Mediator Pattern)
介绍
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

18、乐在其中设计模式(C#) - 备忘录模式(Memento Pattern)
介绍
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。

19、乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
介绍
定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。

20、乐在其中设计模式(C#) - 状态模式(State Pattern)
介绍
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。

21、乐在其中设计模式(C#) - 策略模式(Strategy Pattern)
介绍
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。

22、乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern)

介绍
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

23、乐在其中设计模式(C#) - 访问者模式(Visitor Pattern)
介绍
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。


其他
24、乐在其中设计模式(C#) - 提供者模式(Provider Pattern)
介绍
为一个API进行定义和实现的分离。


OK
[源码下载]

posted @ 2008-04-03 16:40 书生 阅读(99) 评论(0) 编辑

C#事件(event)解析

最近看到一些我认为写的很不错的文章.我觉得能够帮助像我一样,对这些概念或者用法不太熟悉的朋友.
以下转自
http://www.cnblogs.com/michaelxu/archive/2008/04/02/1134217.html

事件(event),这个词儿对于初学者来说,往往总是显得有些神秘,不易弄懂。而这些东西却往往又是编程中常用且非常重要的东西。大家都知道windows消息处理机制的重要,其实C#事件就是基于windows消息处理机制的,只是封装的更好,让开发者无须知道底层的消息处理机制,就可以开发出强大的基于事件的应用程序来。

先来看看事件编程有哪些好处。
在以往我们编写这类程序中,往往采用等待机制,为了等待某件事情的发生,需要不断地检测某些判断变量,而引入事件编程后,大大简化了这种过程:
- 使用事件,可以很方便地确定程序执行顺序。
- 当事件驱动程序等待事件时,它不占用很多资源。事件驱动程序与过程式程序最大的不同就在于,程序不再不停地检查输入设备,而是呆着不动,等待消息的到来,每个输入的消息会被排进队列,等待程序处理它。如果没有消息在等待,则程序会把控制交回给操作系统,以运行其他程序。
- 事件简化了编程。操作系统只是简单地将消息传送给对象,由对象的事件驱动程序确定事件的处理方法。操作系统不必知道程序的内部工作机制,只是需要知道如何与对象进行对话,也就是如何传递消息。

  有了这么多好处,看来我们的确有必要掌握它。俗话说:“难了不会,会了不难”。就让我们一步一步开始吧...

  要讲事件,必然要讲到委托(delegate)。它们之间的关系可以通过一个浅显的比方来说明,这个比方可能不是十分恰当。比如你要租一个房屋,这是一个事件,那么委托就是房屋租赁中介,当你把租房子的消息告知中介后,中介就会产生出一套符合你要求的房屋租赁方案来。再由中介执行这套方案,你便租得了这个房屋,即事件被处理了。当然你也可以不通过中介,直接找房东,但如果没有互联网等工具,你如何得到谁出租房屋的信息?话题扯远了。

委托(delegate)
委托可以理解成为函数指针,不同的是委托是面向对象,而且是类型安全的。关于委托的理解,可以参考我的另一篇文章
《C#委托之个人理解》

事件(event)
  我们可以把事件编程简单地分成两个部分:事件发生的类(书面上叫事件发生器)和事件接收处理的类。事件发生的类就是说在这个类中触发了一个事件,但这个类并不知道哪个个对象或方法将会加收到并处理它触发的事件。所需要的是在发送方和接收方之间存在一个媒介。这个媒介在.NET Framework中就是委托(delegate)。在事件接收处理的类中,我们需要有一个处理事件的方法。好了,我们就按照这个顺序来实现一个捕获键盘按键的程序,来一步一步说明如何编写事件应用程序。

1、首先创建一个自己的EventArgs类。
引自MSDN:
EventArgs是包含事件数据的类的基类,此类不包含事件数据,在事件引发时不向事件处理程序传递状态信息的事件会使用此类。如果事件处理程序需要状态信息,则应用程序必须从此类派生一个类来保存数据。

因为在我们键盘按键事件中要包含按键信息,所以要派生一个KeyEventArgs类,来保存按键信息,好让后面知道按了哪个键。

internal class KeyEventArgs : EventArgs
{
    
private char
 keyChar;
    
public KeyEventArgs( char keyChar ) : base
()
    
{
        
this.keyChar =
 keyChar;
    }


    
public char KeyChar
    
{
        
get

        
{
            
return
 keyChar;
        }

    }

}


2、再创建一个事件发生的类KeyInputMonitor,这个类用于监控键盘按键的输入并触发一个事件:

internal class KeyInputMonitor
{
    
// 创建一个委托,返回类型为void,两个参数

    public delegate void KeyDown( object sender, KeyEventArgs e );
    
// 将创建的委托和特定事件关联,在这里特定的事件为OnKeyDown

    public event KeyDown OnKeyDown;

    
public void
 Run()
    
{
        
bool finished = false
;
        
do

        
{
            Console.WriteLine( 
"Input a char"
 );
            
string response =
 Console.ReadLine();

            
char responseChar = ( response == "" ) ? ' ' : char.ToUpper( response[0
] );
            
switch
( responseChar )
            
{
                
case 'X'
:
                    finished 
= true
;
                    
break
;
                
default
:
                    
// 得到按键信息的参数

                    KeyEventArgs keyEventArgs = new KeyEventArgs( responseChar );
                    
// 触发事件

                    OnKeyDown( this, keyEventArgs );
                    
break
;
            }

        }
while!finished );
    }

}


这里注意OnKeyDown( this, KeyEventArgs );一句,这就是触发事件的语句,并将事件交由KeyDown这个委托来处理,委托指定事件处理方法去处理事件,这就是事件接收方的类的事情了。参数this是指触发事件的对象就是本身这个对象,keyEventArgs包含了按键信息。

3、最后创建一个事件接收方的类,这个类先产生一个委托实例,再把这个委托实例添加到产生事件对象的事件列表中去,这个过程又叫订阅事件。然后提供一个方法回显按键信息。

internal class EventReceiver
{
    
public
 EventReceiver( KeyInputMonitor monitor )
    
{
        
// 产生一个委托实例并添加到KeyInputMonitor产生的事件列表中

        monitor.OnKeyDown += new KeyInputMonitor.KeyDown( this.Echo );
    }

    
private void Echo(object sender, KeyEventArgs e)
    
{
        
// 真正的事件处理函数

        Console.WriteLine( "Capture key: {0}", e.KeyChar );
    }

}


4、看一下如何调用

public class MainEntryPoint
{
    
public static void
 Start()
    
{
        
// 实例化一个事件发送器

        KeyInputMonitor monitor = new KeyInputMonitor();
        
// 实例化一个事件接收器

        EventReceiver eventReceiver = new EventReceiver( monitor );
        
// 运行

        monitor.Run();
    }

}


总结:

C#中使用事件需要的步骤:
1.创建一个委托
2.将创建的委托与特定事件关联(.Net类库中的很多事件都是已经定制好的,所以他们也就有相应的一个委托,在编写关联事件处理程序--也就是当有事件发生时我们要执行的方法的时候我们需要和这个委托有相同的签名)
3.编写事件处理程序
4.利用编写的事件处理程序生成一个委托实例
5.把这个委托实例添加到产生事件对象的事件列表中去,这个过程又叫订阅事件

C#中事件产生和实现的流程:
1.定义A为产生事件的实例,a为A产生的一个事件
2.定义B为接收事件的实例,b为处理事件的方法
3.A由于用户(程序编写者或程序使用者)或者系统产生一个a事件(例如点击一个Button,产生一个Click事件)
4.A通过事件列表中的委托对象将这个事件通知给B
5.B接到一个事件通知(实际是B.b利用委托来实现事件的接收)
6.调用B.b方法完成事件处理

不当之处,欢迎指正。
(完)

这有一个很好的例子,有助于理解事件机制。

using System;

namespace Vczx.ProCSharp.Event
{
/// <summary>
/// 类EatEventArgs 必须继承自类EventArgs,用来引发事件时封装数据
/// </summary>
public class EatEventArgs : EventArgs
{
public String restrauntName; //饭店名称
public decimal moneyOut; //准备消费金额
}

/// <summary>
/// 这个委托用来说明处理吃饭事件的方法的方法头(模式)
/// </summary>
public delegate void EatEventHandler(object sender, EatEventArgs e);

/// <summary>
/// 引发吃饭事件(EateEvent)的类Master(主人),这个类必须
/// 1.声明一个名为EatEvent的事件: public event EatEventHandler EatEvent;
/// 2.通过一个名为OnEatEvent的方法来引发吃饭事件,给那些处理此事件的方法传数据;
/// 3.说明在某种情形下引发事件呢?在饿的时候。用方法Hungrg来模拟。
/// </summary>
public class Master
{
//声明事件
public event EatEventHandler EatEvent;

//引发事件的方法
public void OnEatEvent(EatEventArgs e)
{
if (EatEvent != null)
{
EatEvent(this, e);
}
}

//当主人饿的时候,他会指定吃饭地点和消费金额。
public void Hungry(String restrauntName, decimal moneyOut)
{
EatEventArgs e = new EatEventArgs();
e.restrauntName = restrauntName;
e.moneyOut = moneyOut;

Console.WriteLine("主人说:");
Console.WriteLine("我饿了,要去{0}吃饭,消费{1}元", e.restrauntName, e.moneyOut);

//引发事件
OnEatEvent(e);
}
}

/// <summary>
/// 类Servant(仆人)有一个方法ArrangeFood(安排食物)来处理主人的吃饭事件
/// </summary>
public class Servant
{
public void ArrangeFood(object sender, EatEventArgs e)
{
Console.WriteLine();
Console.WriteLine("仆人说:");
Console.WriteLine("我的主人, 您的命令是 : ");
Console.WriteLine("吃饭地点 -- {0}", e.restrauntName);
Console.WriteLine("准备消费 -- {0}元 ", e.moneyOut);
Console.WriteLine("好的,正给您安排。。。。。。。。\n");
System.Threading.Thread.Sleep( 5000 );
Console.WriteLine("主人,您的食物在这儿,请慢用");
Console.Read();
}
}

/// <summary>
/// 类God安排qinshihuang(秦始皇)的仆人是lisi(李斯),并让李斯的ArrangeFood
/// 方法来处理qinshihuang的吃饭事件:qinshihuang.EatEvent += new EatEventHandler(lishi.ArrangeFood);
/// </summary>
public class God
{
public static void Start()
{
Master qinshihuang = new Master();
Servant lishi = new Servant();

qinshihuang.EatEvent += new EatEventHandler(lishi.ArrangeFood);

//秦始皇饿了,想去希尔顿大酒店,消费5000元
qinshihuang.Hungry("希尔顿大酒店", 5000.0m);
}
}
}

输出:

主人说:
我饿了,要去希尔顿大酒店吃饭,消费5000.0元

仆人说:
我的主人, 您的命令是 :
吃饭地点 -- 希尔顿大酒店
准备消费 -- 5000.0元
好的,正给您安排。。。。。。。。

主人,您的食物在这儿,请慢用

两个小例子的代码我打到一个包里了.
http://files.cnblogs.com/pbwf/newevent.rar

posted @ 2008-04-03 16:07 书生 阅读(177) 评论(0) 编辑