定义设计模式

定义设计模式

定义

  • 定义模式是在某个情境(context)下,针对某个问题的某种解决方案

下面我们来逐步了解定义中所提到的情境、问题、解决方案。

  • 情境就是运用某个模式的情况,这应该是会不断出现的情况,很常见一般的情况。
  • 问题是你想在某情境下要达到的目标,在这种情境下的约束。
  • 解决方案就是你所追求的:一个通用的设计,用来解决约束,达到目标

接下来我们可以重新去定义这个设计模式

  • 定义(详细):如果你发现自己处在某个情境下,面对着所欲达到的目标被一群约束影响着的问题,然而,你能够应用某个设计,克服这些约束并达到该目标,将你领向某个解决方案。
  • Christopher Alexander的原话 :每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,你就能一次又一次使用该方案而不必重复劳动。

举个简单的例子:

  • 情境:我的自行车坏了
  • 问题:我如何才能准时上班
  • 解决方案:我可以坐公交去上班。

这样定义所需要的三部分我们全都有了,我们有一个问题,这个问题包括去上班的目标的,时间空间的约束,可能还有其他的影响因素;我们也具有情境,也就是自行车坏了,我们也有拥有一个解决方案,让我们解决时间和空间的约束。虽然这三部分我们都有,但这并不算是一个真正的模式,因为自行车不能每天都坏,情境缺乏一般性,不是应用于反复出现的问题。

除了上述情况之外,它在某些方面也不符合规定,,首先,别人想要在自己的特殊问题上采用这个方式可能并行不通,如果汽车坏了,坐公交去上班可能依旧会迟到,其次,它也违反了模式所应具备的一个重要而简单的特性:它没有一个名字!如果没有名字,一个模式无法变成开发人员之间共享的词汇。

幸运的是,模式并非只是被描述成简单的问题,情境和解决方案,我们有更好的方案能描述模式,并将它们收录进“模式类目”中。

Q&A

  • Q: 稍微改变某个模式的以符合我的设计,这样可以吗?
    • A:你当时可以改变模式。想设计原则一样,模式不是法律或者准则,模式时一种指导方针,你可以改变模式来符合你的需要。我们也说过,真实世界的许多实例,都不是完全条条框框地符合经典的设计模式。然而。当你在改变模式的时候,最好在文档中注明它与经典的设计模式的差异。这样一来,其他的开发人员就能够很快的认出你用的这个模式,并了解两者的差异。
  • Q:我要从哪里取得模式类目?
    • A:第一个:也就是最重要的设计类目是Gamma,Helm,Johnson,Vlissides(俗称四人帮又名GOF)所著的《设计模式:可复用面向对象软件的基础》(英文名:DesignPatterns:Elements of Reusable Object-Oriented Software).这个类目列出了23个基本模式。 第二个:另外许多将焦点放到不同领域(例如:企业软件,并发系统、业务系统)的模式类目,比如WEB后端对应也有许多相应的设计模式。DAO,Servlet等等,还得学啊,问题很大,居然词穷!- -!才刚刚开始呢。

模式类目

模式类目是一种更好的描述模式的方式。

  • 它描述了某个模式的意图模式类别别名动机适用性结构参与者协作效果实现代码示例已知应用相关模式
    • 意图:简短地描述该模式的作用。你也可以把它看作是模式的定义
    • 模式类别:描述模式属于哪种类别,当下主流的模式模式分类是三种:创建型模式,行为型模式,结构型模式。
    • 别名:模式的其它名称
    • 动机:给出了问题以及如果解决问题的具体场景
    • 适用性:描述模式可以被运行的场合(偏概括)例如:Decorator模式可以在不影响其它对象的情况下,以动态、透明的方式给单个对象添加职责行为。
    • 结构:用UML图去描述模式运作类与类之间的关系
    • 参与者:描述在此设计中所涉及到的类和对象在模式中的责任和角色。
    • 协作:告诉我们,参与者如何在这个模式中协作
    • 效果:描述采用这个模式之后产生的效果:优点和缺点
    • 实现:提供了你在实现该模式时需要使用的技巧,以及你应该需要注意的点
    • 代码示例:提供代码的片段,可能对你的实现有所帮助。
    • 已知应用:描述已经在真实系统中使用的模式的例子
    • 相关模式:描述了这个模式与其它模式的关系,与其它模式的相同点,不同点,便于让你们区别模式,更加深入地理解模式。

模式分类

随着发掘的设计模式数目增加,越来越有必要将模式进行分类。好将它们组织起来,以简化我们寻找模式的过程,并让同一群组内的模式好进行互相比较,更加方便理解。

模式的分类方式有很多种,最广为人知的分类方式有两种:

  • 第一种是根据模式的目标目的分成三个不同类别:
    • 创建型模式:创建型模式涉及到对象实例化,这类模式都提供了方法,将客户从所需要的实例化的对象中解耦
    • 行为型模式:行为型模式涉及到类和对象如何交互和分配职责
    • 结构型模式:结构性模式可以让你把类或对象组合到更大的结构中
  • 第二种是根据模式的范围分,指定模式主要用于类还是用于对象
    • 类模式: 类模式描述类之间的关系如果通过继承定义。类模式的关系是在编译时建立的
    • 对象模式:对象模式描述对象之间的关系,而且主要是利用组合定义。对象模式的关系通常在运行时建立,而且更加动态,更有弹性。

设计模式空间

分类标准具体类别(按范围)按目的按目的按目的
具体类别(按目的)创建型行为型结构型
按范围Factory Method(工厂方法)Interpreter(解释器模式),Template Method(模板方法)Adapter(类适配器 Java中无法实现)
按范围对象Abstract Factory(抽象工厂),Builder(生成器),Prototype(原型),Singleton(单例)Chain of Responsibility(责任链),Command(命令),Iterator(迭代器),Mediator(中介者),Memento(备忘录),Observer(观察者),State(状态),Stategy(策略),Visitor(访问者)Adapter(对象适配器),Bridge(桥接),Composite(组合),Decorator(装饰器),Facade(外观),Flyweight(享元),Proxy(代理)

关于分类的意义,举个例子,就拿汽车来讲吧:汽车有许多不同的款式,我们一般把汽车分成几类,例如:经济车、跑车、旅行车、卡车和豪华轿车,一旦你有了分类,你就可以很方便这么说:“如果你想从硅谷开车到洛杉矶,那么跑车将会是最好的选择。”或者“因为石油的市场状况日益恶化,应该购买经济车,比较省油。”

有了分类,能够便于思考,先找出大类,再从大类中找小类,就好比数据库一样,这样可以提高检索速度,提高效率。

用模式去思考

下面是一份快速指南,可以帮助你开始“用模式思考”,所谓”用模式去思考“,意识是说,能够看着设计,体会在什么地方能自然适用,在什么地方则不会。

KISS原则(Keep It Simple and Stupid)

首先,当你设计时。尽可能地用最简单的方式解决问题,你的目标应该是简单,而不是“如何在这个问题中应用模式”,千万不要认为,如果没有使用模式解决某个问题,就不是经验丰富的开发人员。如果你能够保持简单的设计,那么你将会得到其他开发人员的欣赏和尊敬。正确的说法是,为了让你的设计简单而又弹性,有时候使用模式时最好的方法。

设计模式并非万金油。

如你所知道的,模式时解决一再发生的问题的通用方案,模式已经被许多开发人员实际测试过。所以,当你需要某个模式的时候,可以放心地使用它,毕竟你知道这个模式已经身经百战。

然而,模式并非万灵丹,你不能把模式插入,编译,然后就早早地去吃午餐,药使用模式,你需要考虑到模式对你的设计其他部分所造成的后果(有优点也有缺点)。

何时使用模式?

啊……这是最重要的问题,什么时候使用模式?当你在设计的时候,如果确定在你的设计中可以利用某个模式解决某个问题,那么就使用模式!如果有更简单的方案,那么在决定使用模式之前应该先考虑这个方案。

如何知道何时适合一个模式,这就需要经验和知识。一旦你确定一个简单的解决方案无法满足你的需求,应该考虑这个问题以及相关约束——这可以帮你将问题对应到一个模式中,如果你对于模式有很深的认知,就可能知道什么模式适合这样的情况。否则,就花些时间调查一下可能会解决这个问题的模式,多去查阅一下模式类目,模式类目中的意图和应用部分会特别有用。一旦找到了一个看起来适合的模式,要先确定你是否能够接受这个模式所带来的后果,已经对设计其他部分的影响,如果一切看起来都很好。就用它吧。

有一种情况,即使有更简单的解决方案,你仍然想要使用模式,这种情况就是你预期系统在未来会发生改变。正如我们所见过的,找出你的设计中会改变的区域,通常这是需要模式的迹象,但是务必要确认一件事,加入模式时要应对可能发生的实际改变,而不是假想的改变,就是说比如你设计一个糖果机,可能和糖果机很受欢迎,需要多个出口,或者有新品要添加进入糖果机,这就是可能发生的实际改变,比如让糖果机可以玩LOL,这TM就是假想的改变!

并非只有在设计时才考虑引进模式,重构的时候也要这么做。

并非只有在设计时才考虑引进模式,重构的时候也要这么做

重构就是通过改变你的代码来改进它的组织方式的过程。目标是要改变其结构,而不是其行为。这是一个很好的时机,可以重新检查你的设计来看看是能够利用模式让它有用更好的结构。比方说,代码内如果充满了条件语句,这可能以为这需要使用状态模式,,或者意味着,应该利用工厂模式将这些具体的依赖消除掉。许多书都介绍如果利用模式进行重构,而随着技艺的增长,你需要更多的狩猎这个领域。

拿掉你所不需要的,不要害怕将一个设计模式从你的设计中删除

还没有人谈到何时应该将某个模式删除。那么何时应该删除某个模式呢

当你的系统变得非常复杂,而且并不需要预留任何弹性的时候,就不要使用模式。换句话说,也就是当一个简单的解决防范比使用模式更恰当的时候。

如果现在不需要,就别做

设计模式威力强大,你很容易就可以在当前设计中看到模式的各种应用方式。开发人员天生就热爱创建漂亮的架构以应对任何方向的改变。

要抗拒这种诱惑啊!如果你今天在设计中有实际的需要去支持改变,就方式采用模式处理这个改变吧!然而,如果说理由只是假象的,就不要添加这个模式,因为这只会将你的系统越搞越复杂,而且很可能你永远不会需要它。

模式就是工具,是牛刀,应用"模式"要恰当!

模式是一种工具,只要在需要的时候才是用这种工具,一开始先遵循设计原则,建立最简单的代码以完成工作,在这个过程中,你看到有需要模式的地方,就使用模式。“使用模式/应用模式”绝对不是你开始设计该有的目标。应该让模式在你的设计过程中自然而然地出现。

模式可能带来复杂性,如果没有必要,我们绝不需要这样的复杂性。就像你已经知道的,模式时一种被证实过的设计经验,可以避免某些常见的错误,模式也是一种共享的词汇,能够让我们和其他开发人员提高我们沟通我们的设计的效率。共享词汇也是一种设计模式最大优点之一。

过度使用设计模式可能导致代码被过度工程化,应该总是用最简单的解决防范完成工作,并在真正需要模式的地方才使用它。应用模式要恰当!

使用共享词汇的五种场合

共享词汇能够节省大量的沟通时间,那么共享词汇使用在那些场合呢?

  • 1. 在设计会议中

当你和你的团队在会议中讨论软件设计时,使用设计模式可以帮助你们在“设计中讨论”久一点,从设计模式到面向对象原则的视角讨论设计,可以避免你们的团队很快地陷入实现的细节,也可以避免发生很多误解。

  • 2.和其他开发人员

当你和其他开发人员讨论的时候,可以使用模式。这可以帮助其他开发人员学习新模式,并建立一个社群。和别人分享你所学会的东西是很有成就感的一件事

  • 3.在架构代码中

当你在编写架构文档的时候,使用模式将会缩减文档的额篇幅,并且让读者更清楚你的设计。

  • 4.在代码注释和命名习惯上

当你编写代码的时候,应在注意中清楚地注明你所使用的模式。在选择类和方法的名称是,应尽可能显示出隐藏在下面的模式。其他开发的开发人员在阅读你的代码时会感激你,因为你让他们很快地了解你的实现。

  • 5.将志同道合的开发人员集合在一起

分享你的知识。许多开发人员都听说过模式,但并不真正了解什么是模式。你可以自愿地为他们讲一堂模式介绍课或者成立一个读书会。。。。。。。。

推荐文献

《设计模式:可复用面向对象软件的基础》

《The Timeless Way of Building》

《A Pattern Language》

Journaldev

引用文献

《HeadFirst设计模式》

《设计模式:可复用面向对象软件的基础》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值