赞
踩
为什么要学设计模式?
“设计模式”这个术语最初并不是出现在软件设计中,而是被用于建筑领域的设计中。
1987 年,肯特·贝克(Kent Beck)和沃德·坎宁安(Ward Cunningham)首先将建筑领域的模式思想应用在 Smalltalk 中的图形用户接口的生成中,但没有引起软件界的关注。
1994 年,艾瑞克·伽马(ErichGamma)、理査德·海尔姆(Richard Helm)、拉尔夫·约翰森(Ralph Johnson)、约翰·威利斯迪斯(John Vlissides)等 4 位作者合作出版了《设计模式:可复用面向对象软件的基础》(Design Patterns: Elements of Reusable Object-Oriented Software)一书,在本教程中收录了 23 个设计模式,这是设计模式领域里程碑的事件,导致了软件设计模式的突破。这 4 位作者在软件开发领域里也以他们的“四人组”(Gang of Four,GoF)匿名著称。
软件设计模式(Software Design Pattern),又称设计模式,是指在软件开发中,经过验证的,用于解决在特定环境下、重复出现的、特定问题的解决方案。
设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。正确使用设计模式具有以下优点。
软件设计模式使人们可以更加简单方便地复用成功的设计和体系结构,它通常包含以下几个基本要素:模式名称、别名、动机、问题、解决方案、效果、结构、模式角色、合作关系、实现方法、适用性、已知应用、例程、模式扩展和相关模式等,其中最关键的元素包括以下 4 个主要部分。
每一个模式都有自己的名字,通常用一两个词来描述,可以根据模式的问题、特点、解决方案、功能和效果来命名。
问题(Problem)描述了该模式的应用环境,即何时使用该模式。它解释了设计问题和问题存在的前因后果,以及必须满足的一系列先决条件。
模式问题的解决方案(Solution)包括设计的组成成分、它们之间的相互关系及各自的职责和协作方式。因为模式就像一个模板,可应用于多种不同场合,所以解决方案并不描述一个特定而具体的设计或实现,而是提供设计问题的抽象描述和怎样用一个具有一般意义的元素组合(类或对象的组合)来解决这个问题。
描述了模式的应用效果以及使用该模式应该权衡的问题,即模式的优缺点。主要是对时间和空间的衡量,以及该模式对系统的灵活性、扩充性、可移植性的影响,也考虑其实现问题。
根据模式是用来完成什么工作来划分,这种方式可分为创建型模式结构型模行为型模式
根据模式是主要用于类上还是主要用于对象上来分,这种方式可分为类模式和对象模式
编写软件过程中,程序员面临着来自耦合性,内聚性以及可维护性,可扩展性,重用性,灵活性等多方面的挑战,设计模式是为了让程序(软件),具有更好的
设计模式原则,其实就是程序员在编程时,应当遵守的原则,也是各种设计模式的基础(即:设计模式为什么这样设计的依据)
单一职责原则表示一个模块的组成元素之间的功能相关性。从软件变化的角度来看,对类来说,一个类应该只负责一项职责。
假设某个类 P 负责两个不同的职责,职责 P1 和 职责 P2,那么当职责 P1 需求发生改变而需要修改类 P,有可能会导致原来运行正常的职责 P2 功能发生故障。
单一职责原则注意事项和细节
客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上
接口隔离原则,其 "隔离" 并不是准确的翻译,真正的意图是 “分离” 接口(的功能)
开放-关闭原则表示软件实体 (类、模块、函数等等) 应该是可以被扩展的,但是不可被修改。(Open for extension, close for modification)
如果一个软件能够满足 OCP 原则,那么它将有两项优点:
依赖倒转原则(Dependence Inversion Principle)是指:
在编程中常常会遇到这样的问题:有一功能 P1, 由类 A 完成,现需要将功能 P1 进行扩展,扩展后的功能为 P,其中P由原有功能P1与新功能P2组成。新功能P由类A的子类B来完成,则子类B在完成新功能P2的同时,有可能会导致原有功能P1发生故障。
里氏替换原则告诉我们,当使用继承时候,类 B 继承类 A 时,除添加新的方法完成新增功能 P2,尽量不要修改父类方法预期的行为。
里氏替换原则的重点在不影响原功能,而不是不覆盖原方法。
组合/聚合复用原则就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分; 新的对象通过向这些对象的委派达到复用已有功能的目的。
在面向对象的设计中,如果直接继承基类,会破坏封装,因为继承将基类的实现细节暴露给子类;如果基类的实现发生了改变,则子类的实现也不得不改变;从基类继承而来的实现是静态的,不可能在运行时发生改变,没有足够的灵活性。于是就提出了组合/聚合复用原则,也就是在实际开发设计中,尽量使用组合/聚合,不要使用类继承
学设计模式还得用大二学过的UML类图,所以重新预习下。
UML(Unified Modeling Language)是一种统一建模语言,为面向对象开发系统的产品进行说明、可视化、和编制文档的一种标准语言
类图(ClassDiagram)是用来显示系统中的类、接口、协作以及它们之间的静态结构和关系的一种静态模型,是我们 Java 猿帅们最需要掌握的。它主要用于描述软件系统的结构化设计,帮助人们简化对软件系统的理解,它是系统分析与设计阶段的重要产物,也是系统编码与测试的重要模型依据。 类图中的类可以通过某种编程语言直接实现。类图在软件系统开发的整个生命周期都是有效的,它是面向对象系统的建模中最常见的图。
在软件系统中,类不是孤立存在的,类与类之间存在各种关系。根据类与类之间的耦合度从弱到强排列,UML 中的类图有以下几种关系:依赖关系、关联关系、聚合关系、组合关系、泛化关系和实现关系。其中泛化和实现的耦合度相等,它们是最强的。
只要在类中用到了对方,那么他们之间存在依赖关系,依赖(Dependency)关系是一种使用关系,它是对象之间耦合度最弱的一种关联方式,是临时性的关联。在代码中,某个类的方法通过局部变量、方法的参数或者对静态方法的调用来访问另一个类(被依赖类)中的某些方法来完成一些职责。 在 UML 类图中,依赖关系使用带箭头的虚线来表示,箭头从使用类指向被依赖的类
关联(Association)关系是对象之间的一种引用关系,用于表示一类对象与另一类对象之间的联系,如老师和学生、师傅和徒弟、丈夫和妻子等。关联关系是类与类之间最常用的一种关系,分为一般关联关系、聚合关系和组合关系。
关联具有导航性,即双向关系和单向关系。
关联具有多重性,如“1”表示有且仅有一个,“0..*”表示0个或多个。
单向关联
双向关联
多重关联
聚合(Aggregation)关系表示的是整体和部分的关系,是 has-a 的关系,整体与部分可以分开,是关联关系的特例,是强关联关系。 聚合关系也是通过成员对象来实现的,其中成员对象是整体对象的一部分,但是成员对象可以脱离整体对象而独立存在。例如,学校与老师的关系,学校包含老师,但如果学校停办了,老师依然存在。
组合(Composition)关系也是关联关系的一种特例,也表示类之间的整体与部分的关系,但它是一种更强烈的聚合关系,不可以分开,是 cxmtains-a 关系。 在组合关系中,整体对象可以控制部分对象的生命周期,一旦整体对象不存在,部分对象也将不存在,部分对象不能脱离整体对象而存在。例如,公司和部门。
泛化(Generalization)关系是对象之间耦合度最大的一种关系,表示一般与特殊的关系,是父类与子类之间的关系,是一种继承关系,是 is-a 的关系。 在 UML 类图中,泛化关系用带空心三角箭头的实线来表示,箭头从子类指向父类。在代码实现时,使用面向对象的继承机制来实现泛化关系。
实现(Realization)关系是接口与实现类之间的关系。在这种关系中,类实现了接口,类中的操作实现了接口中所声明的所有的抽象操作。 在 UML 类图中,实现关系使用带空心三角箭头的虚线来表示,箭头从实现类指向接口。
https://zhuanlan.zhihu.com/p/44518805
https://www.edrawsoft.cn/uml-diagram-introduction/
http://c.biancheng.net/view/1319.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。