[Study Note] Patterns in Practice 20100402

这一系列文章是 Jeremy Miller 在 MSDN Magazine 上从 June, 2008 开始的一个专栏,大概是每两个月一篇吧。其中 2008 年的四篇文章关注一些 software design fundamentals 基本的设计理念,学习一下。

[The Open Closed Principle]

Agile Software Development Principles, Patterns, and Practices. Robert C. Martin

software entities should be open for extension but closed for modification

Single Responsibilty Principle

a class should have one, and only one reason to change

在这里 Miller 举了一个可怕的例子,busy class—— OrderProcessingModule,做了几乎所有需要的事情:从配置文件获取连接字符串 grabbing configuration file information;从数据库获得订单实例 doing data access;更新订单,处理国际订单,判断订单大小并调用不同的处理函数 running business rules for order processing;最后,如果订单已经准备好了,那么发货 transforming completed orders into shipments……

An easy way to follow the Sigle Responsibility Principle is to constantly ask yourself whether every method and operation of a class is directly related to the name of that class.

The Chain of Responsibility Pattern

我在看到这段文章之前,一直没有想明白如何替换代码中过多的 if…else.. 或者是 switch 代码段落,虽然知道这是属于坏味道的一种。

其实之前上课的时候曾经听到这部分的内容,看书的时候也见到类似的代码,但是却一直没有把这些联系起来。非常简单的就是,你只需要增加一个 Interface

public interface IOrderHandler

{

    void ProcessOrder(Order order);

    bool CanProcess(Order order);

}

然后就可以把业务逻辑中的那些条件分支,分别放置那些实现了这个接口的类里面,然后在 OrderProcessingModule 中采用 constructor injection 的方式(我不知道这样说对不对)调用。

public class OrderProcessingModule

{

    private IOrderHandler[] _handlers;

    public OrderProcessingModule()

    {

        _handlers = new IOrderHandler[]

        {

            new InternationalOrderHandler(),

            new SmallDomesticOrderHandler(),

            new LargeDomesticOrderHandler(),                               

         }

    }

    public void Process(OrderStatusMessage orderStatusMessage, Order order)

    {

        updateTheOrder(order);

        IOrderHandler handler = Array.Find(_handlers, h => h.CanProcess(order));

        handler.ProcessOrder(order);

    }

    …

}

这里的代码并不完整,不过有点奇怪为什么 _handlers 设置为 IOrderHandler[] 而不是 List<IOrderHandler> ? 难道就是为了后面的 Array.Find() ? 之前还在困惑,为什么没有使用 foreach,后来才看明白在业务逻辑里面是 if…else if…else 的关系。

见识了一个新的 method —— find(),在 Array 和 List(T) 里面分别有其实现。

Double Dispatch

Miller 举了一个例子来说明什么是 Double Dispatch。假如你要让下属完成一件事情,而你并不知道具体应该如何去做;这时你打电话请教去请教某位大牛,与其让大牛给你讲解之后由你转述,那么还不如让大牛直接和你的下属去说明。

这里的例子是关于 Model View Presenter (MVP) 和 Application Controller pattern 的,之前在写一个简单的 WinForm 程序的时候,采用了丑陋的架构,真是应该提前看看这篇文章。

Liskov Substitution Principle

the most common manifestation of the Open Closed Principle is using polymorphism to substitue an existing part of application with a brand new class.

functions that use pointers on references to bass classes must be able to use objects of derived classes without knowing it.

如果简单一点的理解,就是说如果你的方法适用于某一个基类或者是接口,那么所有继承了这个基类或者接口的子类都可以适用于该方法;更进一步,我觉得 Liskov Substitution Principle 并不是要我们使用子类去替换父类/接口,而是说,亲生的兄弟姐妹(实现了同一个基类或者接口的不同子类)之间可以互相替换。

Finding Closure

the Open Closed Principle is only realized by polymorphism if a class only depends on the public contract of the other classes it interacts with.

treat the Open Closed Principle as a design vector rather than an outright goal.

posted on 2010-04-02 12:37  zhaorui  阅读(147)  评论(0编辑  收藏  举报

导航