logo资料库

浅析软件设计模式.doc

第1页 / 共6页
第2页 / 共6页
第3页 / 共6页
第4页 / 共6页
第5页 / 共6页
第6页 / 共6页
资料共6页,全文预览结束
软件设计模式浅析 张 (中原工学院 软件学院,河南 郑州 450000) 摘要:什么是软件设计模式呢?其实广义的来讲,软件设计模式是可解决一类软件问题 并且能反复使用的软件设计方案;狭义的来讲,软件设计模式是对被用来在特定场景下解决 一般设计问题的类和相互通信的对象的描述。是在类和对象的层次描述的可反复使用的软件 设计问题的解决方案。软件设计模式通常描述了一组相互紧密作用的类与对象。 在课堂学到的软件设计模式,我学习的并不好,对各种模式的运用和实现,感觉简单, 但是要做起来还是有些难度。本文简单讲述了以面向对象技术为基础的软件设计模式的分 析。 关键词:设计模式;设计方案;面向对象 中国分类号:TP311.5 文献标志码:A Software design patterns is analysed Chenyadong (Zhongyuan University of Technology Software college,henan zhengzhou 450000) Abstract: What is a software design pattern? Actually, broadly speaking, the software design pattern is a type of the software can solve the problem and the repeated use of the software design; Narrowly speaking, the software design pattern is to be used in specific scenarios and communicate with each other to solve the problem of general design of the description of the object. Is described in the level of the classes and objects can be repeated use of the software design of the solution of the problem. Software design patterns usually describes a set of mutually close function classes and objects. Learned in the class of software design pattern, I'm not a very good learning, for the use of various patterns and implementation, feeling is simple, but want to do or some difficulty. This article simply describes the software design based on object-oriented technology pattern analysis. Key words: design patterns; Design scheme; object-oriented
对于软件设计模式,从上课到现在,我在头脑中还没有一个完整的概念,主要是因为 我的基础比较差,凭自身能力还不能写出来一个项目。通过上网搜索,知道了什么是软件设 计模式,它是一套被反复使用,多数人知晓的,经过分类编目的,代码设计经验的总结,使 用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性[1]。软件设计模 式分为基础模式、委托模式、接口模式、代理模式、创建型模式、抽象工厂模式、单例模式、 生成器模式、工厂方法模式、原型模式、适配器模式等等。 一、设计模式 模式是用来描述所交流的问题及解决方案的[2],一个完整的设计模式主要由模式名称、 问题、解决方案、效果四个基本要素组成[2]。设计模式体现的是程序整体的一种构思,所以 有时候它也会出现在分析或者是概要设计阶段中,设计模式的核心思想是通过增加抽象层, 把变化部分从那些不变的部分中分离出来。这就是我所了解的设计模式。设计模式有五种原 则,“开-闭”原则(OCP)、单一职责原则(SRP)、里氏代换原则(LSP)、依赖倒置原则(DIP) 和接口隔离原则(ISP)[3],设计模式就是实现了上面所说的五种原则,从而达到了代码复用、 增加可维护性的目的。 在设计模式经典著作《GOF95》中,设计模式从应用的角度上被分为三个大的类型,分 别是创建型模式、结构型模式和行为型模式。又根据模式的范围分,模式既用于类又用于对 象,类模式是处理类和子类之间的关系,这些关系通过继承建立,是静态的,在编译时刻便 确定下来了;对象模式是处理对象间的关系,这些关系在运行时刻是可以变化的,更具动态 性。从某种意义上来说,几乎所有模式都使用继承机制,所以“类模式”只指那些集中于处 理类间关系的模式,而大部分模式都属于对象模式的范畴。 二、设计模式的分类 创建型设计模式是用来创建对象的模式,抽象了实例化过程,工厂模式、抽象工厂模式、 单件模式、生成器模式、原型模式都属于创建型设计模式。简单来说一下创建型结构模式有 哪几种模式吧,首先说一下工厂模式,工厂模式:客户类和工厂类分开,消费者任何时候需 要某种产品,只需要向工厂请求即可,消费者无须修改就可以接纳新产品;缺点就是当产品 修改时,工厂类也要做出相应的修改。比如:如何创建及如何向客户端提供。抽象工厂模式: 为一个产品族提供统一的创建接口,当需要这个产品族的某一系列的时候,可以从抽象工厂 中选出相应的系列创建一个具体的工厂类。单件模式:保证一个类有且仅有一个实例,提供 一个全局访问点。生成器模式:将复杂对象创建与表示分离,同样的创建过程可创建不同的 表示,允许用户通过指定复杂对象类型和内容来创建对象,用户不需要知道对象内部的具体 构建细节。原型模式:通过“复制”一个已经存在的实例来返回新的实例(不新建实例)。 被复制的实例就是“原型”,这个原型是可定制的。原型模式多用于创建复杂的或者耗时的 实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效;或者创建值相等,只 是命名不一样的同类数据。这几种模式老师也让做过作业,做起来感觉也挺简单的。 结构型模式讨论的是类和对象的结构,它采用继承机制来组合接口或实现(类结构型模 式),或者通过组合一些对象来实现新的功能(对象结构型模式)。结构型模式有这几种模式, 组合模式:定义一个接口,使之用于单一对象,也可以应用于多个单一对象组成的对象组。 装饰模式:给对象动态添加额外的职责,就好像给一个物体加上装饰物,完善其功能。代理 模式:在软件系统中,有些对象有时候由于跨越网络或者其他障碍,而不能够或者不想直接 访问另一个对象,直接访问会给系统带来不必要的复杂性,这时候可以在客户程序和目标对 象之间增加一层中间层,让代理对象来代替目标对象打点一切,这就是代理模式。享元模式: Flyweight 是一个共享对象,它可以同时在不同上下文(Context)使用。外观模式:外观 模式为子系统提供了一个更高层次、更简单的接口,从而降低了子系统的复杂度,使子系统
更易于使用和管理。外观承担了子系统中类交互的责任。桥梁模式:桥梁模式的用意是将问 题的抽象和实现分离开来实现,通过用聚合代替继承来解决子类爆炸性增长的问题。适配器 模式:将一个类的接口适配成用户所期待的接口。一个适配器允许因为接口不兼容而不能在 一起工作的类工作在一起,做法是将类自己的接口包装在一个已存在的类中。对于这几种模 式,我理解的太笼统,也不太明白,只是根据这些定义来用心理解来消化。 行为型设计模式着力解决的是类实体之间的通讯关系,希望以面向对象的方式描述一个 控制流程。行为型设计模式种类比较多,其中观察者模式和访问者模式运用的比较多。模版 模式:定义了一个算法步骤,并允许子类为一个或多个步骤提供实现。子类在不改变算法架 构的情况下,可重新定义算法中某些步骤。观察者模式:定义了对象之间一对多的依赖,当 这个对象的状态发生改变的时候,多个对象会接受到通知,有机会做出反馈。迭代子模式: 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。责任链 模式:很多对象由每一个对象对其下一个对象的引用而连接起来形成一条链。请求在这个链 上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪 一个对象最终处理这个请求,这使系统可以在不影响客户端的情况下动态的重新组织链和分 配责任。备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之 外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。命令模式:将请求及其参 数封装成一个对象,作为命令发起者和接收者的中介,可以对这些请求排队或记录请求日志, 以及支持可撤销操作。状态模式:允许一个“对象”在其内部状态改变的时候改变其行为, 即不同的状态,不同的行为。访问者模式:表示一个作用于某对象结构中的各元素的操作。 可以在不改变各元素的类的前提下定义作用于这些元素的新操作。解释器模式:给定一个语 言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的 句子。中介者模式:用一个中介对象来封装一系列的对象交互。策略模式:定义一组算法, 将每个算法都封装起来,并且使它们之间可以互换。策略模式使这些算法在客户端调用它们 的时候能够互不影响地变化。因为是学时太少的原因,老师讲的模式并不多,这几个模式好 多都没有讲,我们只能根据一些书籍和资料来学习。 三、模式分析 对于工厂模式,是最常见的一种模式之一。在面向对象编程中, 常用的方法是用 new 操作符构造对象实例,但在有些情况下,new 操作符直接生成对象会带来一些问题。创建对 象之前必须清楚所要创建对象的类信息,但个别情况下无法达到此要求,譬如打开一个视频 文件需要一个播放器对象,但是用户可能不知道具体播放器叫什么名字,需要系统分派给这 个视频文件一个合适的播放器,这种情况下用 new 运算符并不合适。许多类型对象的创造需 要一系列步骤,比如需要计算或取得对象的初始设置,需要选择生成哪个子对象实例,在生 成需要对象之前必须先生成一些辅助功能对象。在这些情况, 新对象的建立就是一个 “过 程”,而不仅仅是一个操作。为了能方便地完成这些复杂的对象创建工作,可引入工厂模式 。 工厂模式的实例分析: // EventFactory 类 class EventFactory:LogFactory public { public override EventLog Create() { } } // FileFactory 类 return new EventLog();
class FileFactory:LogFactory public { public override FileLog Create() { } } return new FileLog(); 客户程序有效避免了具体产品对象和应用程序之间的耦合,增加了具体工厂对象和应用 程序之间的耦合,在类内部创建对象通常比直接创建对象更灵活,通过面向对象的手法,将 具体对象的创建工作延迟到子类,提供了一种扩展策略,较好的解决了紧耦合问题。 工厂模式客户端程序: public { class App static void Main(string[] args) public { LogFactory //FileFactory factory = factory new = EventFactory(); new FileFactory(); Log log = factory.Create(); log.Write(); } } 对于抽象工厂模式,在软件系统中,经常面临“一系列相互依赖对象”的创建工作,由 于需求变化,这“一系列相互依赖的对象”也要改变,如何应对这种变化呢?如何像工厂模 式一样绕过常规的”new”,提供一种“封装机制”来避免客户程序和这种“多系列具体对象 创建工作”的紧耦合呢?其中有一种说法就是可以将这些对象一个个通过工厂模式来创建。 但是,既然是一系列相互依赖的对象,它们是有联系的,每个对象都这样解决,如何保证他 们的联系呢?所以运用抽象工厂模式,是一种有效的解决途径。抽象工厂模式提供一个创建 一系列相关或相互依赖对象的接口,而无需指定他们具体的类。适用于一个系统独立于其产 品创建、组合和表示时,一个系统由多个产品系列中的一个来配置时,强调一系列相关产品 对象的设计以便进行联合时,提供一个产品类库,只想显示其接口而非实现时。 抽象工厂模式的结构,如下图: 图 1 抽象工厂模式的结构 抽象工厂模式与工厂模式的区别就在于工厂模式提供一个接口,用于创建相关和依赖对 象的家族,而不需要明确指定具体类。抽象工厂模式允许客户使用抽象接口来创建一组相关 产品,而不需要关心具体实际产出的产品是什么。
对于适配器模式,是将一个类的接口,转换成客户期望的另一个接口,适配器让原本接 口不兼容的类可以一起工作。打个比方说,一个 team 要为外界提供 S 类服务,但 team 里面 没有能够完成此项任务的 member,只有 team 外的 A 可以完成这项服务。为保证对外服务类 别的一致性(提供 S 服务),一是将 A 招安到 team 内,负责提供 S 类服务,二是 A 不准备接 受招安,可安排 B 去完成这项任务,并让 B 做好 A 的工作,让 B 工作的时候向 A 请教,此时, B 是一个复合体(提供 S 服务,是 A 的继承弟子)。这种模式的使用过程是客户通过目标接 口调用适配器的方法对适配器发出请求,适配器使用被适配者接口把请求转换成被适配者的 一个或者多个调用接口,客户接收到调用的结果,但并未察觉这一切是适配器在起转换作用。 就是将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起 工作的类可以一起工作。适配器模式有三种适用场合,一是使用一个已经存在的类,而它的 接口不符合要求,二是创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类 (即那些接口可能不一定兼容的类)协同工作,三是使用一些已经存在的子类,但不可能通 过子类化以匹配各自接口。对象适配器可以适配它的父类接口。适配器模式还分为了累适配 器和对象适配器两种,这里就不再具体介绍了。适配器模式的优点就是方便设计者自由定义 接口,不用担心匹配问题,而它的缺点是这个模式属于静态结构 ,由于只能单继承,所以 不适用于多种不同的源适配到同一个目标。 对于命令模式,将一个请求封装为一个对象,可用不同请求对客户进行参数化;对请求 排队或记录请求日志,以及支持可撤消的操作。这种模式的适用性是抽象出待执行的动作以 参数化某对象,在不同时刻指定、排列和执行请求,支持取消操作,支持修改日志,用构建 在原语操作上的高层操作构造一个系统。 命令模式的实现: public class Receiver{ //接收者 public void action(){ System.out.println(“我在行动"); } } public interface Command { //抽象命令 public abstract void execute();} public class ConcreteCommand implements Command{ //具体命令 Receiver rcv; ConcreteCommand(Receiver rcv){ //含有接收者的引用 this.rcv=rcv; } public void execute(){ rcv.action(); } //执行命令 } public class Invoker{ //请求者 Command command; public void setCommand(Command command){ this.command=command; } public void startExecuteCommand(){ command.execute(); } } public class Application{ //客户程序 public static void main(String args[]){ Receiver r=new Receiver();
Command command=new ConcreteCommand(r); Invoker i=new Invoker(); i.setCommand(command); i.startExecuteCommand(); } } 命令模式的结构: 图 2 命令模式的结构 命令模式中请求者不直接与接收者交互,即请求者不包接收者的引用,彻底消除了彼此 之间的耦合。满足“开-闭原则”。如果增加新的具体命令和该命令的接受者,不必修改调用 者的代码,调用者就可以使用新的命令对象;反之,如果增加新的调用者,不必修改现有的 具体命令和接受者,新增加的调用者就可以使用已有的具体命令。由于请求者的请求被封装 到了具体命令中,就可以将具体命令保存到持久化的媒介中,在需要的时候,重新执行这个 具体命令。因此,使用命令模式可以记录日志。使用命令模式可以对“请求”进行排队。每 个请求都各自对应一个具体命令,因此可以按一定顺序执行这些具体命令。 四、总结 在现代软件开发当中,软件设计模式起到至关重要的作用。尤其是自从面向对象的语言 普遍使用以后,促成了团队合作设计的热潮,而在此时,没有一个好的设计模式,软件设计 几乎成了不可能完成的任务。软件设计模式在程序中的运用是非常广的,在程序设计的过程 中,是对反复出现的问题的很好的解决办法,是良好思路的经验集成。使用设计模式可确保 更快的开发正确的代码,并且降低在设计或者视线中出现的错误的可能性。通过学习软件设 计模式这门课程,了解到这么多种模式,虽然还不能熟练运用和操作,但是我会在以后的工 作和实践中去多加锻炼。 参考文献: [1]钟茂生,王文明。软件设计模式及其使用[J].计算机应用,2002,22(8):32-35 [2]Gamma E.Design patterns elements of reusable object-oriented software[M].北京: 机械工业出版社,2002 [3]廖志刚,李增智。设计模式在系统中的应用[J]。计算机工程与应用,2002,(12):7-10
分享到:
收藏