2015-OO-设计模式(1)(2)
- 格式:ppt
- 大小:1.90 MB
- 文档页数:74
OO设计原则(一)好的作品来源于好的设计,那么好的设计又来自于哪里?且看OO设计中最常用的几大原则了。
单一职责原则(SPR)核心思想:一类不二用,一个类,最好只要专注于一件事,且只有一个引起它变化的原因。
它强调的是对职责的分离,是模块间保持低耦合,高聚合的一个关键。
下面就来看一下对比,亲身感受一下SPR。
对数据库的操作经常是违背该设计原则的重灾区。
比如当只有符合权限的用户才能对数据进行添加操作时,我们一般会在对数据操作之前对用户身份进行判别。
很多时候我们就会直接写代码如下:Class DBManager{pubic void Add(){If(Permission(userName) == true){Console.WriteLine(“用户可以对数据进行添加”);}public bool Permission(string UserName){//处理权限判断}}}初看可能并没有什么问题,但是仔细看就会发现,在以上设计中,DBManager类将对数据库的操作和对用户权限的判别封装在一起实现。
这样子,现在可能没多大问题,但如果以后对权限的设置规则发生改变的话,那可就有得玩了,你可能得把所有的数据库操作逻辑都重新修改。
这时,你就应该想到要遵循SPR设计原则对其修改了。
修改后如下://用接口定义有哪些操作public interface IDB Operation{Add();bool Delete();……}//而DBManager只关注数据的操作public class DBManager: IDB Operation{public void Add(){//执行数据增加}}通过以上重构,实现了职责的分离,DBManager类在此只关注数据操作,而将权限判断逻辑交给下面的DBManagerProxy代理类来完成。
public class DBManagerProxy: IDB Operation{private IDB Operation m_dbManager;public DBManagerProxy(IDB Operation dbOperation){m_dbManager = dbOperation;}public bool Permission(string UserName){//处理权限判断}public void Add(){if(Permission(userName) == true){m_dbManager.Add();}}}通过此代理,我们将数据操作和权限判断两个职责分离了开来,而实际的数据操作则由DBManager来完成,这样你会发现客户端的调用也将变得相当简单:public class DBClient{public static void Main(){IDB Operation DBManager = new DBManagerProxy(new DBManager(userName))DBManager.Add();}}自此,DBManger将只有数据操作的变更这个会引起变化的原因,而权限的变更和修改则就不会对anger造成任何影响了。
偶然发现这个社区,发一篇较早前写的文章。
若大家觉得还有点帮助作用,我将继续发后续几篇。
我发现,在OO和UML几乎一统天下的今天,仍有很多系统分析员对OO和UML一知半解,甚至包括很多已经使用了很久UM L的系统分析员。
于是打算写一个系列文章,将多年来的工作经验做一个总结。
对初学者起个启蒙作用,也希望抛砖引喻,与各路大虾共同探讨,共同提高。
这个系列文章将以我对OO和系统分析的理解为主,从UM L基础开始,阐述面向对象的需求分析方法,过程,并以RUP 为例,阐述如何将OO过程与软件过程有机结合在一起,做一个真正OO应用。
好了,今天是第一篇。
想得很远,真希望我能坚持下去,呵呵用例是什么?其原始英文是usecase,直译过来就成了用例。
这也是一个比较贴切的叫法了,从字面的直接理解就是使用的例子。
另一种比较流行的定义是用例就是与使用者(actor)交互的,并且给使用者提供可观测的有意义的结果的一系列活动的集合。
这个定义还是比较费解的,笔者在众多应聘者中发现很多使用用例来做需求的系统分析员,有的已经使用了两年以上,但仍不能把握用例的本质,虽然他们号称精通UML。
最具普遍意义的理解错误是认为用例就是功能的划分和描述,认为一个用例就是一个功能点。
在这种理解下,用例变成了仅仅是较早前需求中功能框图的翻版,很多人用用例来划分子系统,功能模块和功能点。
如果这样,用例根本没有存在的必要。
有意思的是,造成这种理解错误的相当一部分原因却是因为对OO思想的理解不够深入,本质上说,把用例当成功能点的系统分析员脑子里还是面向过程的那一套思想,虽然他们在使用OO的工具,OO的语言,号称在做面向对象的开发,但过程的影子还没有从他们脑子里彻底抹去。
如果用例不是功能的话,它是什么呢?从定义上说,能给使用者提供一个执行结果的活动,不就是功能吗?我的回答是:错!功能是计算机术语,它是用来描述计算机的,而非定义需求的术语。
功能实际描述的是输入-->计算-->输出。
OO设计原则在软件软件系统中,一个模块设计得好不好的最主要、最重要的标志,就是该模块在多大程度上将自己的内部数据和其他与实现有关的细节隐藏起来。
一个设计得好的模块可以将它所有的实现细节隐藏起来,彻底地将提供给外界的API和自己的实现分隔开来。
这样一来,模块与模块之间就可以仅仅通过彼此的API相互通信,而不理会模块内部的工作细节。
OO设计根本的指导原则是提高可维护性和可复用性。
这些原则主要有:1. 开闭原则一个软件实体应该对扩展开放,对修改关闭。
在设计一个模块的时候,就当使这个模块可以在不被修改的前提下被扩展。
换言之,就当可以在不必修改源代码的情况下改变这个模块的行为。
如何做到既不修改,又可以扩展?解决问题的关键在于抽象化:在Java语言里,可以给出一个或多个抽象Java类或Java接口,规定出所有的具体类必须提供的方法特征作为系统设计的抽象层。
这个抽象层预见了所有的可能扩展,因此,在任何扩展情况下都不会改变。
这就使得系统的抽象层不需要修改,从而满足了—对修改关闭。
同时,由于从抽象层导出一个或多个新的具体类可以改变系统的行为,因此系统的设计对扩展是开放的。
开闭原则实际上是对“对可变性的封闭原则“:找到一个系统的可变因素,将之封装起来。
这个原则意昧着两点:1) 一个可变性不应当散落在代码的很多角落里,而应当被封装到一个对象里面。
同一种可变性的不同表象意昧着同一个继承等级结构中的具体子类。
继承就当被看作是封装变化的方法,而不应当被认为是从一般的对象生成特殊对象的方法。
2) 一种可变性不应当与另一种可变性混合在一起。
(所有类图的继承结构一般不会超过两层,不然就意昧着将两种不同的可变性混合在了一起。
)开闭原则是总的原则,其它几条是开闭原则的手段和工具。
2. 依赖倒转原则依赖倒转原则讲的是:要依赖于抽象,不要信赖于实现。
开闭原则是目标,而达到这一目标的手段是依赖倒转原则。
抽象层次包含的是应用系统的商务逻辑和宏观的、对整个系统来说重要的战略性决定,是必然性的体现;而具体层次则含有一些次要的与实现有关的算法和逻辑,以及战术性的决定,带有相当大的偶然性选择。
深圳大学课程教学大纲课程编号: 1500300001 课程名称: 软件体系结构开课院系: 计算机与软件学院网络软件工程系制订(修订)人: 毛斐巧审核人: 批准人:2015年3月17日制(修)订课程名称: 软件体系结构英文名称: Software Architecture总学时: 54 其中:实验课 18学时学分: 2.5先修课程: 面向对象系统分析与设计、统一建模语言教材:刘伟.设计模式,清华大学出版社,2011参考教材:[1]《设计模式实训教程》,刘伟著,清华大学出版社课程性质: □综合必修□专业必修■专业选修□全校公选教学目标:开设本课程的目的是为建立一个基于模式的软件体系结构概念,从而为正确地分析和构建实际的复杂软件系统奠定坚实的基础。
学生在完成本课程学习后,应能够:1.理解软件体系结构的相关概念;2.掌握如何将复杂的软件系统按产品特征划分为子系统,以及如何规范子系统的构成;3.掌握如何应用模式的方法构造复杂软件的解决方案;4.掌握一些常见设计模式的应用环境及解决的问题,并能在实践中根据需要应用这些模式。
课程简介:《软件体系结构》主要是为软件工程/计算机专业的高年级本科学生,特别是软件工程方向的学生所开设的课程。
本课程系统地介绍软件体系结构的基本原理、方法和实践,介绍软件体系结构的设计和应用实例,强调理论与实践相结合。
本课程重点讲解基于模式的软件体系结构描述方法、软件体系结构风格和设计模式、基于产品特征的软件开发/重构方法、设计模式作为解决方案空间的有效工具等内容。
软件体系结构的模式描述、产品特征表达与模式设计和重构、在实践中如何应用产品特征来划分和规范子系统等内容是本课程的难点。
本课程采用课堂讲解与课程实验相结合的方法,辅以一定的案例讲解,帮助学生加强理解,更好地掌握课程内容。
教学内容:本课程内容共分6部分:1.软件体系结构概念主要讲授软件体系结构的发展历程和基本概念、软件体系结构设计的基本原理、研究软件体系结构的意义、当前研究状况等内容。
1.1 设计正在“腐烂”的征兆(Symptoms of Rotting Design)有四个主要的征兆告诉我们该软件设计正在“腐烂”中。
它们并不是互相独立的,而是互相关联,它们是过于僵硬、过于脆弱、不可重用性和粘滞性过高。
1. 过于僵硬Rigidity Rigidity 致使软件难以更改,每一个改动都会造成一连串的互相依靠的模块的改动,项目经理不敢改动,因为他永远也不知道一个改动何时才能完成。
2. 过于脆弱Fragility Fragility 致使当软件改动时,系统会在许多地方出错。
并且错误经常会发生在概念上与改动的地方没有联系的模块中。
这样的软件无法维护,每一次维护都使软件变得更加难以维护。
(恶性循环)3. 不可重用性immobility immobility 致使我们不能重用在其它项目中、或本项目中其它位置中的软件。
工程师发现将他想重用的部分分离出来的工作量和风险太大,足以抵消他重用的积极性,因此软件用重写代替了重用。
4. 粘滞性过高viscosity viscosity有两种形式:设计的viscosity和环境的viscosity.当需要进行改动时,工程师通常发现有不止一个方法可以达到目的。
但是这些方法中,一些会保留原有的设计不变,而另外一些则不会(也就是说,这些人是hacks)。
一个设计如果使工程师作错比作对容易得多,那么这个设计的viscosity 就会很高。
环境的viscosity高是指开发环境速度很慢且效率很低。
2 面向对象的类设计原则2.1 开放关闭原则The Open Closed Principle (OCP)A module should be open for extension but closed for modification.一个模块应该只在扩展的时候被打开(暴露模块内部),在修改的时候是关闭的(模块是黑盒子)。
在所有的面向对象设计原则中,这一条最重要。
该原则是说:我们应该能够不用修改模块的源代码,就能更改模块的行为。
种设计模式及事例重点时辰,第一时间送到!个人Github-24 种设计模式事例链接种设计模式案例维导图创立型模式工厂模式工厂模式(FactoryPattern)是Java中最常用的设计模式之一。
这类种类的设计模式属于创立型模式,它供应了一种创立对象的最正确方式。
在工厂模式中,我们在创立对象时不会对客户端裸露创立逻辑,并且是经过使用一个共同的接口来指向新创立的对象。
介绍企图:定义一个创立对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创立过程延缓到子类进行。
主要解决:主要解决接口选择的问题。
何时使用:我们明确地计划不一样条件下创立不一样实例时。
怎样解决:让其子类实现工厂接口,返回的也是一个抽象的产品。
重点代码:创立过程在其子类履行。
应用实例:1、您需要一辆汽车,能够直接从工厂里面提货,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的详细实现。
2、Hibernate换数据库只需换方言和驱动就能够。
长处:1、一个调用者想创立一个对象,只需知道其名称就能够了。
2、扩展性高,假如想增添一个产品,只需扩展一个工厂类就能够。
3、障蔽产品的详细实现,调用者只关怀产品的接口。
弊端:每次增添一个产品时,都需要增添一个详细类和对象实现工厂,使得系统中类的个数成倍增添,在必定程度上增添了系统的复杂度,同时也增添了系统详细类的依靠。
这其实不是什么好事。
使用处景:1、日记记录器:记录可能记录到当地硬盘、系统事件、远程服务器等,用户能够选择记录日记到什么地方。
2、数据库接见,当用户不知道最后系统采纳哪一类数据库,以及数据库可能有变化时。
3、设计一个连结服务器的框架,需要三个协议,'POP3'、'IMAP'、'HTTP',能够把这三个作为产品类,共同实现一个接口。
注意事项:作为一种创立类模式,在任何需要生成复杂对象的地方,都能够使用工厂方法模式。
有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要经过new 就能够达成创立的对象,无需使用工厂模式。
设计模式(OOD)学习设计模式(Object-Oriented Design Patterns)是在软件开发中用来解决经常出现的问题的一种经验总结和方法论。
设计模式通过提供一套经过验证的解决方案来帮助开发人员更高效地设计和组织代码。
本文将介绍设计模式的概念、常见的设计模式分类以及一些常用的设计模式示例。
设计模式的概念设计模式是一种软件设计中的抽象,它描述了解决常见问题的一种方法。
它们不是一种具体的算法或代码实现,而是一种在特定情况下可重复使用的解决方案。
设计模式的目标是提高代码的可重用性、可读性和可维护性。
常见的设计模式分类常见的设计模式可以根据其目标和应用场景进行分类。
以下是几个常见的设计模式分类:1. 创建型模式(Creational Patterns)创建型模式关注对象的实例化过程。
它们提供了一种将对象的创建和使用分离的方法,隐藏了对象的创建细节。
- 单例模式(Singleton Pattern):保证一个类只有一个实例,并提供全局访问点。
- 工厂模式(Factory Pattern):通过使用工厂方法来创建对象,而不是直接使用new操作符。
- 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。
- 原型模式(Prototype Pattern):通过克隆现有对象来创建新对象。
- 建造者模式(Builder Pattern):将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
2. 结构型模式(Structural Patterns)结构型模式关注类和对象的组合,通过定义对象之间的关系来实现更大的结构。
- 适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另一个接口。
- 装饰器模式(Decorator Pattern):动态地将新功能添加到对象中。
- 代理模式(Proxy Pattern):为其他对象提供一个代理以控制对这个对象的访问。