设计模式杂谈

想想疯狂学习设计模式也是10多年前的事了,那个时候对设计模式很是痴迷,而且在工作中或者跟同事讨论某一个问题的时候,总是有意无意的把设计模式带进来,现在想想都好笑。

不常用的设计模式是会忘记的,这不奇怪。如果想熟练在架构或者编码过程中使用设计模式,其实需要对设计模式有深入的了解及思考。当然也不尽然,有时候,即使你完全没看过设计模式,在不经意间你的代码也有可能会符合某个设计模式。但是不可否认一点的是,如果你的代码用上了设计模式,那么它总是会展现很高的扩展性。

先列出经典的23个设计模式,权当帮大家把脑子里的那些设计模式给规整一下:

  • 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
  • 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  • 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

怎么学习设计模式呢,途径很多,网上查资料,看看别人是怎么的学习经历以及相应的代码;买本设计模式的书看。但是你有没有这样的感觉,无论是上面那种,如果你看过后,经过一段比较长的时间,而这期间工作中又没有太多的实践机会的话,你会慢慢的忘记一些设计模式,有印象的也就是经常被大家提起的那些,比如工厂模式,单例模式,适配器模式等等。

依我看,有多种方法可以加深你对设计模式的理解及记忆。首先无论你看网上关于设计模式的资料还是书,都有一个应用场景配合代码来诠释某一个设计模式。那么这种应用场景选取的好不好就显得至关重要。比如工厂方法模式,在你了解简单工厂模式后,一个好的例子是,不同品牌的电脑各自由自己工厂生产,比如联想电脑由联想工厂生产,Dell电脑由Dell工厂生产。建造者模式可以选取的是构造一个人,分成三部分,头,身体和脚。而备忘录模式的适用场景是我们小时候玩的那种RPG游戏,每次在通关大Boss前要保存一下记录,如果通关失败就重现读取进度。所以,尽可能的选择我们工作和生活中涉及到的,而且又在我们记忆里有深刻印象的场景。

另外,当你学习的设计模式越来越多,对单一模式理解越来越深的时候,你有没有发现,有一些设计模式之间有一些相似性,当然这些相似性极有可能会给你的学习造成一些困扰,但是反过来,如果你能清楚的区别这些相似性,你的功力是不是会更深一层了?下面列出一些这样的设计模式供你思考:

  • 工厂方法模式和抽象工厂模式
  • 享元模式和单例模式
  • 代理模式和装饰模式
  • 中介者模式和门面模式

关于设计模式的学习,前面也提到了看书。记得大话设计模式那本书出来以后,我还买了一本,读读觉得挺有意思。但是同样有一个感受是,里面参杂了很多无效的,干扰性的信息。这可能跟我那个时候对大多数设计模式已经了解有关。如果你是一个新手,又觉得设计模式晦涩难懂,那么这本书可能还真的挺适合你,但是如果你有一定的编码基础,又在工作中实践了设计模式,从而积累了一些设计模式的经验,你再回过头去看,你或许跟我的感觉一样。

从我的视角,学习设计模式的一条有效的途径是:

  • 不要买书,网上关于设计模式的文章和资料虽然很散,但是对学习来说,已经足够了,唯一要做的就是鉴别那些能快速帮助到你。
  • 直接网上搜索一下你想学习的设计模式,先看一篇做一个初步的理解,如果觉得看的不是很懂,那么切换到另外一篇,这里不得不提醒的是,设计模式学习过程比较枯燥,不能指望某一篇文章会让你迅速的大彻大悟。如果初步理解后,然后在看看别的文章是否讲的更加易懂,同时又让你印象深刻,可以在这个基础上做一个对比。
  • 最后,代码是少不了的。这也是至关重要的一步,好处颇多。首先你看着别人的代码觉得你明白了,但是事实是不见的你能把完整代码写下来;二来这也会加深你对当前设计模式的理解;最后一段时间过后,你也许有一些忘记,回过头来看你自己写的代码,会短时间内把这块精炼过的知识捡起来,否则,你又会重复上面的过程,搜索-比较-理解。

那么我们的工作中是怎么使用设计模式的呢?还记得当年Hibernate刚出来的时候,那个时候Spring还没出来,如果想通过Hibernate保存数据,首先必须有一个Session对象,而这个对象的产生就是使用工厂模式。

很多时候设计模式在你设计编码以及重构过程中不知不觉的就被使用了。记得当年开发一个企业信息系统,里面有三块业务涉及到流程审批,那么工作流的使用就在所难免。基于当时团队的研发实力以及工期,自己开发一个显而易见不合适,所以就买了一个外部基于J2EE的产品。因为三块业务由不同人负责,所以都在自己部分直接调用工作流提供的API,刚开始的时候,处于开发阶段,没太多问题,但是后来因为工作流产品存在一些bug,所以有一些api发生改变,这就引起两个问题,一个是这三块业务涉及到的代码都需要修改,另外有一块业务因为沟通不畅而没有做相应的修改。所以最后决定把所有和工作流产品有交互的代码封装在几个核心类里。后来想想,这其实是典型的门面模式,只是当时没意识到而已。

当在工作中设计一个系统时,尤其在做一些架构设计或者基础编码时,在避免过度设计的前提下要多考虑当前系统扩展性,从业务层面考虑怎么分离关注点。设计模式的使用切记不要为了设计模式而设计模式,但是设计一个扩展性良好的系统是做IT的一致的目标,我想这个大家不会否认。

想想现在谈设计模式的人少了,为啥呢?个人感觉现在处于一个快速的时代,互联网快速验证模式是否正确,谁还有心思去考虑当前代码怎么设计,说不定,今天编写的代码,明天就全部弃而不用。现在的IT人才也是浮躁的,技术发展如此之快,大量知识需要学习,有多少人愿意在代码设计(日后扩展)上多花功夫?

不管怎么说,设计模式的学习以及实践是有必要的,它不会帮你写出多么漂亮和优雅的代码,但是符合设计模式的代码一定在扩展性上更胜一筹。而且很多时候,对一个产品或者一个通用组件,会有多个版本的升级,这自然会涉及到代码的修改。而修改代码的人不一定就是自己,所以具有良好扩展性的代码也在代码层面做了很好的人与人之间的沟通。

发表评论

电子邮件地址不会被公开。 必填项已用*标注