目录

  • 软件设计模式概述(面向对象设计概述)
    • 一、面向对象设计的表示方法
      • 1. UML
    • 二、面向对象的设计原则
      • 1.单一原则
      • 2.开闭原则
      • 3.里氏代换原则
      • 4.依赖倒转原则
      • 5.接口隔离原则
      • 6.合成复用原则
      • 7.迪米特法则
  • 创建型软件设计模式
    • 一、工厂方法与抽象工厂模式
      • 1.简单工厂方法模式
      • 2.工厂方法模式
      • 3.抽象工厂模式
    • 二、生成器模式
    • 三、单例模式
  • 结构性软件设计模式
    • 一、组合模式
    • 二、适配器模式
    • 三、外观模式
    • 四、桥接模式
  • 行为型软件设计模式
    • 一、迭代器模式
    • 二、访问者模式
    • 三、中介者模式
    • 四、策略模式
    • 五、状态模式

软件设计模式概述(面向对象设计概述)

一、面向对象设计的表示方法

1. UML

  • 类(Class)封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性、操作、关系的对象集合的总称。

类之间的关系:

  • 关联(直线箭头

  • 聚合/组合(聚合:总体的一侧为空菱形,部分的一侧为箭头 组合:总体的一侧为实菱形,部分的一侧为箭头

关联和聚合的区别主要在语义上,关联的两个对象之间一般是平等的,例如你是我的朋友,聚合则一般不是平等的,例如一个公司包含了很多员工,其实现上是差不多的。

  • 泛化(空三角+实线

几种关系所表现的强弱程度依次为:组合>聚合>关联>依赖
参考:关联、聚合、组合的区别

  • 接口和实现

  • 其他辅助视图

好的系统设计应该具有的三个性质:
1.可扩展性
2.灵活性
3.可插拔性

重构(Refactoring)是在不改变软件现有功能的基础上,通过调整程序代码改善软件的质量、性能,使其程序设计模式和架构更趋合理,提高软件的扩展性和维护性

二、面向对象的设计原则

记忆口诀:访问加限制,函数要节俭,依赖不允许,动态加接口,父类要抽象,扩展不更改。

1.单一原则

  • 一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中
  • 一个类(或者大到模块,小到方法)承担的职责过多,它被复用的可能性越小。
  • 单一职责原则是实现高内聚、低耦合的指导方针


2.开闭原则

  • 一个软件实体应当对扩展开放,对修改关闭
  • 开闭原则还可以通过一个更加具体的“对可变性封装原则”来描述

对于扩展时开放的:可以对模块进行扩展,增加新的功能
对于修改时封闭的:在对模块行为进行扩展时,不允许改动块中已经存在的类的源代码


3.里氏代换原则

  • 第一种定义:如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型S是类型T的子类型
  • 第二种定义:所有引用基类(父类)的地方必须能透明地使用其子类的对象

因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象
子类可扩展父类的方法属性,但不能修改


4.依赖倒转原则

  • 定义:

    • 高层模块不应该依赖低层模块,它们都应该依赖抽象
    • 抽象不应该依赖于细节
    • 细节应该依赖于抽象
    • 另一种表述为:要针对接口编程,而不是针对实现编程


JAVAEE中有提到过



5.接口隔离原则

  • 定义:客户端不应该依赖那些它不需要的接口
  • 另一种定义:一旦一个接口太大,则需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可



6.合成复用原则

又称为组合/聚合复用原则

  • 定义:

    • 尽量使用对象组合,而不是继承来达到复用的目的
    • 合成复用原则就是指在一个新的对象里通过组合关系和聚合关系来使用一些已有的对象,使之成为新对象的一部分;新对象通过委派调用已有对象的方法达到复用其已有功能的目的
  • 简而言之,要尽量使用组合/聚合关系,少用继承


7.迪米特法则

定义:

  • 不要和“陌生人”说话
  • 只与你的直接朋友通信
  • 每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位
  • 简单地说,迪米特法则就是指一个软件实体应当尽可能少的与其他实体发生相互作用



创建型软件设计模式

模式包括:
1.模式的名称
2.模式的目的,即要解决的问题
3.实现方法
4.为实现该模式必须考虑的限制和约束因素

设计模式的分类
根据其目的(模式是用来做什么的),面向对象的领域的设计模式可分为创建型(Creational),==结构型(Structural)和行为型(Behavioral)==三种:

  1. 创建型模式主要用于创建对象
  2. 结构型模式主要用于处理类或对象的组合
  3. 行为型模式主要用于描述对类或对象怎样交互和怎样分配职责

创建型模式两个主导思想:

  1. 封装了系统使用的具体类的知识
  2. 隐藏这些具体类的实例被创建与结合的细节

目标

  • 其目的是在哪个对象被创建、谁负责创建对象、怎样创建对象、何时创建对象等方面增强灵活性。
    内容
  • 创建型软件设计模式是解决对象创建机制的设计模式。

一、工厂方法与抽象工厂模式

工厂方法的优点:

  • 使用工厂方法访问并初始化合适的类的对象,简化了应用程序,应用程序本身不再含有大量的条件语句判定何时选取哪个类
  • 工厂方法实现了一些特殊的初始某个类的机制,尤其是层次结构不同的类需要不同的初始化方法的时候
  • 工厂方法返回一个父类的对象,客户程序不必知道这个被初始化的类的存在

工厂方法设计模式被分为:简单工厂方法模式、工厂方法模式和抽象工厂模式等几种情况。

1.简单工厂方法模式

简单工厂模式:又称为静态工厂方法模式。
在简单工厂模式中,可以根据参数的不同返回不同类的实例。
简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

优点
1.实现了对责任的分割,它提供了专门的工厂类用于创建对象
2.客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可
3.通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类
缺点
1.由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响
2.增加系统中类的个数
3.系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时
4.工厂角色无法形成基于继承的等级结构

简单工厂模式最大的缺点就是当有新产品要加入到系统中时,必须修改工厂类,加入必要的处理逻辑,这违背了“开闭原则”

适用环境

2.工厂方法模式

将简单工厂方法中单一的工厂类改写为一个层次类

工厂类+产品类

在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做
工厂方法模式退化后可以演变成简单工厂模式

优点:
1.用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名
2.工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部
3.在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。
缺点:
1.在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
2.增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。


简单工厂模式的中心为一个实的工厂类,工厂方法模式的中心为抽象工厂或者接口
简单工厂模式不支持开闭原则,而工厂模式支持
简单工厂模式中,必要的创建对象的逻辑判断包含在工厂类中(看教材p11的PolicyProducer),在工厂方法模式中,工厂类不必包含创建对象的逻辑判断

工厂方法模式的适用场景

3.抽象工厂模式

两个概念

例如:

开闭原则情况:
1.符合

2.不符合
就是增加一个新的种类产品

例如原来有两家公司A和B生产电视和冰箱,现在增加一个公司C也生产电视和冰箱则符合开闭原则
但如果是让原来的A和B新增加生产空调,则不符合开闭原则

优点

缺点

抽象工厂模式适用场合

二、生成器模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
例如:

1.确定Director,成员为xxxBuilder(表示要用到的生成器的父类),方法有设置生成器,获取产品(getXXX),创建整个产品的方法(这个方法用来调用生成器的各个方法,最后生成一个完整的产品)
2.确定XXXBuilder,成员为产品,方法就是构建这个产品所有部件所需的方法,以及getXXX获取产品,以及初始化产品的方法(肯定要先new申明一个空的产品,赋值给成员变量里的产品)
3.确定具体的生成器类,继承自XXXBuilder
4.确定具体产品,成员和方法就是该产品所需的各种方法属性等
例如:

优点:

缺点:

适用场合:

生成器模式与抽象工厂模式

三、单例模式

单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供一个全局访问点。
要点:

  1. 某个类只能有一个实例
  2. 它必须自行创建这个实例
  3. 它必须自行向整个系统提供这个实例

基本思路

步骤如上

例如

多线程中的单例模式,在getInstance()方法应声明为synchronized,防止当唯一实例尚未创建时有两个线程同时调用创建方法,那么将导致两个现成各自创建了一个实例,从而违反了单例模式的实例唯一性的初衷

优点:

  1. 提供了对唯一的实例的受控访问
  2. 可以节约系统资源
  3. 允许可变数目的实例

缺点

  1. 单例类的扩展有很大的困难
  2. 单例类的职责过重
  3. 滥用单例将带来一些负面影响

适用环境

结构性软件设计模式

结构型软件设计模式的主要目的是将不同的类和对象组合在一起,形成更大或者更复杂的结构体。

一、组合模式

组合模式:组合多个对象形成树形结构以表示“整体-部分”的结构层次。组合模式对单个对象(即叶子对象) 和 组合对象(即容器对象) 的 使用具有一致性

组合模式又可以称为“整体-部分”模式

组合模式结构

  • Component:为组合模式中的对象声明接口
  • Leaf:在组合模式中表示叶结点对象
  • Composite:表示组合部件
  • Client:通过Component接口操纵组合部件的对象

    例子建议看书P56

关于组合模式的讨论
1.安全形式的组合模式

2.透明形式的组合模式

优点:

缺点:

适用环境

二、适配器模式

  • 适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用
  • 当客户类调用适配器的方法时,在适配器类的内部奖调用适配者类的方法,而这个过程对客户类是透明的,客户类并不直接访问适配者类
  • 适配器可以使由于接口不兼容而不能交互的类可以一起工作

模式可分为两种

  • 类适配器模式

  • 对象适配器模式
    例如:




    适配器的作用
    适配器模式是将接口不同而功能相近的两个接口加以转换,包括适配器角色补充一些源角色没有但目标接口需要的方法。

适配器模式可以用于增加新的方法,但主要意图是转换接口

类适配器模式与对象适配器模式的区别(本质上没什么区别,只是在实现上的区别,比如Java不能多继承,所以用对象适配器模式)

优点:

类适配器的优点

类适配器的缺点:


对象适配器的优点

对象适配器的缺点

适用场合

适配者模式的扩展
1.默认适配器模式(缺省适配器模式、单接口适配器模式)


2.双向适配器

三、外观模式

  • 外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子接口更加容易使用
  • 外观模式又称为门面模式,它是一种对象结构型模式

外观模式由三个角色组成:

  1. 外观角色:外观模式的核心。它被客户角色调用,因此它熟悉子系统的功能。其内部根据客户橘色已有的需求预定了几种功能组合
  2. 子系统角色:实现子系统的功能,对它而言,外观角色就和客户角色一样是未知的,它没有任何外观角色的信息和链接
  3. 客户角色:调用外观角色来完成要得到的功能

外观模式讨论



使用外观模式的目的

  • 为一系列复杂的接口提供一个统一的接口,使该系统更容易使用

适配器模式与外观模式的区别

  • 适配器模式转换接口的目的是将一个不适用的接口转换为可以被使用的接口,或将一些接口不同而功能相近的接口加以转换,以便可以被统一使用
  • 外观模式简化接口的目的是为了更好地使用某个类库

四、桥接模式

  • 桥接模式将继承关系转换为关联关系,从而降低类与类之间的耦合,减少了代码编写量
  • 桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化
  • 它是一种对象结构型模式,又称为柄体模式或接口模式

例如:

1.确定抽象部分和实现部分
2.确定抽象部分的实现类,实现部分的实现类

优点

缺点

适用环境

适配器模式与桥接模式的联用

行为型软件设计模式

概述
动机

  • 行为型软件设计模式关心算法和对象之间的责任分配,不仅是描述对象或类模式,更加侧重描述它们之间的通信模式

内容

  • 迭代器模式抽象了访问和遍历一个集合中的对象的方式
  • 访问者模式封装了分布于多个类之间的行为
  • 中介者模式通过在对象间引入一个中介对象,避免对象间的显式引用
  • 策略模式将算法封装在对象中,这样可以方便指定或改变一个对象使用的算法
  • 状态模式封装了兑现过的状态,使得当对象的状态发生变化时,该对象可以改变自身的行为

一、迭代器模式


迭代器模式的关键思想是将对列表的访问和遍历从列表对象中分离出来,放入一个独立的迭代对象中

迭代器里的四个方法(一般)
1.boolean hasNext()
2.next()
3.remove()
4.getNumOfItems()



优点

缺点

适用环境

模式应用
JDK1.2引入了新的Java聚合框架Collections

二、访问者模式

  • 对于系统中的某些对象,它们存储在同一个集合中,具有不同的类型
  • 对于该集合中的对象,可以接受一类被称为访问者的对象来访问
  • 不同的访问者其访问方式有所不同
  • 目的:封装一些施加于某种数据结构元素之上的操作,一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变
  • 模式动机:为不同类型的元素提供多种访问操作方式,且可以在不修改原有系统的情况下增加新的操作方式



访问者模式:表示一个作用于某对象结构中的个元素的操作,它使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
访问者模式是一种对象行为型模式

首先分为两个部分,一是元素类,而是访问者类
先抽象再具体
在访问者类里要有访问元素的方法visitXXX(抽象元素父类做参数)之类的
在元素类里要有接受访问的方法,比如accept(抽象访问者父类做参数)等


访问者与被访问者的关联

优点

缺点

适用场合

模式扩展

三、中介者模式

  • 模式动机:为了减少对象两之间复杂的引用关系,使之成为一个松耦合的系统,需要适用中介者模式
  • 定义:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使耦合松散,而且可以独立地该变它们之间的交互
  • 中介者模式又称为调停者模式,它是一种对象行为型模式
  • 中介者模式的要点是将所有对象之间的交互细节抽象到一个独立的类中,这个类叫做中介者类Mediator

简单来说就是增加一个第三者,控制中心之类的东西

中介者模式组成:

  1. Mediator:中介者接口
  2. ConcreteMediator:具体的中介者,可以有多个具体的中介者
  3. Colleague:参与者类接口
  4. ConcreteColleague:具体的参与者




    优点

    缺点

    适用环境

    模式应用

四、策略模式

简单说就是将算法作为一个类存在,而不是作为方法存在某个类之中

  • 定义:策略模式定义了一系列算法,将每一个算法封装起来,并且使它们之间可以相互替换。策略模式让算法的变化不会影响到适用算法的客户
  • 策略模式试对算法的封装,它把算法的责任和算法本身分隔开,委派给不同的对象管理

策略模式组成

  1. Strategy:定义了一个共同的接口,所有具体的算法类实现这个接口。环境(上下文)类Context使用这个接口调用具体的算法类
  2. ConcreteStrategy:封装了具体的算法,实现同一个接口
  3. Context:环境(上下文)类。用于配置一个具体的算法策略对象,维持一个策略接口类型的参考(Reference),并且可以定义一些让接口Strategy的具体对象访问的接口。在简单情况下,Context类可以省略。


    例如:

    模式应用


    策略模式与状态模式

    适用环境

优点

缺点

五、状态模式

与策略模式类似,状态模式将不同状态下的行为封装在不同的类中,每个类代表一个状态
状态模式的组成

  1. Context:定义了与客户程序的接口,它保持了一个concreteState的代表现在状态的实例
  2. State:定义了状态接口,它的各个子类封装了在各种不同状态下的行为
  3. ConcreteState子类:封装了在各种不同状态下的行为
  • 状态模式描述了对象状态的变化以及对象如何在每一种状态下表现除不同的行为
  • 状态模式的关键是引入了一个抽象类来专门表示对象的状态,这个类我们叫做抽象状态类,而对象的每一种具体状态类都继承了该类,并在不同具体状态类中实现了不同状态的行为,包括各种状态之间的切换。

策略模式和状态模式的相似之处

策略模式和状态模式的区别

优点

软件设计模式与体系结构(上)相关推荐

  1. 软件设计模式与体系结构实验——3.1-1组合模式的应用

    链接: 软件设计模式与体系结构实验--2.1-1(2)(抽象)工厂模式的应用 链接: 软件设计模式与体系结构实验--2.2-1生成器模式的应用 链接: 软件设计模式与体系结构实验--2.3-1单列模式 ...

  2. 软件设计模式与体系结构 课后练习1

    软件设计模式与体系结构 课后练习1 习题如下: 解:第一题 画出该模式的设计类图: 如图1所示: 图1 设计类图 2.  解释为什么自己的设计符合开闭原则? 答:因为设计的类.模块和函数对扩展开放,对 ...

  3. 软件设计模式与体系结构实验——2.1-1(2)(抽象)工厂模式的应用

    文章目录 一.实验三 工厂模式的应用 1.实验目的 2.实验内容 3.模式UML图 4.模式代码 5.运行截图 6.实验小结 二.实验四 抽象工厂模式的应用 1.实验目的 2.实验内容 3.模式UML ...

  4. 软件设计模式与体系结构(中)

    目录 软件体系结构概述 一.软件体系结构的定义 二.软件体系结构的优势 经典软件体系结构 一.调用-返回风格软件体系结构 1.主程序-子程序 2.面向对象 二.数据流风格软件体系结构 1.顺序批处理软 ...

  5. 软件设计模式及体系结构之工厂方法模式

    前言 创建模式 创建型模式( Creational pattern)对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离. 为了使软件的结构更加清晰,外界对于这些对象只需要知道它们共 ...

  6. 软件设计模式与体系结构实验汇总

    实验一 工厂模式的应用 有一个OEM制造商代理做HP笔记本电脑(Laptop),后来该制造商得到了更多的品牌笔记本电脑的订单Acer,Lenovo,Dell,该OEM商发现,如果一次同时做很多个牌子的 ...

  7. 软件设计模式及体系结构之中介者模式

    前言 中介者模式概述 √QQ聊天的两种方式 1)用户与用户直接聊天,用户与用户之间存在多对多的联系,这将导致系统中用户之间的关系非常复杂用户如果要将相同的信息或文件发送给其他所有用户,必须一个一个地发 ...

  8. 软件设计模式及体系结构之外观模式

    前言 分析 1.一个客户类需要和多个业务类交互,而这些需要交互的业务类经常会作为一个整体 2.引入一个新的外观类(Facade)来负责和多个业务类子系统( Subsystem)进行交互,而客户类只需与 ...

  9. 软件设计模式及体系结构之迭代器模式

    前言 1.电视机<→存储电视频道的集合<→聚合类 2.电视机遥控器<→操作电视频道<>迭代器 (Iterator) 3.访问一个聚合对象中的元素但又不需要暴露它的内部 分 ...

最新文章

  1. mysql 主从,主主,主主复制时的主键冲突解决
  2. css 中 border 断线解决,简单实用
  3. Java 如何线程间通信,面试被问哭。。。
  4. Java高级:mysqllimit两个参数
  5. axureux中后台管理信息系统通用原型方案 v2_前端公共图表数据大盘方案
  6. win7重装系统时,使用PE工具箱进入系统看到的“C盘变成0.2G,D盘变成48G左右”这是什么回事?...
  7. plsql连接本地oracle数据库,而远程主机却无法连接,出现无监听程序的解决方法(转)
  8. pdns backend mysql_安装PowerDNS(与MySQL后端)和Poweradmin在Debian蚀刻
  9. IDEA中用maven打出的jar包只有一个META-INF文件夹,没有java的源码???
  10. dsoframer java_dsoframer控件动态加载
  11. php页面劫持网站,网站被劫持了怎么修复
  12. 基于Patachmatch的stereo matching笔记(二):《DeepPruner》
  13. 使用Python读取pdf文件
  14. nginx 域名解析
  15. android 常用机型尺寸_Android中获取手机屏幕大小的方法
  16. 国外问卷调查,一个不错的网上兼职项目
  17. js 函数传参实参包含路径“\”处理
  18. 无主复制系统(2)-读修复和反熵
  19. iOS如何阻止“橡皮筋效果”?
  20. 牛客网——华为题库(41~50)

热门文章

  1. 计算机专业读书推荐卡图片大全,如何完成实践作业《好书推荐卡》,大家谈
  2. Teamviewer - Teamviewer被检测成商用,无法使用个人版怎么解决(不用修改Mac地址)
  3. 人工智能融入社交交友 小冰比非诚勿扰更有诚意
  4. 【css】为什么#fff和#ffffff是一样的?或者说#fff和#ffffff的区别
  5. 编译的学习和实践日志二[我的目标是]
  6. 老罗,认真做一个好产品远比磨嘴皮子重要
  7. PC端“交易猫”网站爬虫项目
  8. 征服账号服务器,最新中文征服服务端(带架设教程+客户端补丁+需要的工具)10.13日更新...
  9. 第十九节 串口通讯与终端设备
  10. [物理实验]计算不确定度