精华内容
下载资源
问答
  • 对软件设计模式的理解
    千次阅读
    2020-09-16 13:42:43

    1、设计模式基本要素4个主要部分

    模式名称使用什么解决方案去解决了什么问题会产生什么样的效果

    2、按照目的分类

    在这里插入图片描述

    更多相关内容
  • 软件设计模式学习总结

    千次阅读 2020-11-27 21:26:47
    软件设计模式的个人理解软件设计模式的简单分类面向对象的设计的7项原则简介创建型模式 软件设计模式的简单分类 GoF(Gang of Four)的 23 种设计模式: 创建型模式:单原工抽建 结构型模式:代适桥装,外享组 ...

    前提

    如果你不太明白抽象和接口,可以先来参考一下:抽象和接口

    软件设计模式的简单分类

    GoF(Gang of Four)的 23 种设计模式:

    • 创建型模式:单原工抽建

    • 结构型模式:代适桥装,外享组

    • 行为型模式:模策命,取状观,中迭访备解

    面向对象的设计的7项原则简介

    软件开发中,程序员要尽量根据以下7条原则来开发程序,从而提高软件的开发效率、节约软件开发成本和维护成本。

    1. 开闭原则
    2. 里氏替换原则
    3. 依赖倒置原则
    4. 单一职责原则
    5. 接口隔离原则
    6. 迪米特法则
    7. 合成复用原则

    1. 开闭原则

    • 定义:软件实体应当对扩展开放,对修改关闭。

    • 作用:

      1. 在软件测试时,只需要测试扩展的代码
      2. 提高代码的复用性(粒度越小,被复用的可能性越大)
      3. 提高软件的可维护性
    • 实现:通过接口或抽象类为软件实体定义一个相对稳定的抽象层,将相同的可变因素封装在相同的具体实现类中。

    2. 里氏替换原则

    • 定义:子类可以扩展父类的功能,但不能改变父类原有的功能。
    • 作用:
      1. 里氏替换原则是实现开闭原则的重要方式之一 (扩展了子类而不能修改父类)
      2. 克服了继承中重写父类造成的可用性变差的缺点 (不能修改父类)
      3. 是动作正确性的保证 (扩展的类不会给已有的系统引入错误,如开闭原则中只测试扩展的代码)
    • 实现:子类继承父类时,除了添加新方法外,尽量不要重写父类的方法。

    3. 依赖倒置原则

    • 定义:高层,底层,细节都依赖于抽象。

    • 核心思想:要面向接口编程,而不是面向实现编程:

    在这里插入图片描述

    • 作用:

      1. 降低类间的耦合性
      2. 提高系统的稳定性
      3. 减少并行开发引起的风险
      4. 提高代码的可读性和可维护性
    • 实现:

      1. 每个类尽量提供接口或抽象类,或两者都提供
      2. 变量的声明类型尽量使接口或者是抽象类
      3. 任何类都不应该从具体类派生
      4. 使用继承时尽量遵循里氏替换原则

    4. 单一职责原则

    • 定义:一个类有且仅有一个引起它变化的原因,否则应该被拆
    • 理解:一个人应该只有一个引起他心动的原因,否则应该拆分。
    • 作用(优点):
      1. 降低类的复杂性
      2. 提高类的可读性
      3. 提高系统的可维护性
      4. 变更引起的风险降低
    • 实现:设计人员发现类的不同职责并将其分离,再封装到不同的类或模块中。

    5. 接口隔离原则

    • 定义:将臃肿庞大的接口拆分成更小的和更具体的接口,让接口中只包含客户喜欢的方法。

    • 理解:卖车的时候根据客户的经济能力为客户分配合适的车辆销售,而不是客户只有10W的预支却提供5W~200W的销售。

    • 优点:

      1. 提高系统的灵活性和可维护性。
      2. 提高了系统的内聚性。
      3. 接口的粒度大小定义合理,保证系统的稳定性。
      4. 使用多个专门的接口体现对象的层次。
      5. 减少项目工程中的代码冗余。
    • 实现:

      1. 接口尽量小,但应有限度。(不能细分到轮胎,方向盘,发动机,而应是整车销售)
      2. 为依赖接口的类定制服务。
      3. 了解环境,拒绝盲从。
      4. 提高内聚,减少对外交互。

    6. 迪米特法则

    • 定义:只与朋友说话,不与陌生人说话。
    • 理解:Demeter is a famous star in the world , and you can just get in touch with him by his assistant.
    • 优点:
      1. 降低了类之间的耦合度,提高模块的相对独立性。
      2. 提高了类的可复用率和系统的扩展性。
    • 缺点:增加系统的复杂性,减低通讯效率。
    • 强调:
      1. 从依赖者的角度说,只依赖应该依赖的对象。
      2. 从被依赖者的角度说,只暴露应该暴露的方法。
    • 运用时注意:
      1. 创建弱耦合的类
      2. 降低类成员的访问权限
      3. 优先考虑将一个类设置成不变类
      4. 将引用其他对象的次数降到最低
      5. 不暴露类的属性成员,提供set和get方法
      6. 谨慎使用序列化(Serializable)功能

    7. 合成复用原则

    • 定义:在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次考虑使用继承关系来实现。
    • 理解:复用时的优先级定义。
    • 实现:将已有的对象纳入新对象中,作为新对象的成员对象来实现的,新对象可以调用已有对象的功能,从而实现复用。

    7种设计原则的要点

    对修改关闭:开闭原则

    不破坏继承:里氏替换原则

    面向接口编程:依赖倒置原则

    类的职责单一:单一职责原则

    设计接口精简:接口隔离原则

    降低耦合度:迪米特法则

    优先使用组合或聚合关系复用,少用继承关系复用:合成复用原则

    总而言之,7种设计原则就是考试范围,如果不用就等于盲目复习,在整个过程中效率低下。

    创建型模式

    概述:怎样创建模型,将对象的创建和使用分离。

    单例模式

    • 定义:一个类只有一个实例,且该类能自行创建这个实例。

    • 特点:

      1. 只有一个实例对象
      2. 该单例对象必须由单例类自行创建
      3. 对外提供一个访问该单例的全局访问点
    • 角色:

      1. 单例类
      2. 访问类
    • 实现:

      1. 懒汉式:在类加载时没有生成单例,第一次调用getInstance方法时才创建。
      2. 饿汉式:类一旦加载就创建一个单例,保证在第一次调用getInstance方法前单例存在。
    • 应用:

      1. 如果一个类频繁实例化,创建的对象又频繁销毁。
      2. 只生成一个对象
      3. 对象需要被共享的场合
    • 举例:班长,身份证号。

    原型模式

    • 定义:用一个已经创建的实例作为原型,通过赋值该原型对象来创建一个和原型相同或相似的新对象。

    • 角色:

      1. 抽象原型类
      2. 具体原型类
      3. 访问类
    • 实现:原型模式的克隆分为浅克隆和深克隆。

      Java中的Object类提供了浅克隆的clone()方法。

    • 应用场景:

      1. 对象间相同或相似(个别属性不同)
      2. 对象创建过程比较麻烦,但是复制方便

    工厂方法模式

    • 定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂中
    • 理解:电视机,电冰箱工厂
    • 优点:
      1. 用户只需要知道工厂的名字就可以得到所要的产品
      2. 系统新家新的产品只需要添加具体产品类和具体工厂类
    • 角色:
      1. 抽象工厂
      2. 具体工厂
      3. 抽象产品
      4. 具体产品
    • 应用场景:
      1. 客户只知道创建产品的工厂名,而不知道具体的产品名
      2. 创建对象得到任务有多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口
      3. 客户不关心创建产品的细节,只关心品牌

    抽象工厂模式

    • 定义:为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品模式结构
    • 理解:电器工厂
    • 优点:
      1. 在类的内部对产品族中相关联的多等级产品共同管理
      2. 增加一个新的产品族不需要修改代码
    • 角色:同工厂模式一样
    • 应用场景:
      1. 创建的对象是一系列相互关联或相互依赖的产品族(电器工厂中电视机,洗衣机)
      2. 系统中有多个产品族,但每次只使用某一族产品
      3. 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构

    建造者模式

    • 定义:将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示
    • 理解:装修客厅时,客户告诉负责人需求,负责人分配工人干活
    • 优点:
      1. 各个具体的建造者相互独立,有利于系统的扩展
      2. 客户端不必知道产品内部组成的细节,便于控制细节风险
    • 缺点:
      1. 产品的组成部分必须相同,限制了使用范围
      2. 如果产品的内部变化复杂,会增加很多的建造者类
    • 角色:
      1. 产品角色
      2. 抽象建造者
      3. 具体建造者
      4. 指挥者
    • 应用场景:
      1. 创建的对象较复杂,由多个部件构成,各部件面临复杂的变化,但构件间的建造方式是稳定的
      2. 产品的构建过程和最终的表示是独立的

    结构型模式

    概述:描述如何将类或对象按某种布局组成更大的结构。

    代理模式

    • 定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。

    • 举例:微信上的某些鞋厂代理商(各种鞋都卖)

    • 优点:

      1. 在客户端和目标对象之间起到一个中介作用和保护目标对象的作用
      2. 代理对象可以扩展目标对象的功能
      3. 分离客户端和目标对象,降低系统的耦合度
    • 缺点:

      1. 请求处理速度变慢
      2. 增加系统的复杂性
    • 角色:

      1. 抽象主题类

      2. 真实主题类

      3. 代理类

    • En:agency,proxy

    适配器模式

    • 定义:使原来的接口转换成用户希望的接口,使原来因为接口不兼容而不能工作的类而正常工作

    • 举例:Type-c接口耳机转换器,读卡器(年代久远)

    • 优点:

      1. 客户端通过适配器可以透明的调用接口
      2. 复用现存的类
      3. 将目标类和适配者类解耦,解决目标类和适配者类接口不一致的问题
    • 缺点:更换适配器的过程比较复杂

    • 角色:

      1. 目标接口
      2. 适配器类
      3. 适配者类
    • En: Adapter

    桥接模式

    • 定义:将抽象和实现分离,使它们可以独立变化
    • 举例:按分类调用某款背包(颜色,类型,大小)
    • 优点:
      1. 扩展能力强
      2. 实现细节对客户透明
    • 缺点: 聚合关系建立在抽象层,增加了系统的理解和设计难度。
    • 角色:
      1. 抽象化角色
      2. 扩展化角色
      3. 实现化角色
      4. 具体实现化角色
    • En:bridge,concrete , refine

    装饰模式

    • 定义:不改变现有对象结构的情况下,动态地给该对象增加一些职责的模式。
    • 举例:巴啦啦小魔仙全身变
    • 优点:
      1. 比采用父类继承更灵活
      2. 可以设计出多个不同的具体装饰类,创造出多个不同行为的组合
    • 缺点:装饰模式增加了许多子类
    • 角色:
      1. 抽象构件
      2. 具体构件
      3. 抽象装饰
      4. 具体装饰
    • En:concrete,decorator,component

    外观模式

    • 定义:通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。
    • 举例:市民之家提供一个统一的接口办理许多业务
    • 优点:
      1. 降低了子系统与客户端之间的耦合度
      2. 对客户屏蔽了子系统组件
      3. 降低了大型软件系统中的编译依赖性
    • 缺点:
      1. 不能很好的限制客户使用子系统类
      2. 增加新的子系统可能会修改客户类或客户端的源代码(开闭原则
    • 角色:
      1. 外观角色
      2. 子系统角色
      3. 客户角色
    • En:facade,sub,client

    享元模式

    • 定义:运用共享技术有效支持大量细粒度对象的复用。

    • 举例:五子棋的棋子生成,从享元工厂中取出。

    • 优点:相同对象只保存一份,降低了系统中对象的数量。

    • 缺点:

      1. 一些不能共享的状态外部化,增加程序的复杂性。
      2. 读取享元模式的外部状态会使得运行时间变长。
    • 角色:

      1. 抽象享元角色
      2. 具体享元角色
      3. 非享元角色
      4. 享元工厂角色
    • En:flyweight,concrete

    组合模式

    • 定义:将对象组合成树状的层次结构模式。

    • 举例:网店购物车的实现。

    • 优点:

      1. 客户端代码可以一致地处理单个对象和组合对象,简化了客户端代码
      2. 容易在组合体内加入新的对象
    • 缺点:

      1. 设计较为复杂。
      2. 不容易限制容器中的构件。
      3. 不容易用继承的方法来增加构件的新功能。
    • 角色:

      1. 抽象构件角色
      2. 树叶构件角色
      3. 树枝构件角色
    • 分类:透明方式,安全方式。

    • En:component , leaf , composite

    行为型模式

    概述:用于描述程序在运行时复杂的流程控制,满足合成复用原则。

    模板方法模式

    • 定义:定义了操作中的算法骨架,将算法的一些步骤(每个子类中都会用到的)延迟到子类中。

    • 举例:点单——吃饭(父类的抽象方法)——结账

    • 优点:

      1. 封装了不变部分,扩展可变部分。
      2. 在父类中提取了公共的部分代码,便于代码的复用。
      3. 部分方法是由子类实现。
    • 缺点:

      1. 每个不同的实现都需要重新定义一个子类。

      2. 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果(代码的阅读难度增加)。

    • 角色:

      • 抽象类:

        1. 抽象方法:父类声明,子类实现。
        2. 具体方法:父类已实现,子类继承或重写。
        3. 钩子方法:父类已实现,用于判断的逻辑方法和需要子类重写的空方法。
      • 具体子类:

        实现抽象和钩子方法。

    策略模式

    • 定义:将定义的每个算法封装起来,使他们可以相互替换,且算法的变换不影响用户的使用。

    • 举例:客户点单大闸蟹,厨房做大闸蟹时两种算法:清蒸 红烧

    • 优点:

      1. 可以避免使用多重条件语句。
      2. 提供可重用的算法族,避免重复的代码。
      3. 可以提供相同行为的不同实现,客户可以根据不同时间/空间选择不同的策略。
      4. 提供了对开闭原则的完美支持。
      5. 把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现分离。
    • 缺点:

      1. 客户端必须理解所有策略算法的区别,适当时选择恰当的算法类。
      2. 策略模式造成很多的策略类。
    • 角色:

      1. 抽象策略类

      2. 具体策略类

      3. 环境类

    命令模式

    • 定义:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。

    • 举例:饭店将点餐信息(命令)告诉服务员(调用者),服务员将命令传递给厨师(执行者)

    • 优点:

      1. 降低系统的耦合度(厨师与服务员解耦)。
      2. 增加或删除命令非常方便。
      3. 可以实现宏命令(多个命令装配成一个组合命令)。
      4. 方便实现Undo和Redo操作。
    • 缺点:可能产生大量具体命令类,增加系统的复杂性。

    • 角色:

      1. 抽象命令类角色
      2. 具体命令角色
      3. 实现者/接受者角色
      4. 调用者/请求者角色

    职责链模式

    • 定义:避免请求发送者与多个请求处理着耦合在一起,将所有请求的处理者通过前一对象记住其下一对象的引用而形成一条链。

    • 举例: 请假的过程 :学生→班主任 → 辅导员 →院主任→ 教务处 有一个对象处理即可,对象无权限处理传递到下一级

    • 优点:

      1. 降低对象间的耦合度
      2. 增强了系统的扩展性
      3. 增强了给对象指派职责的灵活性
      4. 简化了对象间的链接
      5. 责任分担
    • 缺点:

      1. 不能保证每个请求一定被处理
      2. 对于较长的链,请求的处理可能涉及多个处理对象,系统性能受一定的影响。
      3. 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,导致系统出错,循环调用。
    • 角色:

      1. 抽象处理者
      2. 具体处理者
      3. 客户类

    状态模式

    • 定义:对有状态的对象,把复杂的”判断逻辑“提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。

    • 举例:由风扇的转速把风扇的档位进行划分。

    • 优点:

      1. 将与特定状态相关的行为局部化到一个状态,并且将不同状态的行为分割开。
      2. 减少对象间的相互依赖。
      3. 有利于程序的扩展。
    • 缺点:

      1. 会增加系统的类和对象的个数。
      2. 结构和实现比较复杂,使用不当会造成程序结构和代码的混乱。
    • 角色:

      1. 环境角色(维持当前状态)
      2. 抽象状态角色
      3. 具体状态角色
    • En: Context,state,concrete,enviroment

    观察者模式

    • 定义:多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新

    • 举例:上课程序检测到上课时间到,打铃通知上课。

    • 优点:

      1. 降低了目标与观察者之间的耦合关系。
      2. 目标与观察者之间建立了一套触发机制。
    • 缺点:

      1. 目标与观察者之间的依赖问题并没有完全解除,可能出现循环引用。
      2. 观察者对象很多时,通知的发布会花费很多时间,降低效率。
    • 角色:

      1. 抽象主题角色
      2. 具体主题角色
      3. 抽象观察者角色
      4. 具体观察者角色
    • En:subject,concrete,observer

    中介者模式

    • 定义:用一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,并可以独立的改变他们之间的交互。
    • 举例:Like Demeter
    • 优点:
      1. 降低耦合度
      2. 将对象间一对多关联变成一对一
    • 缺点:同事类太多时,难以维护
    • 角色:
      1. 抽象中介者角色
      2. 具体中介者角色
      3. 抽象同事类角色
      4. 具体同事类角色
    • En:concrete ,mediator ,colluage

    迭代器模式

    • 定义:提供一种方法来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。

    • 举例:旅行软件展示一个地区的所有旅游景点(java中提供的iterator)。

    • 优点:

      1. 访问一个聚合对象的内部无需暴露它的内部表示。
      2. 遍历任务交由迭代器完成。
      3. 支持以不同的方式遍历一个集合,可以自定义。
      4. 增加新的聚合类无须修改原有的代码。
      5. 封装性良好,为聚合结构提供了一个统一的接口。
    • 缺点:增加了类的个数,增加了系统的复杂性。

    • 角色:

      1. 抽象聚合角色
      2. 具体聚合角色
      3. 抽象迭代器角色
      4. 具体迭代器角色
    • En:aggregate (聚合),iterator

    访问者模式

    • 定义:将数据结构中的各元素的操作分离出来封装成独立的类,在不改变集合元素的前提下,为数据结构中每个元素提供多种访问方式。
    • 举例:不同的访问着对类的处理不同,生成的产品也不同(比如自己和厨师同样拿一条鱼做饭)
    • 优点:
      1. 扩展性好。
      2. 复用性好。
      3. 灵活性好。
      4. 符合单一职责原则。
    • 缺点:
      1. 增加新的元素类很困难。
      2. 破坏了封装。对访问者公布了具体元素细节。
      3. 违反了依赖倒置原则,依赖了具体类而没有依赖抽象类。
    • 角色:
      1. 抽象访问者角色
      2. 具体访问者角色
      3. 抽象元素角色
      4. 具体元素角色
      5. 对象结构
    • En:Visitor,element

    备忘录模式

    • 定义:不破坏封装性的前提下,获取保存一个对象的内部状态,以便以后需要的时候恢复。
    • 举例:书中提供了一个相亲游戏,从四大美女中选择来做自己的爱人(我觉得行,你觉得呢
    • 优点:
      1. 提供了一种可以恢复状态的机制。
      2. 实现了内部状态的封装。
      3. 简化了发起人类。
    • 缺点:资源消耗大。
    • 角色:
      1. 发起人角色。
      2. 备忘录角色。
      3. 管理者角色。
    • En:Originator,memento,caretaker

    解释器模式

    • 定义:给分析对象定义一个语言,并定义该语言的文法表示,设计一个解析器来解释语言中的句子。

    • 举例:我觉得这个可以用 java—语法—API来表示,或者 English—Grammar—dictionary

    • 优点:

      1. 扩展性好
      2. 容易实现
    • 缺点:

      1. 执行效率较低(通过例子就很容易理解了)
      2. 引起类膨胀,每条规则都应至少定义一个类,导致系统难以管理和维护
    • 角色:

      1. 抽象表达式角色
      2. 终结符表达式
      3. 非终结符表达式
      4. 环境角色
      5. 客户端
    • En:Expression, terminal, noterminal , context , client

    展开全文
  • 设计模式的本质是面向对象设计原则的实际运用,是类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。 正确使用设计模式具有以下优点。 可以提高程序员的思维能力、编程能力和设计能力。 使程序...


    前言

    设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性以及类的关联关系和组合关系的充分理解。

    正确使用设计模式具有以下优点。

    • 可以提高程序员的思维能力、编程能力和设计能力。
    • 使程序设计更加标准化、代码编制更加工程化,使软件开发效率大大提高,从而缩短软件的开发周期。
    • 使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。

    一、设计模式分类

    总体来说设计模式分为三大类:创建型模式、结构型模式、行为型模式

    示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

    1.创建型模式,共五种

    模式描述:
    这些模式是为类实例化而设计的。它们可以是类创建模式,也可以是对象创建模式。
    模式包括:

    • 单例模式
    • 工厂方法模式
    • 抽象工厂模式
    • 建造者模式(生成器模式)
    • 原型模式

    2.结构型模式,共七种

    模式描述:
    这些模式是针对类的结构和组成而设计的。这些模式中的大多数的主要目标是在不改变其组成的大部分情况下,增加所涉及类的功能。
    模式包括:

    • 适配器模式
    • 装饰者模式
    • 代理模式
    • 门面模式(外观模式)
    • 桥接模式
    • 组合模式
    • 享元模式

    3.行为型模式,共十一种

    模式描述:
    这些模式是根据一个类与其他类的交流方式设计的。
    描述包括:

    • 策略模式
    • 模版方法模式
    • 观察者模式
    • 迭代器模式
    • 责任链模式
    • 命令模式
    • 备忘录模式
    • 状态模式
    • 访问者模式
    • 中介者模式
    • 解释器模式

    4.扩展模式

    • 规则模式、对象池模式、雇工模式、黑板模式、空对象模式

    二、设计模式之间的关系

    在这里插入图片描述


    结尾

    • 感谢大家的耐心阅读,如有建议请私信或评论留言。
    • 如有收获,劳烦支持,关注、点赞、评论、收藏均可,博主会经常更新,与大家共同进步
    展开全文
  • Java常见设计模式总结

    万次阅读 多人点赞 2021-09-18 17:18:54
    设计模式是一套经过反复使用的代码设计经验,目的是为了重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式于己于人于系统都是多赢的,它使得代码编写真正工程化,它是软件工程的基石,如同大厦的一块块...

     一、设计模式总述:

    1、什么是设计模式:

            设计模式是一套经过反复使用的代码设计经验,目的是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 设计模式于己于人于系统都是多赢的,它使得代码编写真正工程化,它是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。总体来说,设计模式分为三大类:

    • 创建型模式:共5种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
    • 结构型模式:共7种:适配器模式、装饰器模式、代理模式、桥接模式、外观模式、组合模式、享元模式
    • 行为型模式:共11种:策略模式、模板方法模式、观察者模式、责任链模式、访问者模式、中介者模式、迭代器模式、命令模式、状态模式、备忘录模式、解释器模式

    其实还有两类:并发型模式和线程池模式,用一个图片来整体描述一下:

    2、设计模式的六大原则:

    (1)开闭原则 (Open Close Principle) :

            开闭原则指的是对扩展开放,对修改关闭。在对程序进行扩展的时候,不能去修改原有的代码,想要达到这样的效果,我们就需要使用接口或者抽象类

    (2)依赖倒转原则 (Dependence Inversion Principle):

            依赖倒置原则是开闭原则的基础,指的是针对接口编程,依赖于抽象而不依赖于具体

    (3)里氏替换原则 (Liskov Substitution Principle) :

            里氏替换原则是继承与复用的基石,只有当子类可以替换掉基类,且系统的功能不受影响时,基类才能被复用,而子类也能够在基础类上增加新的行为。所以里氏替换原则指的是任何基类可以出现的地方,子类一定可以出现。

            里氏替换原则是对 “开闭原则” 的补充,实现 “开闭原则” 的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏替换原则是对实现抽象化的具体步骤的规范。

    (4)接口隔离原则 (Interface Segregation Principle):

            使用多个隔离的接口,比使用单个接口要好,降低接口之间的耦合度与依赖,方便升级和维护方便

    (5)迪米特原则 (Demeter Principle):

            迪米特原则,也叫最少知道原则,指的是一个类应当尽量减少与其他实体进行相互作用,使得系统功能模块相对独立,降低耦合关系。该原则的初衷是降低类的耦合,虽然可以避免与非直接的类通信,但是要通信,就必然会通过一个“中介”来发生关系,过分的使用迪米特原则,会产生大量的中介和传递类,导致系统复杂度变大,所以采用迪米特法则时要反复权衡,既要做到结构清晰,又要高内聚低耦合。

    (6)合成复用原则 (Composite Reuse Principle):

            尽量使用组合/聚合的方式,而不是使用继承。

    二、Java的23种设计模式:

            接下来我们详细介绍Java中23种设计模式的概念,应用场景等情况,并结合他们的特点及设计模式的原则进行分析

    1、创建型-工厂方法模式:

    工厂方法模式分为三种:

    (1)简单工厂模式:

    建立一个工厂类,并定义一个接口对实现了同一接口的产品类进行创建。首先看下关系图:

    (2)工厂方法模式:

    工厂方法模式是对简单工厂模式的改进,简单工厂的缺陷在于不符合“开闭原则”,每次添加新产品类就需要修改工厂类,不利于系统的扩展维护。而工厂方法将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。UML关系图如下:

     (3)静态工厂方法模式:

    静态工厂模式是将工厂方法模式里的方法置为静态的,不需要创建实例,直接调用即可。

    工厂方法模式详情文章:Java设计模式之创建型:工厂模式详解(简单工厂+工厂方法+抽象工厂)

    2、创建型-抽象工厂模式:

            抽象工厂模式主要用于创建相关对象的家族。当一个产品族中需要被设计在一起工作时,通过抽象工厂模式,能够保证客户端始终只使用同一个产品族中的对象;并且通过隔离具体类的生成,使得客户端不需要明确指定具体生成类;所有的具体工厂都实现了抽象工厂中定义的公共接口,因此只需要改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。

            但该模式的缺点在于添加新的行为时比较麻烦,如果需要添加一个新产品族对象时,需要更改接口及其下所有子类,这必然会带来很大的麻烦。

            UML结构图如下:

    抽象工厂模式详情:Java设计模式之创建型:工厂模式详解(简单工厂+工厂方法+抽象工厂)

    3、创建型-建造者模式:

             建造者模式将复杂产品的创建步骤分解在在不同的方法中,使得创建过程更加清晰,从而更精确控制复杂对象的产生过程;通过隔离复杂对象的构建与使用,也就是将产品的创建与产品本身分离开来,使得同样的构建过程可以创建不同的对象;并且每个具体建造者都相互独立,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。UML结构图如下:

     建造者模式详情:Java设计模式之创建型:建造者模式

    4、创建型-单例模式:

            单例模式可以确保系统中某个类只有一个实例,该类自行实例化并向整个系统提供这个实例的公共访问点,除了该公共访问点,不能通过其他途径访问该实例。单例模式的优点在于:

    • 系统中只存在一个共用的实例对象,无需频繁创建和销毁对象,节约了系统资源,提高系统的性能
    • 可以严格控制客户怎么样以及何时访问单例对象。

    单例模式的写法有好几种,主要有三种:懒汉式单例、饿汉式单例、登记式单例。

    单例模式详情:Java设计模式之创建型:单例模式

    5、创建型-原型模式:

            原型模式也是用于对象的创建,通过将一个对象作为原型,对其进行复制克隆,产生一个与源对象类似的新对象。UML类图如下:

     在 Java 中,原型模式的核心是就是原型类 Prototype,Prototype 类需要具备以下两个条件:

    • 实现 Cloneable 接口:
    • 重写 Object 类中的 clone() 方法,用于返回对象的拷贝;

    Object 类中的 clone() 方法默认是浅拷贝,如果想要深拷贝对象,则需要在 clone() 方法中自定义自己的复制逻辑。

    • 浅复制:将一个对象复制后,基本数据类型的变量会重新创建,而引用类型指向的还是原对象所指向的内存地址。
    • 深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。

            使用原型模式进行创建对象不仅简化对象的创建步骤,还比 new 方式创建对象的性能要好的多,因为 Object 类的 clone() 方法是一个本地方法,直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显;

    原型模式详情:Java设计模式之创建型:原型模式

            

            上面我们介绍了5种创建型模式,下面我们就开始介绍下7种结构型模式:适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。其中对象的适配器模式是各种模式的起源,如下图:

    6、结构型-适配器模式:

            适配器模式主要用于将一个类或者接口转化成客户端希望的格式,使得原本不兼容的类可以在一起工作,将目标类和适配者类解耦;同时也符合“开闭原则”,可以在不修改原代码的基础上增加新的适配器类;将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性,但是缺点在于更换适配器的实现过程比较复杂。

            所以,适配器模式比较适合以下场景:

    • (1)系统需要使用现有的类,而这些类的接口不符合系统的接口。
    • (2)使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能。

    下面有个非常形象的例子很好地说明了什么是适配器模式:

    适配器模式的主要实现有三种:类的适配器模式、对象的适配器模式、接口的适配器模式。三者的使用场景如下:

    • 类的适配器模式:当希望将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。
    • 对象的适配器模式:当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个Wrapper类,持有原类的一个实例,在Wrapper类的方法中,调用实例的方法就行。
    • 接口的适配器模式:当不希望实现一个接口中所有的方法时,可以创建一个抽象类Wrapper,实现所有方法,我们写别的类的时候,继承抽象类即可。

    适配器模式详情:Java设计模式之结构型:适配器模式

    7、结构型-装饰器模式:

            装饰器模式可以动态给对象添加一些额外的职责从而实现功能的拓展,在运行时选择不同的装饰器,从而实现不同的行为;比使用继承更加灵活,通过对不同的装饰类进行排列组合,创造出很多不同行为,得到功能更为强大的对象;符合“开闭原则”,被装饰类与装饰类独立变化,用户可以根据需要增加新的装饰类和被装饰类,在使用时再对其进行组合,原有代码无须改变。装饰器模式的UML结构图如下:

            但是装饰器模式也存在缺点,首先会产生很多的小对象,增加了系统的复杂性,第二是排错比较困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。

    装饰器模式详情:Java设计模式之结构型:装饰器模式

    8、结构型-代理模式:

            代理模式的设计动机是通过代理对象来访问真实对象,通过建立一个对象代理类,由代理对象控制原对象的引用,从而实现对真实对象的操作。在代理模式中,代理对象主要起到一个中介的作用,用于协调与连接调用者(即客户端)和被调用者(即目标对象),在一定程度上降低了系统的耦合度,同时也保护了目标对象。但缺点是在调用者与被调用者之间增加了代理对象,可能会造成请求的处理速度变慢。UML结构图如下:

    代理模式详情:Java设计模式之结构型:代理模式

    9、结构型-桥接模式:

            桥接模式将系统的抽象部分与实现部分分离解耦,使他们可以独立的变化。为了达到让抽象部分和实现部分独立变化的目的,桥接模式使用组合关系来代替继承关系,抽象部分拥有实现部分的接口对象,从而能够通过这个接口对象来调用具体实现部分的功能。也就是说,桥接模式中的桥接是一个单方向的关系,只能够抽象部分去使用实现部分的对象,而不能反过来。 

            桥接模式符合“开闭原则”,提高了系统的可拓展性,在两个变化维度中任意扩展一个维度,都不需要修改原来的系统;并且实现细节对客户不透明,可以隐藏实现细节。但是由于聚合关系建立在抽象层,要求开发者针对抽象进行编程,这增加系统的理解和设计难度。桥接模式的UML结构图如下:

            就像在Java中我们使用 JDBC 连接数据库时,在各个数据库之间进行切换,基本不需要动太多的代码,原因就是使用了桥接模式,JDBC 提供统一接口,每个数据库提供各自的实现,然后由桥接类创建一个连接数据库的驱动,使用某一个数据库的时候只需要切换一下就行。JDBC 的结构图如下:

             在 JDBC 中,桥接模式的实现化角色 (Implementor) 为的 Driver 接口,具体实现化 (Concrete Implementor) 角色对应 MysqlDriver、OracleDriver 和 MariadbDriver,扩展抽象化 (Refined Abstraction) 角色对应 DriverManager,不具有抽象化 (Abstraction) 角色作为扩展抽象化角色的父类。

    桥接模式详情:Java设计模式之结构型:桥接模式

    10、结构型-外观模式:

            外观模式通过对客户端提供一个统一的接口,用于访问子系统中的一群接口。使用外观模式有以下几点好处:

    (1)更加易用:使得子系统更加易用,客户端不再需要了解子系统内部的实现,也不需要跟众多子系统内部的模块进行交互,只需要跟外观类交互就可以了;

    (2)松散耦合:将客户端与子系统解耦,让子系统内部的模块能更容易扩展和维护。

    (3)更好的划分访问层次:通过合理使用 Facade,可以更好地划分访问的层次,有些方法是对系统外的,有些方法是系统内部使用的。把需要暴露给外部的功能集中到门面中,这样既方便客户端使用,也很好地隐藏了内部的细节。

            但是如果外观模式对子系统类做太多的限制则减少了可变性和灵活性,所以外观模式适用于为复杂子系统提供一个简单接口,提高系统的易用性场景 以及 引入外观模式将子系统与客户端进行解耦,提高子系统的独立性和可移植性。

            外观模式的UML结构图如下:

    外观模式详情: Java设计模式之结构型:外观模式

    11、结构型-组合模式:

            组合模式将叶子对象和容器对象进行递归组合,形成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性,能够像处理叶子对象一样来处理组合对象,无需进行区分,从而使用户程序能够与复杂元素的内部结构进行解耦。

            组合模式最关键的地方是叶子对象和组合对象实现了相同的抽象构建类,它既可表示叶子对象,也可表示容器对象,客户仅仅需要针对这个抽象构建类进行编程,这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。组合模式的UML结构图如下:

    组合模式详情: Java设计模式之结构型:组合模式

    12、结构型-享元模式:

            享元模式通过共享技术有效地支持细粒度、状态变化小的对象复用,当系统中存在有多个相同的对象,那么只共享一份,不必每个都去实例化一个对象,极大地减少系统中对象的数量,从而节省资源。

            享元模式的核心是享元工厂类,享元工厂类维护了一个对象存储池,当客户端需要对象时,首先从享元池中获取,如果享元池中存在对象实例则直接返回,如果享元池中不存在,则创建一个新的享元对象实例返回给用户,并在享元池中保存该新增对象,这点有些单例的意思。

            工厂类通常会使用集合类型来保存对象,如 HashMap、Hashtable、Vector 等等,在 Java 中,数据库连接池、线程池等都是用享元模式的应用。

            享元模式的UML结构图如下:

             Java 中,String 类型就是使用享元模式,String 对象是 final 类型,对象一旦创建就不可改变。而 Java 的字符串常量都是存在字符串常量池中的,JVM 会确保一个字符串常量在常量池中只有一个拷贝。

            而且提到共享池,我们也很容易联想到 Java 里面的JDBC连接池,通过连接池的管理,实现了数据库连接的共享,不需要每一次都重新创建连接,节省了数据库重新创建的开销,提升了系统的性能!

    享元模式详情:Java设计模式之结构型:享元模式

            前面我们介绍了7种结构型设计模式,接下来我们介绍一下11种行为型设计模式:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。先来张图,看看这11中模式的关系:

     13、行为型-策略模式:

            将类中经常改变或者可能改变的部分提取为作为一个抽象策略接口类,然后在类中包含这个对象的实例,这样类实例在运行时就可以随意调用实现了这个接口的类的行为。

            比如定义一系列的算法,把每一个算法封装起来,并且使它们可相互替换,使得算法可独立于使用它的客户而变化,这就是策略模式。UML结构图如下:

            策略模式的优点在于可以动态改变对象的行为;但缺点是会产生很多策略类,并且策略模式的决定权在用户,系统只是提供不同算法的实现,所以客户端必须知道所有的策略类,并自行决定使用哪一个策略类; 

            策略模式适用用于以下几种场景:

    • (1)应用程序需要实现特定的功能服务,而该程序有多种实现方式使用,所以需要动态地在几种算法中选择一种
    • (2)一个类定义了多种行为算法,并且这些行为在类的操作中以多个条件语句的形式出现,就可以将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。

    策略模式详情:Java设计模式之行为型:策略模式

    14、行为型-模板方法:

            模板方法是基于继承实现的,在抽象父类中声明一个模板方法,并在模板方法中定义算法的执行步骤(即算法骨架)。在模板方法模式中,可以将子类共性的部分放在父类中实现,而特性的部分延迟到子类中实现,只需将特性部分在父类中声明成抽象方法即可,使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤,不同的子类可以以不同的方式来实现这些逻辑。

            模板方法模式的优点在于符合“开闭原则”,也能够实现代码复用,将不变的行为转移到父类,去除子类中的重复代码。但是缺点是不同的实现都需要定义一个子类,导致类的个数的增加使得系统更加庞大,设计更加抽象。模板方法模式的UML图如下:

    模板方法详情:Java设计模式之行为型:模板方法模式

    15、行为型-责任链模式:

            职责链可以将请求的处理者组织成一条链,并将请求沿着链传递,如果某个处理者能够处理请求则处理,否则将该请求交由上级处理。客户端只需将请求发送到职责链上,无须关注请求的处理细节,通过职责链将请求的发送者和处理者解耦了,这也是职责链的设计动机。        

           职责链模式可以简化对象间的相互连接,因为客户端和处理者都没有对方明确的信息,同时处理者也不知道职责链中的结构,处理者只需保存一个指向后续者的引用,而不需要保存所有候选者的引用。

            另外职责链模式增加了系统的灵活性,我们可以任意增加或更改处理者,甚至更改处理者的顺序,不过有可能会导致一个请求无论如何也得不到处理,因为它可能被放置在链末端。

    所以责任链模式有以下几个优点:

    • (1)降低耦合度,将请求的发送者和接收者解耦。反映在代码上就是不需要在类中写很多丑陋的 if….else 语句,如果用了职责链,相当于我们面对一个黑箱,只需将请求递交给其中一个处理者,然后让黑箱内部去负责传递就可以了。
    • (2)简化了对象,使得对象不需要链的结构。
    • (3)增加系统的灵活性,通过改变链内的成员或者调动他们的次序,允许动态地新增或者删除处理者
    • (4)增加新的请求处理类很方便。

    但是责任链模式也存在一些缺点:

    • (1)不能保证请求一定被成功处理
    • (2)系统性能将受到一定影响,并且可能会造成循环调用。
    • (3)可能不容易观察运行时的特征,而且在进行代码调试时不太方便,有碍于除错。

            责任链模式的UML结构图如下:

    责任链模式详情:Java设计模式之行为型:责任链模式

    16、行为型-观察者模式:

            观察者模式又称为 发布-订阅模式,定义了对象之间一对多依赖关系,当目标对象(被观察者)的状态发生改变时,它的所有依赖者(观察者)都会收到通知。一个观察目标可以对应多个观察者,而这些观察者之间没有相互联系,所以能够根据需要增加和删除观察者,使得系统更易于扩展,符合开闭原则;并且观察者模式让目标对象和观察者松耦合,虽然彼此不清楚对方的细节,但依然可以交互,目标对象只知道一个具体的观察者列表,但并不认识任何一个具体的观察者,它只知道他们都有一个共同的接口。

            但观察者模式的缺点在于如果存在很多个被观察者的话,那么将需要花费一定时间通知所有的观察者,如果观察者与被观察者之间存在循环依赖的话,那么可能导致系统崩溃,并且观察者模式没有相应的机制让观察者知道被观察对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。观察者模式的UML结构图如下:

     观察者模式详情:Java设计模式之行为型:观察者模式

    17、行为型-访问者模式:

            访问者模式就是一种分离对象数据结构与行为 (基于数据结构的操作) 的方法,通过这种分离,达到为一个被访问者动态添加新的操作而无需做其它修改的效果,使得添加作用于这些数据结构的新操作变得简单,并且不需要改变各数据结构,为不同类型的数据结构提供多种访问操作方式,这样是访问者模式的设计动机。

            除了使新增访问操作变得更加简单,也能够在不修改现有类的层次结构下,定义该类层次结构的操作,并将有关元素对象的访问行为集中到一个访问者对象中,而不是分散搞一个个的元素类中。

           但访问者模式的缺点在于让增加新的元素类变得困难,每增加一个新的元素类都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作,违背了“开闭原则”的要求;

            所以访问者模式适用于对象结构中很少改变,但经常需要在此对象结构上定义新的操作的系统,使得算法操作的增加变得简单;或者需要对一个对象结构中进行很多不同并且不相关的操作,并且需要避免让这些操作污染这些对象,也不希望在增加新操作时修改这些类的场景。

            访问者模式的UML结构图如下:

            从上面的 UML 结构图中我们可以看出,访问者模式主要分为两个层次结构,一个是访问者层次结构,提供了抽象访问者和具体访问者,主要用于声明一些操作;一个是元素层次结构,提供了抽象元素和具体元素,主要用于声明 accept 操作;而对象结构 ObjectStructure 作为两者的桥梁,存储了不同类型的对象,以便不同的访问者来访问,相同访问者可以以不同的方式访问不同的元素,所以在访问者模式中增加新的访问者无需修改现有代码,可扩展行强。

            在访问者模式使用了双分派技术,所谓双分派技术就是在选择方法的时候,不仅仅要根据消息接收者的运行时区别,还要根据参数的运行时区别。在访问者模式中,客户端将具体状态当做参数传递给具体访问者,这里完成第一次分派,然后具体访问者作为参数的“具体状态”中的方法,同时也将自己this作为参数传递进去,这里就完成了第二次分派。双分派意味着得到的执行操作决定于请求的种类和接受者的类型。

     访问者模式详情:Java设计模式之行为型:访问者模式

    18、行为型-中介者模式:

             中介者模式通过中介者对象来封装一系列的对象交互,将对象间复杂的关系网状结构变成结构简单的以中介者为核心的星形结构,对象间一对多的关联转变为一对一的关联,简化对象间的关系,便于理解;各个对象之间的关系被解耦,每个对象不再和它关联的对象直接发生相互作用,而是通过中介者对象来与关联的对象进行通讯,使得对象可以相对独立地使用,提高了对象的可复用和系统的可扩展性。

            在中介者模式中,中介者类处于核心地位,它封装了系统中所有对象类之间的关系,除了简化对象间的关系,还可以对对象间的交互进行进一步的控制。中介者模式的UML结构图如下:

            但是,中介者对象封装了对象之间的关联关系,导致中介者对象变得比较庞大复杂,所承担的责任也比较多,维护起来也比较困难,它需要知道每个对象和他们之间的交互细节,如果它出问题,将会导致整个系统都会出问题。

    中介者模式详情:Java设计模式之行为型:中介者模式

    19、行为型-命令模式:

            命令模式的本质是将请求封装成对象,将发出命令与执行命令的责任分开,命令的发送者和接收者完全解耦,发送者只需知道如何发送命令,不需要关心命令是如何实现的,甚至是否执行成功都不需要理会。命令模式的关键在于引入了抽象命令接口,发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。

            使用命令模式的优势在于降低了系统的耦合度,而且新命令可以很方便添加到系统中,也容易设计一个组合命令。但缺点在于会导致某些系统有过多的具体命令类,因为针对每一个命令都需要设计一个具体命令类。

            命令模式的UML结构图如下:

    命令模式详情: Java设计模式之行为型:命令模式

    20、行为型-状态模式:

            状态模式,就是允许对象在内部状态发生改变时改变它的行为,对象看起来就好像修改了它的类,也就是说以状态为原子来改变它的行为,而不是通过行为来改变状态。

            当对象的行为取决于它的属性时,我们称这些属性为状态,那该对象就称为状态对象。对于状态对象而言,它的行为依赖于它的状态,比如要预订房间,只有当该房间空闲时才能预订,想入住该房间也只有当你预订了该房间或者该房间为空闲时。对于这样的一个对象,当它的外部事件产生互动的时候,其内部状态就会发生变化,从而使得他的行为也随之发生变化。

            状态模式的UML结构图如下:

     从上面的UML结构图我们可以看出状态模式的优点在于:

    (1)封装了转换规则,允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块

    (2)将所有与状态有关的行为放到一个类中,可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。 

    但是状态模式的缺点在于:

    (1)需要在枚举状态之前需要确定状态种类

    (2)会导致增加系统类和对象的个数。

    (3)对 “开闭原则” 的支持并不友好,新增状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态;而且修改某个状态类的行为也需修改对应类的源代码。

    所以状态模式适用于:代码中包含大量与对象状态有关的条件语句,以及对象的行为依赖于它的状态,并且可以根据它的状态改变而改变它的相关行为。

    状态模式详情:Java设计模式之行为型:状态模式

    21、行为型-备忘录模式:

            备忘录模式提供了一种恢复状态的机制,在不破坏封装的前提下,捕获对象的某个时刻内部状态,并保存在该对象之外,保证该对象能够恢复到某个历史状态;备忘录模式将保存的细节封装在备忘录中,除了创建它的创建者之外其他对象都不能访问它,并且实现了即使要改变保存的细节也不影响客户端。但是备忘录模式都是多状态和多备份的,会早用较多的内存,消耗资源。备忘录模式的额UML结构图如下:

             备忘录模式的核心就是备忘录 Memento,在备忘录中存储的就是原发器 Originator 的部分或者所有的状态信息,而这些状态信息是不能够被其他对象所访问的,也就是说我们是不能使用备忘录之外的对象来存储这些状态信息,如果暴漏了内部状态信息就违反了封装的原则,故备忘录除了原发器外其他对象都不可以访问。所以为了实现备忘录模式的封装,我们需要对备忘录的访问做些控制:

    (1)对原发器:可以访问备忘录里的所有信息。

    (2)对负责人 caretaker:不可以访问备忘录里面的数据,但是他可以保存备忘录并且可以将备忘录传递给其他对象。

    (3)其他对象:不可访问也不可以保存,它只负责接收从负责人那里传递过来的备忘录同时恢复原发器的状态。

    备忘录模式详情:Java设计模式之行为型:备忘录模式

    22、行为型-迭代器模式:

            迭代器模式提供一种访问集合中的各个元素,而不暴露其内部表示的方法。将在元素之间游走的职责交给迭代器,而不是集合对象,从而简化集合容器的实现,让集合容器专注于在它所应该专注的事情上,更加符合单一职责原则,避免在集合容器的抽象接口层中充斥着各种不同的遍历操作。迭代器模式的UML结构图如下:

    迭代器模式详情:Java设计模式之行为型:迭代器模式

    23、行为型-解释器模式:

            解释器模式,就是定义语言的文法,并建立一个解释器来解释该语言中的句子,通过构建解释器,解决某一频繁发生的特定类型问题实例。

            解释器模式描述了如何构成一个简单的语言解释器,主要应用在使用面向对象语言开发的编译器中,它描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子。    

            解释器模式中除了能够使用文法规则来定义一个语言,还能通过使用抽象语法树来更加直观表示、更好地地表示一个语言的构成,每一颗抽象语法树对应一个语言实例。抽象语法树描述了如何构成一个复杂的句子,通过对抽象语法树的分析,可以识别出语言中的终结符和非终结符类。 在解释器模式中由于每一种终结符表达式、非终结符表达式都会有一个具体的实例与之相对应,所以系统的扩展性比较好。

            解释器模式的UML如下:

     解释器模式详情:Java设计模式之行为型:解释器模式


    相关推荐阅读:

    Spring常见面试题总结

    SpringMVC常见面试题总结

    Mybatis常见面试题总结

    MySQL常见面试题总结

    Redis常见面试题总结

    RabbitMQ消息队列常见面试题总结

    ElasticSearch搜索引擎常见面试题总结

    计算机网络常见面试题总结

    操作系统常见面试题总结

    Java基础、集合、多线程常见面试题总结

    Java虚拟机常见面试题总结

    Java常见设计模式总结

    海量数据处理的方法总结


    参考文章:

    Java之美[从菜鸟到高手演变]之设计模式

    Java之美[从菜鸟到高手演变]之设计模式二

    Java之美[从菜鸟到高手演变]之设计模式三

    Java之美[从菜鸟到高手演变]之设计模式四

    展开全文
  • 嵌入式软件设计设计模式

    千次阅读 2019-04-21 17:24:31
    文章目录前言1.设计模式之适配器模式2.设计模式之单例模式3.设计模式之命令模式 前言 在嵌入式软件设计过程中,...适配器模式是一种比较常用的软件设计模式(有时候叫做包装模式)。它将对象的接口转换成对于客户端(...
  • 对于设计模式中七大原则的理解

    千次阅读 多人点赞 2021-08-28 01:14:28
    使用设计模式能够使我们开发的程序,易维护、可拓展,可...但是在23个设计模式的背后,还有7个开发原则去支撑着设计模式,保证23个设计模式能够易维护、可拓展,可复用。所以这篇文章来解开七大设计原则的神秘面纱。
  • 软件设计模式详解

    万次阅读 多人点赞 2018-11-07 21:40:21
    软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 ...
  • 深入理解设计模式-设计模式七大原则

    万次阅读 多人点赞 2021-05-26 09:44:41
    深入理解设计模式-设计模式七大原则 文章目录前言一、单一职责原则1.基本介绍2.注意事项和细节二、接口隔离原则1.基本介绍三、依赖倒转原则1.基本介绍2.注意事项和细节四、里氏替换原则1.基本介绍五、开闭原则1....
  • 深入理解设计模式-工厂方法模式

    万次阅读 2022-02-18 14:40:23
    文章目录前言一、定义二、使用场景三、代码样例1.需求2.类图3.工厂相关类4.产品相关类5.... 前言 在现实生活中社会分工越来越...在简单工厂模式中,我们提到了简单工厂模式违背了开闭原则,而“工厂方法模式”是简单工厂
  • 软件工程的23种设计模式

    万次阅读 多人点赞 2019-11-22 22:07:00
    设计模式 模式 在一定环境中解决某一问题的方案,包括三个基本元素–问题,解决方案和环境。 大白话:在一定环境下,用固定套路解决问题。 设计模式(Design pattern) 是一套被反复使用、多数人知晓的、经过分类编目的...
  • 软件设计模式期末大作业——可乐商城管理系统

    千次阅读 多人点赞 2021-06-16 22:09:39
    课程名称: 软件设计模式 设计题目: 可乐商城管理系统 设计要求: 1.设计一个应用场景,最少使用所学过的三种设计模式解决一个实际问题。一人一题,不可重复。 2.应用场景设计要合理,模式选择要适当。 3.要求给...
  • 一、软件设计模式的产生背景 “设计模式”这个术语最初并不是出现在软件设计中,而是被用于建筑领域的设计中。 1977 年,美国著名建筑大师、加利福尼亚大学伯克利分校环境结构中心主任克里斯托夫·亚历山大...
  • 文章目录前言一、定义二...在软件开发中也常常遇到类似的情况,当实现某一个功能存在多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能,如数据排序策略有冒泡排序、选择排序、插入
  • 说明 该文章适用于之前学习过设计模式,但是基本忘了。...设计模式:软件设计模式各种面向对象方法的一种总结。前辈们遇到了好多设计问题,然后利用面向对象解决了。然后他们把他们的解决方案汇总
  • 设计模式23模式介绍

    万次阅读 多人点赞 2020-01-18 08:20:52
    毫无疑问,设计模式使代码编程真正工程化,设计模式软件工程的基石,如同大厦的一块块砖头一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式都有响应的原理与之对应,每一个模式描述了一个在我们...
  • 1、什么是设计模式? 每一个模式描述了一个在我们周围不断重复发生的事情,以及该问题的解决方案的核心。 一般而言,一个模式有四个基本要素: 模式名称 — 一个助记名,它用一两次来描述模式的问题、解决方案和...
  • 深入理解Java设计模式-工厂模式

    千次阅读 2020-03-15 18:13:12
    在工厂模式中,我们在创建对象时不会客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。实现了创建者和调用者分离,工厂模式分为简单工厂、工厂方法、抽象工厂模式 2.工厂模式好处 工厂模式...
  • 几种常见设计模式理解

    千次阅读 2015-08-31 10:58:49
    几种常见设计模式理解 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 最早提出“设计模式”概念的...
  • 一张图快速了解23种设计模式

    万次阅读 多人点赞 2021-09-10 16:07:41
    这是《设计模式:可复用面向对象软件的基础》(Design Patterns: Elements of Reusable Object-Oriented)中对设计模式的定义。看完以后你会不会和我有一样的感觉:这特么说是啥? 于是,我找到了英文原文: The ...
  • 什么是设计模式?程序员如何学好设计模式

    万次阅读 多人点赞 2021-11-30 00:15:58
    前几天,我给大家介绍了算法和数据结构的基础知识。后来又有小伙伴私信问我:“小灰,你能不能也讲一讲设计模式的相关知识?”没问题!对于程序员来说,设计模式也是必须要掌握的一项核心知识,我今天就...
  • 仅供参考,以下是个人的课堂笔记,只有设计模式部分,这门课的sk老师非常负责,在学生中口碑很好,如果认真听课,课后及时总结,最后会更易读懂代码的架构以及为何这样设计的原因,编程也有很大的帮助。...
  • 快速理解设计模式六大原则

    千次阅读 2020-10-21 22:57:58
    设计模式的核心总结起来就一句话:用抽象构建框架,用实现扩展细节。目的就是代码修改的改动量最小 设计模式六大原则 单一职责原则 很好理解,一个类职责要单一,不要承载过多的职责,就比如说我们电脑上所有的...
  • 图解Java设计模式(一)

    万人学习 2019-02-27 21:06:35
    本课程针对上述问题,有针对性的进行了升级 (1) 授课方式采用 图解+框架源码分析的方式,让课程生动有趣好理解 (2) 系统全面的讲解了设计模式,包括 设计模式七大原则、UML类图-类的六大关系、23种设计模式及其分类,...
  • Jungle有两个手机,分别是M手机和N手机,M手机上有游戏Game1,N手机上有Game2。每次Jungle想玩Game1时,就使用M手机,想玩Game2时,就玩N手机。...同样都是游戏软件,为什么不把所有游戏都装到一个手机上呢...
  • 如何通俗理解设计模式及其思想

    万次阅读 多人点赞 2018-07-08 20:36:52
    本文由 玉刚说写作平台 提供写作赞助 原作者:却把清梅嗅 ... 版权声明:本文版权归微信公众号 玉刚...数据结构,算法,设计模式被认为是程序员必备技能的三叉戟,如果说编程语言的语法特性和业务编码能力是【术】,...
  • 软件设计模式(Software Design Pattern),俗称设计模式,设计模式是一套被反复使用的、多数人知晓的、经过 分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不断重复发生的问题,以及该问题的解决...
  • 设计模式(一)设计模式的分类与区别

    千次阅读 多人点赞 2020-05-17 11:21:37
    设计模式的分类、设计模式的原则、设计模式的适用场景、设计模式的区别
  • 设计模式

    万次阅读 多人点赞 2019-07-22 09:33:22
    设计模式简介 设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式软件开发人员在软件...使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性...
  • 23 种设计模式详解(全23种)

    万次阅读 多人点赞 2019-06-09 00:21:59
    设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式...
  • 设计模式软件体系结构【期末全整理答案】

    万次阅读 多人点赞 2020-07-13 19:01:19
    若本文你有帮助,请点赞、关注我呦! 期末试题基本出自这些题,请提前复制黏贴到word文档里,方便考试时直接查找。 单选题汇总 ...2、常用的基本设计模式可分为(A)。 A.创建型、结构型和行为型 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 385,279
精华内容 154,111
关键字:

对软件设计模式的理解