哪些设计模式最值得学习

最近又在首页看到几篇设计模式相关的学习随笔。回想起来,这几年在园子里发布的有关设计模式的随笔都有一个共同的特点。那就是Factory和Singleton居多,如果是系列的,也往往是从这两个模式开始的。由于能够坚持把《设计模式》中所有模式都写完的非常少,所以基本上也很少见到有关其它模式的随笔。

 

这种情况也很好理解,因为《设计模式》这本书就是按照这个顺序来的。最先讲述的就是Abstract Factory模式,于是它排第一也无可厚非;排第二的Builder基本不太容易见到;第三的Factory Method由于也叫“Factory”所以往往和Abstract Factory放在一起,或者干脆就混淆了; 第四的Prototype也不是太容易见到;第五位的Singleton简单易懂,易学易用。而再往后的模式,恐怕作者们就没什么耐心学下去了……这可能就是为什么Factory和Singleton出现频率如此之多的原因吧。

 

《设计模式》已经出版超过15年了,到今天已经不是什么新鲜的东西了,可以说正在由“绝招”慢慢向着“基本功”转变着。然而,这种学习模式的方式方法却实在令人担忧。

 

Abstract Factory在实际中并不常见,因为它需要你有两套并行的继承体系,需要对同一个抽象有多于一种的实现方式。这种复杂的系统可以说不是每个领域,每个开发人员都能遇到的。在某些特定的领域可能很常见,但是在大多数领域并不需要这么复杂的对象创建方法。这就造成了很多人“杀鸡用宰牛刀”,用复杂的方式,解决不那么复杂的问题。后果是增加了不必要的复杂度,给系统维护增加了困难。

 

另一个模式Singleton,由于实现简单,意图“似乎”也很明显。被很多人用来作为“优化”的一种方式。通过这种方式来节省内存空间,减少对象实例。但是单一实例本身就等同于全局变量,而全局变量在几十年前就已经被证明是“反模式”了,用另一种形态的全局变量来代替另一种形态的全局变量有什么好处么?问题在与,Singleton的“意图”并不在于优化,而是在于“妥协”。Singleton的目的在于保证对象有单一的实例,这是因为对象必须要有单一的实例,如果存在多个实例,可能会引发错误。也就是说,Singleton以牺牲程序的清晰和可维护性,来达到保证程序正确的目的。这跟本就和优化八竿子打不着,这完全是一种设计上的妥协,牺牲一些好处来获取更大的好处。如果仅仅是为了节省几个对象实例,而非程序的正确才使用Singleton,那就是丢了西瓜拣芝麻。况且节省那几个实例也跟本就不可能对程序的性能有太大的影响(特殊领域除外)。

 

人的时间是有限的,23个模式也不是都那么常用,哪些模式才是最经常用到的,才是最值得学习的呢?

 

第一梯队:Iterator,Observer,Template Method,Strategy

Iterator:LINQ,foreach这不都是Iterator么。

Observer:MVC的核心,.NET中事件就是Observer。

Strategy:对同一个行为有不同实现的时候,如果考虑将行为的实现委托(不是.NET中的委托)给另一个类,那就用到了Strategy。通过这种方式,可以简单的替换算法的实现类,来达到更换算法的目的。

代码
class Foo
{
  
private IBar bar;
  
public Foo(IBar bar)
  {
    
this.bar = bar;
  }

  
public void DoSomething()
  {
    
//some code
    bar.DoWhatYouWant();
    
//some code
  }
}

class A : IBar
{
  
public void DoWhatYouWant()
  {
    
//do in A's way
  }
}
class B : IBar
{
  
public void DoWhatYouWant()
  {
    
//do in B's way
  }
}

Template Method:一个算法的同一个步骤有不同的实现,通过继承来实现。这种方式通过创建子类来改变算法的实现和行为。ASP.NET WebForm中Page的OnInit,OnLoad等事件,就是Template Method

代码
class Foo
{
  
public void DoSomething()
  {
    
//some code
    DoWhatYouWant();
    
//some code
  }
  
protected abstract void DoWhatYouWant();
}

class A: Foo
{
  
protected override void DoWhatYouWant();
  {
    
//do in A's way
  }
}

class B: Foo
{
  
protected override void DoWhatYouWant();
  {
    
//do in B's way
  }
}

面向对象的一个重要特点就是多态,也就是对于同一个动作有不同的行为。Strategry通过委托的方式,将一个算法的不同实现委托给其它类;Template Method通过继承的方式,让子类实现算法的可变部分,基类则处理算法的流程和不变部分。近年来组合优于继承的观点已经成为主流,因此Strategy的处境频率相对高一些,但是Template Method在解决简单问题的时候更好用,只要注意继承层次不要太多(<=3)就好。

 

第二梯队:Adapter,Facade,Decorator

Adapter:当你需要使用第三方库,但是又不想太依赖于它的API,以便于今后在需要时可以方便的切换到另一个库的时候,你就需要在你的代码和第三方API之间放置一个抽象层,也就需要用Adapter模式了。比如你想使用log4net,如果直接在代码中到处引用log4net的API,将来有一天需要切换到另一个库比如EntLib,你的改动量可就大了去了。如果在一开始就自己设计一个API,在代码中使用自己的API,再用Adapter模式将log4net的API包装到自己的API中,如果有一天想要切换到Entlib,只要为EntLib在写一个Adapter就行了。对于IoC框架也是一样的。不过需要注意的是,如果第三方库的API接口非常庞大,使用Adapter就会很麻烦,因为你需要包装太多的东西,那么使用Adapter可能就不是一个太好的主意。或许谨慎考虑确定一个不太可能会变化的第三方库更好一些。

Facade:基本上用于简化API,隐藏细节,在一个系统中,高层模块调用低层模块时,如果低层模块API比较复杂,而高层模块并不需要这种复杂度,那么加一个Facade,可以简化高层模块使用API的难度。

Decorator:为一个类的行为增加行为,比如ASP.NET MVC中的Action Filter。

 

第三梯队:Command,State,Composite

Command:统一接口,Undo/Redo。

State:当你的model有多种状态,model的行为在每种状态下并不一样的时候,就需要用State。如果你有多个相似的Switch,那也可能意味着需要用State来代替Switch。

Composite:ASP.NET WebForm的Page和Control就是一个例子。

 

这些模式和分类只是凭我的感觉,并没有任何实际的数据做支持,而我的感觉也只来源于我所接触到的领域和代码。 希望同学们也可以提供自己接触到的代码中,最常见到和用到的模式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436072.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【转】000.DICOM:DICOM标准学习路线图(初稿)!!!!!!!!!!!!

转自&#xff1a;https://zssure.blog.csdn.net/article/details/49231303 题记&#xff1a; DICOM医学图像处理专栏撰写已有两个年头&#xff0c;积累了近百篇文章。 起初 只是用于记录自己科研、工作中遇到的疑难问题&#xff0c;专注于图像处理&#xff08;主要是医学图像…

对比 SQL Server 2005 和 Oracle

在 Microsoft Windows Server 上运行的 SQL Server 2005&#xff0c;为企业级关系数据库和分析解决方案提供了一个平台&#xff0c;在安全、可用性、与 Visual Studio 的整合度&#xff0c;从小企业到大企业的可扩展性以及低费用方面胜过了Oracle 10g。探索下列信息以发现在 这…

【转】pacs定位线_C#开发PACS医学影像处理系统(十五):Dicom影像交叉定位线算法

转自&#xff1a;https://www.cnblogs.com/Uncle-Joker/p/13686618.html 1.定位线概念&#xff1a;某个方位的影像在另一个方向的影像上的投影相交线&#xff0c;例如横断面(从头到脚的方向)在矢状面(从左手到右手)上的影像投影面交线。 举个例子&#xff1a;右边的是MR(核磁共…

C++设计模式之 简单工厂模式讲解(历史上最简单明白的例子)

工作之余&#xff0c;在看资料过程中发现一个极易理解的简单工厂模式的例子&#xff0c;自己亲自试练一番,感觉对这个设计模式不熟悉的朋友&#xff0c; 一看马上就知道是什么回事了。 简单工厂模式根据提供给它的数据&#xff0c;返回几个可能类中的一个类的实例。通常它返的…

【转】.NET Core 可移植类库PCL Portable Class Library详解

转自&#xff1a;https://www.kaifaxueyuan.com/server/dotnet-core/dotnet-core-portable-class-library.html 在这一章中&#xff0c;我们将讨论什么是PCL (可移植类库)&#xff0c;以及为什么我们需要PCL。为了理解这个概念&#xff0c;让我们打开上一章创建的类库项目文件夹…

设计模式C++实现(4)——原型模式、模板方法模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性&#xff1a;封装、继承、多态&#xff0c;真正领悟设计模式的精髓是可能一个漫长的过程&#xff0c;需要大量实践经验的积累。最近看设计模式的书&#xff0…

【转】医疗业务学习笔记--DICOM协议的基础内容!!!!!!!!!!

转自&#xff1a;医疗业务学习笔记--DICOM协议的基础内容 - 知乎 本文首发于“雨夜随笔”公众号&#xff0c;欢迎关注。 DICOM协议是医疗领域对如何处理、存储、打印和传输医疗图片的一系列标准。DICOM是 Digital Imaging and Communications in Medicine 的缩写&#xff0c;…

linux去掉u盘写保护,最全面win10系统下u盘写保护怎么去掉

U盘写保护就是只能读取U盘中的内容&#xff0c;但是却不能修改或者将其它文件保存在U盘&#xff0c;有时候U盘写保护妨碍我们使用&#xff0c;有些朋友想要将其接除&#xff0c;对此&#xff0c;我给大家整理了win10移除写保护的方法&#xff0c;希望能帮助到你U盘是通过USB接口…

设计模式C++实现(5)——桥接模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性&#xff1a;封装、继承、多态&#xff0c;真正领悟设计模式的精髓是可能一个漫长的过程&#xff0c;需要大量实践经验的积累。最近看设计模式的书&#xff0…

【转】CT基本概念(必须掌握)!!!!!!!!!!!!!!

转自&#xff1a;http://www.bmecn.com/wenku/knowledge/988.html 1.像素&#xff08;Pixel&#xff09;和体素&#xff08;Voxel&#xff09; 像素&#xff08;Pixel&#xff09;是构成图像的基本单位&#xff0c;即图像可被分解成的最小的独立信息单元。因为图像是二维的&a…

推荐笔记本用户使用的硬盘。。。2.5”战胜台式机硬盘 日立7K320-250GB

2.5”战胜台式机硬盘 日立7K320-250GB 相关评测文章参考&#xff1a;http://www.beareyes.com.cn/2/lib/200808/07/20080807034_8.htm 转载于:https://www.cnblogs.com/bingdongli/archive/2008/10/05/1304169.html

设计模式C++实现(6)——适配器模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性&#xff1a;封装、继承、多态&#xff0c;真正领悟设计模式的精髓是可能一个漫长的过程&#xff0c;需要大量实践经验的积累。最近看设计模式的书&#xff0…

设计模式C++实现(7)——装饰模式

装饰模式&#xff1a;动态地给一个对象添加一些额外的职责。就增加功能来说&#xff0c;装饰模式相比生成子类更为灵活。有时我们希望给某个对象而不是整个类添加一些功能。比如有一个手机&#xff0c;允许你为手机添加特性&#xff0c;比如增加挂件、屏幕贴膜等。一种灵活的设…

较为周全的Asp.net提交验证方案 (下)

接上篇。 下面要对这个生成的“提交验证”类进行功能扩展&#xff0c;通过.Net的“部分类”或“扩展方法”技术都可以轻松实现&#xff0c;这里采用的是“部分类”技术&#xff1a; 引用生成的ADO.NET Entity Framework数据模型的命名空间&#xff0c;且声明为部分类。 书写静态…

linux 14.04安装方法,Ubuntu 14.04 安装配置GNOME经典界面

Ubuntu 14.04上基本完美支持GNOME经典界面&#xff0c;安装配置步骤如下&#xff1a;1. 安装gnome-session-flashbacksudo apt-get install gnome-session-flashback这个包安装后&#xff0c;注销后&#xff0c;在登录界面就能选择GNOME Flashback (Compiz)这个桌面环境了。2. …

设计模式C++实现 —— 策略模式

策略模式是指定义一系列的算法&#xff0c;把它们一个个封装起来&#xff0c;并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。也就是说这些算法所完成的功能一样&#xff0c;对外的接口一样&#xff0c;只是各自实现上存在差异。用策略模式来封装算法&#…

【转】DIB位图(Bitmap)的读取和保存

转自&#xff1a;https://www.cnblogs.com/wangguchangqing/p/5417444.html 设备无关位图&#xff08;Device Independent Bitmap&#xff09;是可以保存在磁盘的位图文件&#xff0c;可以从磁盘读取到内存或者从内存保存到磁盘上。它的文件结构是标准化的&#xff0c;可以在W…

【转】DCMTK各模块说明!!!!!!!

转自&#xff1a;https://blog.csdn.net/Kelvin_Yan/article/details/50765693 有删改 原文来自wiki DCMTK&#xff1a;http://support.dcmtk.org/redmine/projects/dcmtk/wiki/modules 各模块说明 These are the modules of the public DCMTK toolkit (version 3.6.0): 关…

【转】DICOM医学图像处理:基于DCMTK工具包学习和分析worklist

转自&#xff1a;https://blog.csdn.net/zssureqh/article/details/38775315 背景&#xff1a; DICOM3.0协议中有介绍关于worklist的部分。简而言之&#xff0c;worklist可以看做是放射科设备从医院RIS系统中自动读取患者信息的一种“通信协议”&#xff0c;可以指存储在RIS系…

【Visual C++】游戏开发笔记三十五 站在巨人的肩膀上:游戏引擎导论

看到在留言中很多朋友提到不太清楚DirectX与游戏引擎的区别的问题&#xff0c;在这里浅墨就专门把自己对游戏引擎的一些理解写成一篇文章&#xff0c;作为我们《Visual C游戏开发》专栏的游戏引擎导论&#xff0c;也希望能通过这篇文章&#xff0c;能让大家有所启发&#xff0c…