设计模式课程设计报告

通过这次课程设计使我们都更加懂得并亲身体会到了理论与实际相结合的重要性,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从实践中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。以下是小编整理的设计模式课程设计报告,欢迎阅读。

设计模式课程设计报告

一、问题要求及任务描述

设计模式课程作业要求独立制作一个软件,功能是实现23种模式的定义、优缺点以及显示示例代码。

(一)、题目要求

设计软件,将23种设计模式结合,要能够显示每种模式的定义、优缺点以及举例说明例子,加上简单的代码说明。

(二)、主要任务

主要是选择一种工具,实现显示的功能,整理各种模式的定义,概念、使用情况、以及选择模式实例,代码实现;

(三)、典型实例实现(任选三个分属于不同设计模式的实例)

1、单例模式 定义与结构

单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。 单例模式的要点

显然单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。在下面的对象图中,有一个单例对象,而客户甲、客户乙和客户丙是单例对象的三个客户对象。可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。静态变量(这是c/c++的叫法,其他语言或有不同)是实现单例模式的要素。 单例模式的2种方式:饿汉式,懒汉式

单例模式属于对象创建型模式,其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点。对一些类来说,只有一个实例是很重要的,虽然系统中可以有许多打印机,但却只应该有一个打印机假脱机,只应该有一个文件系统和一个窗口管理器,一个数字滤波器只能有一个A/D转换器,一个会计系统只能专用于一个公司。怎样才能保证一个类只有一个实例并且这个实例易于被访问,一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象,一个更好的方法是让类自身负责保存他的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法,这就是Singleton模式。

一个产生随机数的例子,整个应用程序中只需要一个类的实例来产生随机数,客户端程序从类中获取这个实例,调用这个实例的方法nextInt(),公用的方法访问需要进行同步,这是单例模式需要解决的同步问题。

2、工厂方法模式 定义与结构

工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。

工厂方法模式的对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。

适用情况

第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。Java Collection中的iterator() 方法即属于这种情况。

第二种情况,只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是透明的。 优缺点

首先,良好的.封装性,代码结构清晰。一个对象创建是有条件约束的,如一个调用者需要一个具体的产品对象,只要知道这个产品的类名(或约束字符串)就可以了,不用知道创建对象的艰辛过程,减少模块间的耦合。

其次,工厂方法模式的扩展性非常优秀。在增加产品类的情况下,只要适当地修改具体的工厂类或扩展一个工厂类,就可以完成“拥抱变化”。例如在我们的例子中,需要增加一个棕色人种,则只需要增加一个BrownHuman类,工厂类不用任何修改就可完成系统扩展。 再次,屏蔽产品类。这一特点非常重要,产品类的实现如何变化,调用者都不需要关心,它只需要关心产品的接口,只要接口保持不表,系统中的上层模块就不要发生变化,因为产品类的实例化工作是由工厂类负责,一个产品对象具体由哪一个产品生成是由工厂类决定的。在数据库开发中,大家应该能够深刻体会到工厂方法模式的好处:如果使用JDBC连接数据库,数据库从MySql切换到Oracle,需要改动地方就是切换一下驱动名称(前提条件是SQL语句是标准语句),其他的都不需要修改,这是工厂方法模式灵活性的一个直接案。 最后,工厂方法模式是典型的解耦框架。高层模块值需要知道产品的抽象类,其他的实现类都不用关心,符合迪米特原则,我不需要的就不要去交流;也符合依赖倒转原则,只依赖产品类的抽象;当然也符合里氏替换原则,使用产品子类替换产品父类,没问题!

3、备忘录模式

定义与结构

备忘录(Memento)模式又称标记(Token)模式。GOF给备忘录模式的定义为:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

从定义可以看出备忘录模式是专门来存放对象历史状态的,这对于很好的实现undo、redo功能有很大的帮助。所以在命令模式中undo、redo功能可以配合备忘录模式来实现。

适用情况

使用了备忘录模式来实现保存对象的历史状态可以有效地保持封装边界。使用备忘录可以避免暴露一些只应由“备忘发起角色”管理却又必须存储在“备忘发起角色”之外的信息。把“备忘发起角色”内部信息对其他对象屏蔽起来, 从而保持了封装边界。

但是如果备份的“备忘发起角色”存在大量的信息或者创建、恢复操作非常频繁,则可能造成很大的开销。

GOF在《设计模式》中总结了使用备忘录模式的前提:

1) 必须保存一个对象在某一个时刻的(部分)状态, 这样以后需要时它才能恢复到先前的状态。

2) 如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。 优缺点

优点:使用备忘录模式,可以避免暴露一些只应由源发器管理却又必须存储在源发器之外的信息,而且能够在对象需要时恢复到先前的状态。

缺点:使用备忘录可能代价很高。如果源发器在生成备忘录时必须复制并存储大量的信息,或者客户非常频繁地创建备忘录和恢复源发器状态,可能会导致非常大的开销。

1)备忘录(Memento)角色:备忘录角色存储“备忘发起角色”的内部状态。“备忘发起角色”根据需要决定备忘录角色存储“备忘发起角色”的哪些内部状态。为了防止“备忘发起角色”以外的其他对象访问备忘录。备忘录实际上有两个接口,“备忘录管理者角色”只能看到备忘录提供的窄接口——对于备忘录角色中存放的属性是不可见的。“备忘发起角色”则能够看到一个宽接口——能够得到自己放入备忘录角色中属性。

2)备忘发起(Originator)角色:“备忘发起角色”创建一个备忘录,用以记录当前时刻它的内部状态。在需要时使用备忘录恢复内部状态。

3)备忘录管理者(Caretaker)角色:负责保存好备忘录。不能对备忘录的内容进行操作或检查。

三、小结

(一)、问题解决方法及程序实现小结

我的课程设计作业用的是Dreamever,即静态网页。因为本身每种模式的内容相对固定,实例代码以及uml图片都不会有很大的变动,而且所有模式所涉及的数据内容不多,不需要数据库支持,所以用静态网页形式显示既方便又合理。

在制作网页的过程中,开始的思路是运用浮动框架,但是因为每种模式代码普遍比较多,若显示与框架之内,整个页面布局不够合理,也不美观,于是,一种模式运用两个页面来显示,即合理又美观。

但是软件也有本身的缺陷,内容相对固定,不易改变,在变动后不容易改变。从每个页面回归前一个页面的时候可能会不方便。

学习设计模式让我们感觉程序设计实际上是一件很有意思的事情,23种设计模式,每种模式又有自己独特的解决思路,带有一定的通用性。我们在发现问题到解决问题这个过程中,常会发现很多问题是重复出现的,或是某个问题的变体,外在不同,而本质相同,这些问题的本质就是模式。设计模式主要是在大量变成的基础上加以总结,以减少重复编码。

(二)、 尚未解决的问题及下一步工作思路

对于模板方法模式的理解还不够,相关内容还没有找到,对于课本上c#理解还不够深入,应该学习用多种语言实现每种模式,理解其基本思想。

(三)、 收获

在本次课程设计中,加深了对于23种设计模式的理解和记忆,更加明白总结对于学习的重要性,在程序开发中,重复性的东西是对于资源的一种浪费,所以在以后学习中应该在更加注重总结学习。本次的课程设计作业也能作为以后学习的一个工具,在需要复习的时候,可以回来查阅总结的内容,一举两得。