惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
The GitHub Blog
The GitHub Blog
F
Fortinet All Blogs
Last Week in AI
Last Week in AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
L
LangChain Blog
爱范儿
爱范儿
博客园_首页
Stack Overflow Blog
Stack Overflow Blog
MongoDB | Blog
MongoDB | Blog
博客园 - 三生石上(FineUI控件)
大猫的无限游戏
大猫的无限游戏
宝玉的分享
宝玉的分享
GbyAI
GbyAI
H
Help Net Security
A
About on SuperTechFans
Recent Announcements
Recent Announcements
Hugging Face - Blog
Hugging Face - Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
雷峰网
雷峰网
D
Docker
博客园 - Franky
有赞技术团队
有赞技术团队
G
Google Developers Blog

博客园 - changhai-xuri

[转]VS2005快捷键大全 <转载>C#基础面试题 转载(ASP.NET页面之间传递值的几种方式?) 面试的一些体会 程序之路对我来说有多远呢? 晕!我还是没办法改页面顶部的背景图片 关于开发模式的一点点思考 VB和VSS断绝往来了咋办? JAVA中对象的序列化 C#中的代理(Delegate) Spoolsv占用CPU100%的解决方案 Js文件中调用其它Js函数的方法 设计模式之策略模式在设计一群鸭子中的应用 修改一下博客的式样 软件开发模式--软件开发教父与国内高手论道实录全文 微软公司软件开发模式简介 自己写的使用聚集函数实现多行字串合并处理 (转载)使用自定义聚集函数来实现分组合并字符串 关于ORACLE中插入,更新(MERGE)的使用
设计模式之策略模式探讨初步
changhai-xuri · 2006-11-24 · via 博客园 - changhai-xuri


记得以前刚接触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类的说明。
    也许就这点文字描述还是有点难以弄的明白,可以参考《设计模式之策略模式在设计一群鸭子中的应用