【设计模式】使用设计模式来解决设计问题

选择对象

面向对象设计最困难的部分是将系统分解成对象集合。因为要考虑许多因素:封装、粒度、依赖关系、灵活性、性能、演化、复用等等,它们都影响着系统的分解,并且这些因素通常还是互相冲突的。

设计的许多对象来源于现实世界的分析模型。但是,设计结果所得到的类通常在现实世界中并不存在。设计模式帮你确定并不明显的抽象和描述这些抽象的对象。例如,描述过程或算法的对象现实中并不存在,但它们却是设计的关键部分。Strategy模式描述了怎样实现可互换的算法族。State模式将实体的每一个状态描述为一个对象。这些对象在分析阶段,甚至在设计阶段的早期都并不存在,后来为使设计更灵活、复用性更好才将它们发掘出来。

对象的粒度

Facade模式描述了怎样用对象表示完整的子系统,Flyweight模式描述了如何支持大量的最小粒度的对象。其他一些设计模式描述了将一个对象分解成许多小对象的特定方法。Abstract Factory和Builder产生那些专门负责生成其他对象的对象。Visitor和Command生成的对象专门负责实现对其他对象或对象组的请求。

对象接口

对象接口描述了该对象所能接受的全部请求的集合,任何匹配对象接口中型构的请求都可以发送给该对象。

在面向对象系统中,接口是基本的组成部分。对象只有通过它们的接口才能与外部交流,如果不通过对象的接口就无法知道对象的任何事情,也无法请求对象做任何事情。对象接口与其功能实现是分离的,不同对象可以对请求做不同的实现,也就是说,两个有相同接口的对象可以有完全不同的实现。

动态绑定(dynamic binding)

当给对象发送请求时,所引起的具体操作既与请求本身有关又与接受对象有关。发送给对象的请求和它的相应操作在运行时刻的连接就称之为动态绑定 (dynamic binding)。

动态绑定是指发送的请求直到运行时刻才受你的具体的实现的约束。动态绑定允许你在运行时刻彼此替换有相同接口的对象。这种可替换性就称为多态,它是面向对象系统中的核心概念之一。多态简化了客户的定义,使得对象间彼此独立,并可以在运行时刻动态改变它们相互的关系。

设计模式指定对象接口

设计模式通过确定接口的主要组成成分及经接口发送的数据类型,来帮助你定义接口。

Memento模式描述了怎样封装和保存对象内部的状态,以便一段时间后对象能恢复到这一状态。它规定了Memento对象必须定义两个接口:一个允许客户保持和复制Memento的限制接口,和一个只

有原对象才能使用的用来储存和提取Memento中状态的特权接口。

设计模式也指定了接口之间的关系。特别地,它们经常要求一些类具有相似的接口;或

它们对一些类的接口做了限制。例如Decorator和Proxy模式要求Decorator和Proxy对象的接口与被修饰的对象和受委托的对象一致。而Visitor模式中,Visitor接口必须反映出Visitor能访问的对象的所有类。

对象的实现

对象通过实例化类来创建。当实例化类时,要给对象的内部数据(由实例变量组成)分配存储空间,并将操作与这些数据联系起来。对象的许多类似实例是由实例化同一个类来创建的。

新的类可以由已存在的类通过类继承(class inheritance)来定义。当 子类(subclass)继承父类(parent class) 时,子类包含了父类定义的所有数据和操作。子类的实例对象包含所有子类和父类定义的数据,且它们能完成子类和父类定义的所有操作。

抽象类

抽象类(abstract class)的主要目的是为它的子类定义公共接口。一个抽象类将把它的部分或全部操作的实现延迟到子类中,因此,一个抽象类不能被实例化。在抽象类中定义却没有实现的操作被称为抽象操作 (abstract operation) 。

子类能够重定义(override)父类定义的操作,重定义使得子类能接管父类对请求的处理操作。

对接口编程,而不是对实现编程

类继承是一个通过复用父类功能而扩展应用功能的基本机制。它允许你根据旧对象快速定义新对象。

当继承被恰当使用时,所有从抽象类导出的类将共享该抽象类的接口。这意味着子类仅仅添加或重定义操作,而没有隐藏父类的操作。这时,所有的子类都能响应抽象类接口中的请求,从而子类的类型都是抽象类的子类型。

只根据抽象类中定义的接口来操纵对象有以下两个好处:

  1. 客户无须知道他们使用对象的特定类型,只须对象有客户所期望的接口。
  2. 客户无须知道他们使用的对象是用什么类来实现的,他们只须知道定义接口的抽象类。

针对接口编程,而不是针对实现编程。

不将变量声明为某个特定的具体类的实例对象,而是让它遵从抽象类所定义的接口。

复用机制

对象组合

面向对象系统中功能复用的两种最常用技术是类继承和对象组合。

类继承允许你根据其他类的实现来定义一个类的实现。这种通过生成子类的复用通常被称为白箱复用 (white-box reuse) 。在继承方式中,父类的内部细节对子类可见。

对象组合要求被 组合 的对象具有良好定义的接口。这种复用风格被称为 黑箱复用(black-box reuse),因为对象的内部细节是不可见的。

优点:

  • 类继承是在编译时刻静态定义的,且可直接使用。类继承可以较方便地改变被复用的实现。

    不足:

  • 因为继承在编译时刻就定义了,所以无法在运行时刻改变从父类继承的实现。
  • 因为继承对子类揭示了其父类的实现细节,所以继承常被认为“破坏了封装性”
  • 子类中的实现与它的父类有如此紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化。

对象组合是通过获得对其他对象的引用而在运行时刻动态定义的。组合要求对象遵守彼此的接口约定,进而要求更仔细地定义接口,而这些接口并不妨碍你将一个对象和其他对象一起使用。

这种方式带来的好处:因为对象只能通过接口访问,所以我们并不破坏封装性;只要类型一致,运行时刻还可以用一个对象来替代另一个对象;更进一步,因为对象的实现是基于接口写的,所以实现上存在较少的依赖关系。

参数化类型

另一种功能复用技术 (并非严格的面向对象技术)是参数化类型。

参数化类型允许你在定义一个类型时并不指定该类型所用到的其他所有类型。未经指定的类型在使用时以参数形式提供。

对象组合技术允许你在运行时刻改变被组合的行为,但是它存在间接性,比较低效。继承允许你提供操作的缺省实现,并通过子类重定义这些操作。参数化类型允许你改变类所用到的类型。但是继承和参数化类型都不能在运行时刻改变。

支持变化的设计

获得最大限度复用的关键在于对新需求和已有需求发生变化时的预见性,要求你的系统设计要能够相应地改进。

设计模式可以确保系统能以特定方式变化,从而帮助你避免重新设计系统。每一个设计模式允许系统结构的某个方面的变化独立于其他方面,这样产生的系统对于某一种特殊变化将更健壮。

设计模式在开发主要软件中起的作用

应用程序

软件的内部复用性、可维护性和可扩充性在开发应用程序时要优先考虑。内部复用性确保你不会做多余的设计和实现。设计模式通过减少依赖性来提高内部复用性。松散耦合也增强了一类对象与其他多个对象协作的可能性。

当设计模式被用来对系统分层和限制对平台的依赖性时,它们还会使一个应用更具可维护性。通过显示怎样扩展类层次结构和怎样使用对象复用,它们可增强系统的易扩充性。同时,耦合程度的降低也会增强可扩充性。如果一个类不过多地依赖其他类,扩充这个孤立的类还是很容易的。

工具箱

一个应用经常会使用来自一个或多个被称为工具箱(Toolkit)的预定义类库中的类。工具箱是一组相关的、可复用的类的集合,这些类提供了通用的功能。工具箱强调的是代码复用,它们是面向对象环境下的“子程序库” 。

工具箱的设计比应用设计要难得多,因为它要求对许多应用是可用的和有效的。再者,工具箱的设计者并不知道什么应用使用该工具箱及它们有什么特殊需求。这样,避免假设和依赖就变得很重要,否则会限制工具箱的灵活性,进而影响它的适用性和效率。

框架

框架(Framework) 是构成一类特定软件可复用设计的一组相互协作的类。

框架规定了你的应用的体系结构。它定义了整体结构,类和对象的分割,各部分的主要责任,类和对象怎么协作,以及控制流程。框架预定义了这些设计参数,以便于应用设计者或实现者能集中精力于应用本身的特定细节。框架记录了其应用领域的共同的设计决策。因而框架更强调设计复用,尽管框架常包括具体的立即可用的子类。

时间: 2024-08-04 21:28:53

【设计模式】使用设计模式来解决设计问题的相关文章

设计模式怎样解决设计问题

设计模式采用多种方法解决面向对象设计者经常碰到的问题,这里给出几个问题以及使用设计模式解决他们的方法. 1.寻找合适的对象 面向对象程序由对象组成,对象包括数据和对数据进行操作的过程,过程通常称为方法或操作,对象在收到客户的请求(或)消息后,执行相应的操作. 客户请求是使对象执行操作的唯一方法,操作又是对象改变内部数据的唯一方法.由于这些限制,对象的内部状态是被封装的,它不能被直接访问,它的表示对于对象外部是不可见的. 面向对象设计最困难的部分是将系统分解成对象集合.因为要考虑许多因素:封装.粒

设计模式的概念以及面向对象设计原则

设计模式的定义 设计模式(Design Pattern)是一套面向对象的代码设计经验总结. 设计模式是一种思想,也是一种技术. 一种设计模式就是一种解决实际问题的方案. 每一种设计模式虽然有既定的结构图和基本程序代码,但是应该不局限于此,要理解其精髓而熟练应用. OOP的六大设计原则 单一职责原则定义:对于一个类,应该只有一个引起它变化的原因.|-----降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单.|-----提高类的可读性,提高系统的可维护性. 里氏代换原则定义:子类

Java设计模式中的单例设计

/** * 单例设计模式 * 应用场合:只需要一个对象的 * 作用:保证整个应用程序中某个实例有且只有一个 * 类型有:饿汉模式.懒汉模式 * 下面的例子是一个饿汉模式的例子 */ class SingleDemo { // 1.将构造方法私有化,不允许外部直接创建使用 private SingleDemo() {} // 2.创建类的唯一实例,使用private static修饰 private static SingleDemo instance = new SingleDemo(); //

Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析

Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析 这个分为两个部分的系列文章研究了 Apache Tomcat 服务器的系统架构以及其运用的很多经典设计模式.第 1 部分 分析了 Tomcat 的工作原理,第 2 部分将分析 Tomcat 中运用的许多经典设计模式,如模版模式.工厂模式和单例模式等.通过学习它们的实践运用能给我们以后的软件设计起到一定的借鉴作用. 门面设计模式 门面设计模式在 Tomcat 中有多处使用,在 Request 和 Response 对象封装中.Stan

[设计模式]之零:六大设计原则

设计模式系列目录 单一职责原则 Single Responsibility Principle - SRP 就一个类而言,应该仅有一个引起它变化的原因. 假设现在要在iPhone上做一个图片编辑工具.功能有裁剪图片,旋转图片,缩放移动照片等等. 呐,我们可以写一个功能集类,然后把这些所有操作视为功能集的一部分,把代码全部写进这个类里面. 这么看来似乎可以,因为这是作为一个单独的模块嘛,把相关功能写进一个工具类里,用哪个功能调用哪个函数就好了.但这带来了一个问题就是这个工具类包含过多功能显得非常臃

【设计模式】设计模式基本概念

一.设计模式空间 类模式:处理类和子类之间的关系,通过继承建立,静态. 对象模式:处理对象之间的关系,动态性. 1.创建型:对象的创建. 类:Factory Method 将对象的部分创建工作延迟到子类 对象:Abstract Factory.Bulider.Prototype.Singleton 将它延迟到另一个对象中 2.结构型:类或对象的组合. 类:Adapter 使用继承机制组合类 对象:Adapter.Bridge.Composite.Decorator.Facade.Flyweigh

大话设计模式1:初识设计模式及设计模式五大基本原则

一什么是设计模式? 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计 模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于系统都是多 赢的:设计模式使代码编制真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 二为什么要使用设计模式? 为什么要提倡Design Pattern呢?根本原因是为了代码复用,增加可维护性.那么怎么才能实现代码复用呢?面 向对象有几个原则:单一职责原

大话设计模式—何为设计模式

设计模式,说起设计模式,设计模式,总是给人留下一种高屋建瓴,金碧辉煌的感觉.甚至很多人以在一款软件里使用了多少设计模式来衡量软件代码的质量.所以设计模式对于我们这些软件开发人员来说,实在再熟悉不过了.自从一本由四人组合写的奇书横空出世以后,设计模式在软件开发中就火了起来,很多程序员甚至把那本书奉为圣经.虽然我们怎么熟悉它,那我们是否真的完全理解或者掌握了它的精髓了呢? 无论学习什么知识我们首先从三问,或者五问问起(所有知识学习都逃不出这几问).第一问,是什么?首先我们来看看这个设计模式到底是什么

结构型设计模式对比 设计模式(十六)

结构型设计模式 结构型模式关注于整体最终的结构,通过继承和组合,构建出更加复杂的结构 进而提供更加强大的逻辑功能 七种结构型模式 适配器模式(Adapter Pattern) 组合模式(Composite Pattern) 装饰器模式(Decorator Pattern) 代理模式(Proxy Pattern) 桥接模式(Bridge Pattern) 外观模式(Facade Pattern) 享元模式(Flyweight Pattern) 所有的结构型设计模式在逻辑上都各自不同程度的隐含了“间

图解Java设计模式之设计模式面试题

图解Java设计模式之设计模式面试题 1.1 Java设计模式内容介绍 1.1.1 先看几个经典的面试题 1.1.2 设计模式的重要性 1.1 Java设计模式内容介绍 1.1.1 先看几个经典的面试题 原型设计模式问题 :1)有请使用UML类图画出原型模式核心角色2)原型设计模式的深拷贝和浅拷贝是什么.并写出深拷贝的两种方式的源码(重写clone方法实现深拷贝.使用序列化来实现深拷贝)3)在Spring框架中哪里使用到原型模式,并对源码进行分析beans.xml <bean id="id