设计模式概述

设计模式概述

前言

设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

一、设计模式的分类

在这里插入图片描述

二、创建型设计模式

创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建、组合和表示它的那些 对象。一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给 另一个对象。

随着系统演化得越来越依赖于对象复合而不是类继承,创建型模式变得更为重要。当这种 情况发生时,重心从对一组固定行为的硬编码转移为定义一个较小的基本行为集,这些行为可以被组合成任意数目的更复杂的行为。这样创建有特定行为的对象要求的不仅仅是实例化一个类。

在这些模式中有两个不断出现的主旋律。

第一,它们都将关于该系统使用哪些具体的类的信息封装起来。

第二,它们隐藏了这些类的实例是如何被创建和放在一起的。整个系统关于这些对象所知道的是由抽象类所定义的接口。

因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以及何时创建这些方面给予了很大的灵活性。它们允许用结构和功能差别很大的“产品”对象配置一个系统。配置可以是静态的(即在编译时指定),也可以是动态的(在运行吋)。

三、结构型设计模式

结构型设计模式涉及如何组合类和对象以获得更大的结构。结构型类模式采用继承机制来 组合接口或实现。一个简单的例子是釆用多重继承方法将两个以上的类组合成一个类,结果这 个类包含了所有父类的性质。这一模式尤其有助于多个独立开发的类库协同工作。其中一个例 子是类形式的Adapter模式。一般来说,适配器使得一个接口与其他接口兼容,从而给出了多 个不同接口的统一抽象。为此,类适配器对一个adaptee类进行私有继承。这样,适配器就可 以用adaptee的接口表示它的接口。

结构型对象模式不是对接口和实现进行组合,而是描述了如何对一些对象进行组合,从而 实现新功能的一些方法。因为可以在运行时刻改变对象组合关系,所以对象组合方式具有更大 的灵活性,而这种机制用静态类组合是不可能实现的。

Composite模式是结构型对象模式的一个实例。它描述了如何构造一个类层次式结构,这 一结构由两种类型的对象所对应的类构成。其中的组合对象使得用户可以组合基元对象以及其 他的组合对象,从而形成任意复杂的结构。在Proxy模式中,proxy对象作为其他对象的一个 方便的替代或占位符。它的使用可以有多种形式,例如可以在局部空间中代表一个远程地址空 间中的对象,也可以表示一个要求被加载的较大的对象,还可以用来保护对敏感对象的访问。Proxy模式还提供了对对象的一些特有性质的一定程度上的间接访问,从而可以限制、增强或 修改这些性质。Flyweiglit模式为了共享对象定义了一个结构。至少有两个原因要求对象共享: 效率和一致性。Flyweight的对象共享机制主要强调对象的空间效率。使用很多对象的应用必须 考虑每一个对象的开销。使用对象共享而不是进行对象复制,可以节省大量的空间资源。但是,仅当这些对象没有定义与上下文相关的状态时,它们才可以被共享。Flyweight的对象没有这样 的状态。任何执行任务时需要的其他一些信息仅当需要时才传递过去。由于不存在与上下文相 关的状态,因此Flyweight对象可以被自由地共享。

如果说Flyxveight模式说明了如何生成很多较小的对象,那么Facade模式则描述了如何用 单个对象表示整个子系统。模式中的facade用来表示一组对象,facade的职责是将消息转发给 它所表示的对象。Bridge模式将对象的抽象和其实现分离,从而可以独立地改变它们。

Decorator模式描述了如何动态地为对象添加职责。Decorator模式是一种结构型模式,这 一模式釆用递归方式组合对象,从而允许添加任意多的对象职责。例如,一个包含用户界面组 件的Decorator对象可以将边框或阴影这样的装饰添加到该组件中,或者它可以将窗口滚动和缩放这样的功能添加到组件中。可以将一个Decorator对象嵌套在另外一个对象中,就可以很简 单地增加两个装饰,添加其他的装饰也是如此。因此,每个Decorator对象必须与其组件的接口兼容并且保证将消息传递给它。Decorator模式在转发一条信息之前或之后都可以完成它的工作 (例如绘制组件的边框)。许多结构型模式在某种程度上具有相关性。

四、行为型设计模式

为模式涉及算法和对象间职责的分配。行为模式不仅描述对象或类的模式,还描述它们之间的通信模式。这些模式刻画了在运行时难以跟踪的、复杂的控制流。它们将用户的注意力 从控制流转移到对象间的联系方式上来。

行为类模式使用继承机制在类间分派行为。本小节包括两个这样的模式。其中
Template Metliod较为简单和常用。模板方法是一个算法的抽象定义,它逐步地定义该算法,每一步调用一个抽象操作或一个原语操作,子类定义抽象操作以具体实现该算法。另一种行为类模式是Interpreter,它将一个文法表示为一个类层次,并实现一个解释器作为这些类的实例上的 一个操作。

行为对象模式使用对象复合而不是继承。一些行为对象模式描述了一组对等的对象怎样相 互协作以完成其中任一个对象都无法单独完成的任务。这里一个重要的问题是对等的对象。

如何互相了解对方。对等对象可以保持显式的对对方的引用,但那会增加它们的耦合度。 在极端情况下,每一个对象都要了解所有其他的对象。Mediator在对等对象间引入一个mediator 对象以避免这种情况的岀现。mediator提供了松耦合所需的间接性。

Chain of Responsibility提供更松的耦合。它让用户通过一条候选对象链隐式地向一个对象发送请求。根据运行时刻情况任一候选者都可以响应相应的请求。候选者的数目是任意的,可以在运行时刻决定哪些候选者参与到链中。

Observer模式定义并保持对象间的依赖关系。典型的Observer的例子是Smalltalk中的模型/视图/控制器,其中,一旦模型的状态发生变化,模型的所有视图都会得到通知。

其他的行为对象模式常将行为封装在一个对象中并将请求指派给它。Strategy模式将算法封装在对象中,这样可以方便地指定和改变一个对象所使用的算法。Conunand模式将请求封装 在对象中,这样它就可作为参数来传递,也可以被存储在历史列表中,或者以其他方式使用. State模式封装一个对象的状态,使得这个对象的状态对象变化时,该对象可改变它的行为。 Visitor封装分布于多个类之间的行为,而Iterator抽象了访问和遍历一个集合中的对象的方式。

五、设计模式的六大原则

1、开闭原则(Open Close Principle)

开闭原则的意思是:对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。

2、里氏代换原则(Liskov Substitution Principle)

里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

3、依赖倒转原则(Dependence Inversion Principle)

这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。

4、接口隔离原则(Interface Segregation Principle)

这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。

5、迪米特法则,又称最少知道原则(Demeter Principle)

最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。

6、合成复用原则(Composite Reuse Principle)

合成复用原则是指:尽量使用合成/聚合的方式,而不是使用继承。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值