Bruce Xiao 的程序生活

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
设计模式之策略模式在设计一群鸭子中的应用
记得以前刚接触JAVA程序的时候,申请一个QQ群,结果被拒绝,回复是:你懂设计模式和框架不?真是让人汗颜!
近日看了一篇有关策略模式的文章,感觉写的不错,原文是PDF,不便于大家在网页上阅读,于是自己按照其大意进行了组织和整理了一下,发出来大家共赏


使用模式最好的方式是:「把模式装进脑子中,然后在你的设计和已有的应用中,寻找何处
可以使用这些模式。」以往是代码复用,那么现在则是经验复用。

让我们来看看什么叫策略模式?
『策略模式』把易于变化的行为分别封装起来,让它们之间可以互相替换, 让这些行为的变化独立于拥有这些行为的客户。

听起来有些过于概括了,在实际运用中怎么处理才能完成它所描述的让让这些行为的变化独立于拥有这些行为的客户呢?
第一个设计原则:
   找出应用中可能需要变化之处,把它们独立出来, 不要和那些不需要变化的代码混在一起。
也就是说: 如果每次新的需求一来, 都会变化到某方面的代码, 那么你就可以确定, 这部分的代码需要被抽出来, 和其他闻风不动的代码有所区隔。
把会变化的部分取出并封装起来,以便以后可以轻易地扩充此部分,而不影响不需要变化的其他部分。这样的概念很简单,几乎是每个设计模式背后的精神所在。
所有的模式都提供了一套方法让「系统中的某部分改变不会影响其他部分」。
这样的结果如何?代码变化之后,出其不意的部分变得很少,系统变得更有弹性。
第二个设计原则:
针对接口编程」真正的意思是「针对超类型(supertype)编程」。
这里所谓的「接口」有多个含意,接口是一个「概念」,也是一种Java的interface构造。你可以在不涉及Java interface的情况下,「针对接口编程」,关键就在多态。
利用多态,程序可以针对超类型编程,执行时会根据实际状况执行到真正的行为,不会被绑死在超类型的行为上。
「针对超类型编程」这句话,可以更明确地说成变量的声明类型,应该是超类型,通常是一个抽象类或者是一个接口,
如此,只要是具体实现此超类型的类所产生的对象,都可以指定给这个变量;这也意味着,声明类时,不用理会以后执行
时的真正对象类型!
看看下面这个简单的多态例子:假设有一个抽象类Animal,有两个具体的实现(Dog与Cat)继承Animal。

public abstract class Animal{
  
public abstract void makeSound();
}

public class Dog extend Animal{
  
public void makeSound(){
   
//汪汪叫;
  }

}

public class Cat extend Animal{
   
public void makeSound(){
    
//喵喵叫;
   }

}

「针对实现编程」,作法如下:

Dog d = new Dog();
d.makeSound();
//声明变量d为Dog类型(是Animal的具体实现) ,会造成我们必须针对实现编码

但是「针对接口/超类型编程」,作法会如同下面

Animal animal = new Dog();
animal.makeSound();

更棒的是,子类型实例化的动作不再需要在代码中硬编码,例如new Dog ( ),而是可以通过另外的getAnimal()在运行时才指定具体实现的对象

= getAnimal();
a.makeSound();    
//我们不知道实际的子类型是「什么」.. . 我们只关心它知道如何正确地进行 makeSound() 的动作就够了。

第三个设计原则
  多用组合,少用继承。
  在设计时你会发现,对象的一些行为往往易于改变,采用继承时,超类的形为特性的改变会涉及到的有子类的改变,扩展性变得不够好,
  按第一原则把这些易于变化的行为抽取出来,按第二原则采用接口来管理每一类形为,让具体的形为类去继承这些接口,
  每一种形为之间不再有关系,对于主体类涉及到哪些形为,我们就把它们组合到一起好了。这样通过组合建立起来的系统具有很大的弹性,
  我们就可以在运行时动态地改变行为,只要组合的行为对象,符合正确的接口标准即可。
  这好比我们要设计一Animal的类,不管Animal有一些共同的特性,那让每一种Animal去继承好了,不过不同的Animal之间有许多不同的形为,
  我们把这些行为按不同类写成接口,如能说,能听等, 具体的怎么听、怎么说行为由不同的类去实现听、说接口,我让Animal拥有听、说
  的接口变量,而不去管它怎么听和怎么说,而对于继承Animal的子类,我们就把具体的怎么听和怎么说组合给它就可以了。我们每发现新Animal子类有了新的行为,
  也并不会涉及以前的行为和Animal的子类的改变。甚至可以让Animal的子类在运行时动态的获得行为的改变了。

注:这篇文章是据一篇关于策略模式的文章整理得来,有些地方有一些改动和添加。欢迎大家多多批评、指证!
    关于策略模式的定义原文为:『策略模式』定义了算法族,分别封装起来,让它们之间可以互相替换, 此模式让算法的变化独立于使用算法的客户。
    所谓算法族在原文中即指行为。
    在第三个设计原则里添加了利用Animal类的说明。
    也许就这点文字描述还是有点难以弄的明白,可以参考《设计模式之策略模式在设计一群鸭子中的应用

posted on 2006-11-26 10:21  Bruce Xiao  阅读(213)  评论(0编辑  收藏  举报