新足迹

 找回密码
 注册

精华好帖回顾

· 80年代经典电视剧系列之大陆篇 (2008-10-31) zmzhu · 美食接龙: 传统广东主食——鸳鸯薄餐 下一棒:阿狗 食材:糯米 (2008-8-17) komen
· 短登作业之二------墨尔本被盗篇! (2005-2-25) suxiaomei · 澳洲小生意攻略(鱼薯店篇,四--终结) (2008-7-14) 车友
Advertisement
Advertisement
12
返回列表 发新帖
楼主:dalaohu

[IT] Happy coding: BackgroundWorker refactoring [复制链接]

2010年度奖章获得者

发表于 2010-3-28 20:41 |显示全部楼层

Observer Pattern

此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
既然聊到了observer, 就占个坑。
Advertisement
Advertisement

发表于 2010-3-28 20:56 |显示全部楼层
此文章由 Cloy 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 Cloy 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 dalaohu 于 2010-3-28 20:37 发表


这张表的排名是以open source project 来排的吧?

哦.倒是不太清楚. 不过开源世界的趋势很多可以从这个里面看出来的. 最近PHP的势头确实很猛. 我也在用.
参考:
http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

[ 本帖最后由 Cloy 于 2010-3-28 20:58 编辑 ]

2010年度奖章获得者

发表于 2010-3-28 21:27 |显示全部楼层

Observer By Definition

此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
Design Patterns Design patterns are recognized solutions to common problems defined originally by the Gang of Four programmers.


The observer design pattern defines a one to many dependency between an object and its dependents. The dependency is created in order to inform the dependents that the object changed its state and therefore the dependents
can react to the change. A very good example of such behavior is the blogging
systems were subscribers are notified whenever a blogger published a new post.
Another real world example can be the MVC architecture pattern which uses the  
pattern.

就是说当 Subject object 有变动是,所有的 Subscribers (observers) 都会被主动通知到。

Real World Example;(参考MSDN)
网上点歌系统。 每当Album的歌被点播时,就要通知到Billing service收费。

abstract Subject
concrete Album (inherits form Subject)

interface Observer
concrete BillingService (implements Observer)

===============================================================================

public abstract class Subject
{
    ArrayList observers = new ArrayList();

    public void AddObserver(Observer observer)
    {
        observers.Add(observer); //注册所有的observer
    }

    public void Notify()
    {
        foreach (var observer in observers)
            observer.Update(this);
    }
}

public class Album : Subject
{
   string name;
   public Album(string name)
   {
       this.name = name;
   }

    public void Play()
    {
        Notify();
        //album play logics;
    }
}

//************* Observers ****************

public interface Observer
{
    void Update(object subject);
}


public class BillingService : Observer
{
    public void Update(object subject)
    {
        if (subject is Album)
           GenerateCharge((Album)subject);
    }

    void GenerateCharge(Album album)
    {
        //billing logics
    }
}

//************* wireup subject and observer ********************

BillingService billing = new BillingService();
Album album = new Album("South Park");

album.AddObserver(billing);
album.Play();

----------------------------------------------------------------------
以上就是observer pattern 的最基本的原型。 MSDN 里接着又把Subject 改为了Interface.
之所以说‘最基本’, 就是说这么土的用法你在real world project 里是看不到的 :)

下一帖说一说演化。

2010年度奖章获得者

发表于 2010-3-28 21:40 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
The built-in features of .NET help you to implement the Observer pattern with much less code. There is no need for the Subject, SubjectHelper, and Observer types because the common language runtime makes them obsolete. The introduction of delegates and events in .NET provides a means of implementing Observer without developing specific types.

In the .NET-based implementation, an event represents an abstraction (supported by the common language runtime and various compilers) of the SubjectHelper class described earlier in "Modified Observer." The Album class exposes an event type instead of SubjectHelper. The observer role is slightly more complicated. Rather than implementing the Observer interface and registering itself with the subject, an observer must create a specific delegate instance and register this delegate with the subject's event. The observer must use a delegate instance of the type specified by the event declaration; otherwise, registration will fail. During the creation of this delegate instance, the observer provides the name of the method (instance or static) that will be notified by the subject. After the delegate is bound to the method, it may be registered with the subject's event. Likewise, this delegate may be unregistered from the event. Subjects provide notification to observers by invocation of the event.

看懂啥意思了吗?

如果你在project 里看到谁手工call 这, notify 那的。 那你可以大声的说太土了! 让我们来refactor吧!
正确的方法是什么? delegate & event!

消化一下, 下一帖来说一下演变后的样子!

2010年度奖章获得者

发表于 2010-3-28 21:52 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
我们先来吧Album 的土拍掉。

public class Album
{
    public delegate void PlayHandler(object sender);
    public event PlayHandler PlayEvent;
    .....

    private void Notify()
    {
        if (PlayEvent != null)
            PlayEvent(this);
    }
}

所有的Observers当然就可以简单的subscribe 这个event!

BillingService billing = new BillingService();
Album album = new Album("South Park");

album.PlayEvent += new Album.PlayHandler(billing.Update);
album.Play();

说道这里大家发现这根我的BackgroundWorker 是不是完全吻合啊。。。。这就叫圆满

评分

参与人数 1积分 +3 收起 理由
hornsay + 3 你太有才了

查看全部评分

2010年度奖章获得者

发表于 2010-3-28 21:58 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
大道于无形。 很多你每天都在用的东西原来都有个说法和来头。但你未必知道,只是用的人多了你也就跟着用了。

面试时如果你被问到 observer pattern...你可能张大嘴巴,吱呀半天说不到点上。

有些挺能编的人,面试是未必能通过。 面试时头头是道的,未必编的好。

[ 本帖最后由 dalaohu 于 2010-3-28 22:02 编辑 ]
Advertisement
Advertisement

发表于 2010-3-29 11:23 |显示全部楼层
此文章由 IsDonIsGood 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 IsDonIsGood 所有!转贴必须注明作者、出处和本声明,并保持内容完整
受教了,关于delegate和event虽然有用但始终觉得概念模糊。谢楼主,回去要好好想想。
头像被屏蔽

禁止访问

发表于 2010-3-29 11:24 |显示全部楼层
此文章由 wtf 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 wtf 所有!转贴必须注明作者、出处和本声明,并保持内容完整
haha, dalaohu也在侃设计模式啊. 我也受教了..

2010年度奖章获得者

发表于 2010-3-29 12:19 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 IsDonIsGood 于 2010-3-29 11:23 发表
受教了,关于delegate和event虽然有用但始终觉得概念模糊。谢楼主,回去要好好想想。


delegate is a pointer to a method/function (as oppose to variables)

event is the trigger point (or say broadcast mech to all listeners)

event can have the type of a delegate.

it's too common you see everywhere in the code something like

this.grdGrid.AfterRowActive += new System.EventHandler(this.grdGrid_AfterRowActivate);

System.EventHandler is actually a delegate (public delegate void EventHandler(object sender, EventArgs e) )
which specify the method signature.

this.grdGrid_AfterRowActivate is the event.

发表于 2010-3-29 13:00 |显示全部楼层
此文章由 IsDonIsGood 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 IsDonIsGood 所有!转贴必须注明作者、出处和本声明,并保持内容完整
Thanks brother!

发表于 2010-3-30 20:36 |显示全部楼层
此文章由 gozh2005 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 gozh2005 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 dalaohu 于 2010-3-26 18:20 发表


event delegate 和 IOC 是两码事。IOC 是通过interface走的。
说道pattern, 坛子里那么多pattern圣手, 模式强人不知为何那么安静了呢?


这个例子很好,因为它其实就不可能是一个pattern的实现。pattern是基于面向对象的概念,用的是interface和多态。
可是当你特别你要求用delegate和generic了以后。这些都不是面向对象的东西,也不是patter能做的了。
我以前理解的delegate就是函数指针,纯面向对象的java一直是没它的,不过java也很奇怪,它有个anonymous function,可以做一些closure的强大的东西。c#到3.5以后才加上。
而generic就更不是面向对象的了。generic出来后我就一直想找一本书能不能告诉我怎么用generic来实现design pattern,我觉得会更简洁。不过我到现在也没见过这样的书。
我个人认为generic其实是在pattern的另外一边。而且你看C#从3.5以后,语法越来越简洁轻七,走的都是ruby的道路。离pattern也是越来越远。

另外,pattern的应用我觉得和软件的methodology也是分不开的。pattern可以让你好好做design,走的是RUP的模式。而现在的这些新的编程方法(generic, delegate, action, ananoymous function, extension method),UML里我都不知道要怎么画?

[ 本帖最后由 gozh2005 于 2010-3-30 20:43 编辑 ]
Advertisement
Advertisement

发表于 2010-3-30 20:52 |显示全部楼层
此文章由 乱码 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 乱码 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 gozh2005 于 2010-3-30 20:36 发表


这个例子很好,因为它其实就不可能是一个pattern的实现。pattern是基于面向对象的概念,用的是interface和多态。
可是当你特别你要求用delegate和generic了以后。这些都不是面向对象的东西,也不是patter能做的 ...


confused

generic本来就是对interface编程的,不隶属于某个pattern我同意(我没有一个个pattern对着比,如果我错了,请纠正我),但也不是跟pattern走的反方向阿。

发表于 2010-3-30 21:00 |显示全部楼层
此文章由 gozh2005 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 gozh2005 所有!转贴必须注明作者、出处和本声明,并保持内容完整
这样说了,没有一个patter是用到generic的。以前最常用的在dofactory上的pattern的例子时,generic 还没出呢。
所以我也在说,我想知道怎么用generic来实现pattern,可是我找不到。

发表于 2010-3-30 21:25 |显示全部楼层
此文章由 乱码 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 乱码 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 gozh2005 于 2010-3-30 21:00 发表
这样说了,没有一个patter是用到generic的。以前最常用的在dofactory上的pattern的例子时,generic 还没出呢。
所以我也在说,我想知道怎么用generic来实现pattern,可是我找不到。


对generic实现具体某一个pattern我也没想过,抱歉。

但个人觉得gof那4个无聊的人把pattern细分成23个(印象中是,错了一定纠正我),除了让大家系统的学习方便,其中一个原因就是大家讨论问题的时候,说起某一个pattern,其他人都能知道怎么回事,就不用太费事的画uml来重新给大家洗脑了。

己然pattern中最重要的就是对interface编程,我觉得generic本身就是一个成功的pattern。


这就像张三丰在武当山顶大敌当前教张无忌太极,张无忌打第一遍还记得80%的拳法,第二遍就记得50%,第三遍记得30%,第四编就全忘了,张三丰这才颔首,”你终于领会了“。

其实太极跟pattern一样,就是一个字:神。 只要领会了一种的精髓,你完全可以创造自己的pattern,不必拘泥于前人的理论,但具体能否超越,就看个人的造化了。

我自觉有点唐僧了,如果口气有冒犯的地方,你多原谅吧,就当我没说过。

[ 本帖最后由 乱码 于 2010-3-30 21:28 编辑 ]

2010年度奖章获得者

发表于 2010-3-30 21:35 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 gozh2005 于 2010-3-30 21:00 发表
这样说了,没有一个patter是用到generic的。以前最常用的在dofactory上的pattern的例子时,generic 还没出呢。
所以我也在说,我想知道怎么用generic来实现pattern,可是我找不到。


鲁迅说过用的人多了,自然就成模式了。 不知道是不是这个道理?

.net 4.0 dynamic 都出了。 大熔炉了。新技术太多太快了, 那些模式都是祖上定的吧?

发表于 2010-3-30 22:22 |显示全部楼层
此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 dalaohu 于 2010-3-26 18:20 发表


event delegate 和 IOC 是两码事。IOC 是通过interface走的。


我说的ioc是比较广泛的概念,表示把一个程序的控制流程交给另外一个程序。比如你程序里的BackgoundWorker把run和compelete工作交给你的客户端程序。ioc可以有很多种实现方式, observer, factory模式都可以用来实现。

你说的ioc我猜是指狭义的那种,Martin Flower给这种IoC定义叫Dependency Injection, 请看下面这段引用于他Blog的话


The question, is what aspect of control are they inverting? When I first ran into inversion of control, it was in the main control of a user interface. Early user interfaces were controlled by the application program. You would have a sequence of commands like "Enter name", "enter address"; your program would drive the prompts and pick up a response to each one. With graphical (or even screen based) UIs the UI framework would contain this main loop and your program instead provided event handlers for the various fields on the screen. The main control of the program was inverted, moved away from you to the framework.

For this new breed of containers the inversion is about how they lookup a plugin implementation. In my naive example the lister looked up the finder implementation by directly instantiating it. This stops the finder from being a plugin. The approach that these containers use is to ensure that any user of a plugin follows some convention that allows a separate assembler module to inject the implementation into the lister.

As a result I think we need a more specific name for this pattern. Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name Dependency Injection.
Advertisement
Advertisement

2010年度奖章获得者

发表于 2010-3-30 22:42 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 flyspirit 于 2010-3-30 22:22 发表


我说的ioc是比较广泛的概念,表示把一个程序的控制流程交给另外一个程序。比如你程序里的BackgoundWorker把run和compelete工作交给你的客户端程序。ioc可以有很多种实现方式, observer, factory模式都可以用来 ...


说的没错我脑子的IOC还真跟DI 等同。。。

你别说那帮整天定义模式,给模式命名的人,我怎么感觉那么想政客呢。。。

[ 本帖最后由 dalaohu 于 2010-3-30 22:44 编辑 ]

发表于 2010-3-30 22:52 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
顶一下。

用的比较多的是Observer.

delegate 在Delphi里没有这样的称呼,不过是用 procedure of TSomething, 是event 的 type.

发表于 2010-3-30 22:55 |显示全部楼层
此文章由 中间人 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 中间人 所有!转贴必须注明作者、出处和本声明,并保持内容完整
confused
generic本来就是对interface编程的,不隶属于某个pattern我同意(我没有一个个pattern对着比,如果我错了,请纠正我),但也不是跟pattern走的反方向阿。


generic跟interface 没有关系。

2010年度奖章获得者

发表于 2010-3-30 23:04 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
占个坑。 Generic by definition.

* generic 有些人叫他 type-safe.

What Are Generics

Generics allow you to define type-safe classes without compromising type safety, performance, or productivity. You implement the server only once as a generic server, while at the same time you can declare and use it with any type. To do that, use the < and > brackets, enclosing a generic type parameter.

Generics Benefits

Generics in .NET let you reuse code and the effort you put into implementing it. The types and internal data can change without causing code bloat, regardless of whether you are using value or reference types. You can develop, test, and deploy your code once, reuse it with any type, including future types, all with full compiler support and type safety. Because the generic code does not force the boxing and unboxing of value types, or the down casting of reference types, performance is greatly improved. With value types there is typically a 200 percent performance gain, and with reference types you can expect up to a 100 percent performance gain in accessing the type (of course, the application as a whole may or may not experience any performance improvements). The source code available with this article includes a micro-benchmark application, which executes a stack in a tight loop. The application lets you experiment with value and reference types on an Object-based stack and a generic stack, as well as changing the number of loop iterations to see the effect generics have on performance.

public class Point<T>
{
   public T X;
   public T Y;
}

You can use the generic point for integer coordinates, for example:

Point<int> point;
point.X = 1;
point.Y = 2;

Or for charting coordinates that require floating point precision:

Point<double> point;
point.X = 1.2;
point.Y = 3.4;

Multiple Generic Types

class Node<K,T>
{
   public K Key;
   public T Item;

   public Node()
   {
      Key      = default(K);
      Item     = defualt(T);
   }
   public Node(K key,T item)
   {
      Key      = key;
      Item     = item;
   }
}

var node = new Node<int,string>();
or
var node = new Node<int,string>(123, "ABC");

说白了generic的引入,就是程序的reusability跟高了一点的

[ 本帖最后由 dalaohu 于 2010-3-30 23:23 编辑 ]

发表于 2010-3-30 23:40 |显示全部楼层
此文章由 gozh2005 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 gozh2005 所有!转贴必须注明作者、出处和本声明,并保持内容完整
仔细想想generic和pattern还是有不同的,generic讲究的是把type抽象出来,type也变成类似data的一个变量。它的type通常是value type. (string, int, double, long etc)。
而pattern是用interface来抽象出来解决一个domain上的问题,比较面向的是类的结构和组合。

不过我一直想说的是其实现在的程序语言越来越强大,都是multi-paradigm的编程模式。好象c#,ruby,java的groovy都慢慢的引入越来越多dynamic programming特性,也不是pure type safe language (编译器或者CLR level的type inference可能同样保证type安全性)。他们可以是面向对象的,面向函数的。很多情形也不是非要用pattern才能做的好看的。真的是够用就好。
Advertisement
Advertisement

2010年度奖章获得者

发表于 2010-3-30 23:49 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 gozh2005 于 2010-3-30 23:40 发表
仔细想想generic和pattern还是有不同的,generic讲究的是把type抽象出来,type也变成类似data的一个变量。它的type通常是value type. (string, int, double, long etc)。
而pattern是用interface来抽象出来解决一个 ...


同意, generic不过是一个新的 data type (or day a type holder) 而起。 跟pattern真的没啥关系吧。

发表回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Advertisement
Advertisement
返回顶部