设计模式

(一)UML

结构式图形:强调的是系统式的建模

  • 静态图(类图、对象图、包图)
  • 实现图(组件图、部署图)
  • 剖面图
  • 复合结构图

行为式图形:强调系如模式中触发的时间

  • 活动图
  • 状态图
  • 用例图

交互式图形:属于行为式图形子集合,强调系统模型中资料流程

  • 通信图
  • 交互概述图
  • 时序图
  • 时间图

类图:

  • 用于表示类、接口、实例等之间相互的静态关系
  • 类图中并不是只有类
  • UML箭头方向:从子类指向父类
  • 空心实线三角箭头代表继承,is a 关系。扩展目的,不虚,很结实
  • 空心虚线三角箭头代表实现,虚线代表虚无实体
  • 实线箭头-关联(一个类有另一个类作为属性) | 虚线箭头-依赖(一般是方法形参依赖于另一个类)
  • 空心菱形-聚合(独立的生命周期) | 实心菱形-组合(两者具有相同的生命周期)
  1. 第一格(普通类:正常类名、抽象类:斜体类名、接口:<<接口名称>>)
  2. 第二格(属性)
  3. 第三格(行为方法;方法小括号里面代表形参)
  4. 注意点:(+【public权限】、-【private】、#【protected】、~【default】;冒号后面是属性类型或者方法返回值;带下划线代表是static声明的属性或者方法;抽象方法用斜体表示)

时序图:

  • 显示对象之间交互的图,这些对象是按时间顺序排列
  • 包括的建模元素主要有:对象(Actor)、生命线(LifeLine)、控制焦点(Focus of control)、消息(Message)等
  • 实心实线三角箭头代表同步调用
  • 实线箭头代表异步调用
  • 虚线箭头代表返回(方法执行完【不一定是return返回】)

(二)7大设计原则

开闭原则

  1. 定义:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭
  2. 用抽象构建框架,用实线扩展细节
  3. 优点:提高软件系统的可复用性和可维护性
  4. 思路:面向抽象、接口编程

依赖倒置原则

  1. 定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象
  2. 抽象不应该依赖细节;细节应该依赖抽象
  3. 针对接口编程,不要针对实现编程
  4. 优点:可以减少类间的耦合性、提高系统稳定性,提高代码可读性和可维护性,可降低修改程序所造成的风险

单一指责原则(针对类、接口、方法的程序中实现细节)

  1. 定义:不要存在多于一个导致类变更的原因
  2. 一个类/接口/方法/只负责一项职责
  3. 优点:降低类的复杂度、提高类的可读性,提高系统的可维护性、降低变更引起的风险

接口隔离原则(针对抽象针对接口之间的框架依赖关系)

  1. 定义:用多个专门的接口,而不使用单一的总接口,客户端不应该依赖它不需要的接口
  2. 一个类对一个类的依赖应该建立在最小的接口上
  3. 建立单一接口,不要建立庞大臃肿的接口
  4. 尽量细化接口,接口中的方案尽量少
  5. 注意适度原则,一定要适度 
  6. 优点:符合我们常说的高内聚低耦合的设计思想,从而使得类具有很好的可读性、可扩展性和可维护性

迪米特原则(最少知道原则)

  1. 定义:一个对象应该对其它对象保持最少的了解。又叫最少知道原则
  2. 尽量降低类与类之间的耦合
  3. 优点:降低类之间的偶合
  4. 强调只和朋友交流,不和陌生人说话。
  5. 朋友:出现在成员变量,方法的输入、输出参数中的类称为成员朋友类,而出现在方法体内部的类不属于朋友类

里氏替换原则

  1. 定义:如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都替换成o2时,程序P的行为没有发生变化,那么类型T2是T1的子类型
  2. 定义扩展:一个软件实体如果适用一个父类的话,那一定适用于其子类,所有一使用父类的地方必须能透明地使用其子类的对象,子类对象能够替换父类对象,而程序逻辑不变
  3. 引申意义:子类可以扩展父类的功能,但不能改变父类原有的功能
  4. 含义1:子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
  5. 含义2:子类中可以增加自己特有的方法
  6. 含义3:当子类的方法重载父类的方法时,方法的前置条件(即方法的输入/入参)要比父类方法的输入参数更宽松
  7. 含义4:当子类的方法实现父类的方法时(重写/重载或实现抽象方法),方法的后置条件(即方法的输出/返回值)要比父类更严格或相等
  8. 优点1:约束继承泛滥,开闭原则的一种体现
  9. 优点2:加强程序的健壮性,同时变更时也可以做到非常好的兼容性提高程序的维护性、扩展性。降低需求变更引入的风险

合成复用原则(组合复用原则)

  1. 定义:尽量使用对象组合/聚合,而不是继承关系达到软件复用的目的
  2. 聚合has-A和组合contains-A
  3. 优点:可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其它类造成的类影响相对较少
  4. 合适使用合成(contains-A) / 聚合(has-A)、继承(is-A)

(三)设计模式

创建型模式:

  • 工厂方法模式
  • 抽象工厂模式
  • 建造者模式
  • 单例模式
  • 原型模式

结构性模式:

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

行为型模式:

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

简单工厂:

  1. 定义:由一个工厂对象决定创建出哪一种产品的实例
  2. 类型:创建型,但不属于GOF23种设计模式
  3. 适用场景(工厂类负责创建的对象比较少;客户端[应用层]只知道传入工厂类的参数,对于如何创建对象[逻辑]不关心)
  4. 优点:只需要传入一个正确的参数,就可以获取所需的对象,而无需知道其创建细节
  5. 缺点:工厂类的职责相对过重,增加新的产品,需要修改工厂类的判断逻辑,违背开闭原则

工厂方法:(关注产品结构)

  • 定义:定义一个创建对象的接口,但让它实现这个接口的类来决定实例化哪个类,工厂方法让类的实例化推迟到子类中进行
  • 类型:创建型
  • 使用场景:创建对象需要大量重复代码;客户端(应用层)不依赖于产品类实例如何被创建、实现等细节;一个类通过其子类来指定创建哪个对象
  • 优点:用户只需要关心所需产品对应的工厂,无需关心创建细节;加入新产品符合开闭原则,提高可扩展性
  • 缺点:类的个数容易过多,增加复杂度;增加了系统的抽象性和理解难度

抽象方法:(关注产品族;增加产品族符合开闭原则,增加产品结构破坏开闭原则)[java.sql.Connection]

  • 定义:抽象工厂模式提供一个创建一些列相关或相互依赖对象的接口
  • 无需指定他们具体的类
  • 类型:创建型
  • 适用场景:客户端(应用层)不依赖于产品类实例如何被创建、实现等细节;强调一系列相关的产品对象(属于同一产品族一起使用创建对象需要大量重复的代码;提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现
  • 优点:具体产品在应用层代码隔离,无需关心创建细节;将一个系列的产品族统一到一起创建
  • 缺点:规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口;增加了系统的抽象性和理解难度

建造者模式:

  • 定义:将一个复杂对象的构建于它的表示分离,使得同样的构建过程可以创建不同的表示
  • 用户只需指定需要建造的类型就可以得到他们,建造过程及细节不需要知道
  • 类型:创建型
  • 适用场景:如果一个对象有非常复杂的内部机构(很多属性);想把复杂对象的创建和使用分离
  • 优点:封装型好,创建和使用分离;扩展性好、建造类之间独立、一定程度上解耦
  • 缺点:产生对于的Builder对象;产品内部发生变化,建造者都要修改,成本较大
  • 与工厂模式区别:建造者模式注重调用的顺序,不同的顺序产出不同的产品,工厂模式注重创建产品,不需要关注顺序;创建对象力度不同,建造者模式创建一些复杂的产品,工厂模式创建一样的产品;关注点不同,建造者模式不仅需要创建产品,还需要知道哪些部件创建组成的,工厂模式只需要创建出对象产品;
  • JDK(StringBuilder、StringBuffered)、Spring(BeanDefinitionBuilder)、Mybatis(SqlSessionFactoryBuilder)

单例模式:

  • 定义:保证一个类仅有一个实例,并提供一个全局访问点
  • 类型:创建型
  • 适用场景:想确保任何情况下都绝对只有一个实例;
  • 优点:在内存里只有一个实例,减少了内存开销;可以避免对资源的多重占用;设置了全局访问点,严格控制访问
  • 缺点:没有接口,扩展困难
  • 重点:私有构造器;线程安全;延迟加载;序列化和反序列化安全;反射
  • 懒汉式单例模式(注重延迟加载,使用的时候才创建;)
  • 饿汉式单例模式(类加载的时候就生成实例【RunTime】)
  • 枚举单例模式【最佳创建单例方式,可以防止序列化问题以及反射问题】 
  • 容器单例模式(使用键值Map,判断key值保证唯一)
  • TheadLocal线程单例模式()

原型模式:

  • 定义:指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象;不需要知道任何创建的细节,不调用构造函数
  • 类型:创建型
  • 适用场景:类初始化消耗较多资源;new产生的一个对象需要非常繁琐的过程(数据准备、访问权限等);构造函数比较复杂;循环体中生产大量对象时
  • 优点:原型模式性能比直接new一个对象性能高;简化创建过程
  • 缺点:必须配备克隆方法;对克隆复杂对象或克隆出的对象进行复杂改造时,容易引入风险;深拷贝(属性为引用类型时)、浅拷贝要运用得当
  • 扩展:深克隆、浅克隆

外观模式:

  • 定义:又叫做门面模式,提供了一个统一的接口,用来访问子系统中的一群接口;外观模式定义了一个高层接口,让子系统更容易使用
  • 类型:结构型
  • 适用场景:子系统越来越复杂,增加外观模式提供简单调用接口;构建多层系统结构,利用外观对象作为每层的入口,简化层间调用 
  • 优点:简化了调用过程,无需了解深入子系统,防止带来风险;减少了系统依赖,松散耦合;更好的划分访问层次;符合迪米特法则。即最少知道原则
  • 缺点:增加子系统、扩展子系统行为容易引入风险;不符合开闭原则
  • 外观模式和中介者模式:外观模式关注的是外界和子系统之间的交互,而中介者模式关注的是子系统内部之间的交互;外观模式和单例模式:外观对象可以使用单例模式创建对象;外观模式和抽象工厂模式:

装饰者模式:

  • 定义:在不改变原有对象的基础之上,将功能附加到对象上;提供了比继承更有弹性的替代方案(扩展原有对象功能费);
  • 类型:结构型
  • 适用场景:扩展一个类的功能或给一个类添加附加职责;动态的给一个对象添加功能,这些功能可以在动态的撤销
  • 优点:继承的有利补充,比继承灵活,不改变原有对象的情况下给一个对象扩展功能;通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同的效果;符合开闭原则
  • 缺点:会出现更多的代码,更多的类,增加程序复杂性;动态装饰时,多层装饰时会更复杂
  • 装饰者模式和代理模式:装饰者模式在于动态的添加方法,代理模式;装饰者模式和适配器模式:

适配器模式:

  • 定义:将一个类的接口转换成客户期望的另一个接口;使原本接口不兼容的类可以一起工作;
  • 类型:结构型
  • 适用场景:已经存在的类,它的方法和需求不匹配时(方法结果相同或相似);不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似而接口不相同的情况下的解决方法
  • 优点:能提高类的透明性和复用,现有的类复用但不需要改变;目标类和适配器类解耦,提高程序扩展性;符合开闭原则
  • 缺点:适配器编写过程需要全面考虑,可能会增加系统的复杂性;增加系统代码可读的难度
  • 对象适配器(使用委托机制,不需要继承,直接在类中创建需要的类【优先考虑】);类适配器(使用类继承的方法)
  • 适配器模式和外观模式:都是对现有的类现有的系统进行封装,适配粒度不同,外观针对对象粒度更对(针对子系统)

享元模式:

  • 定义:提供了减少对象数量从而改善应用所需的对象结构的方法;运用共享技术有效支持大量细粒度的对象
  • 类型:结构型
  • 适用场景:常常应用于系统底层的开发,以便解决系统的性能问题;系统中有打俩ing象时对象、需要缓冲池的场景
  • 优点:减少对象的创建,降低内存中对象的数量,降低系统的内存,提高效率;减少内存之外的其它资源占用
  • 缺点:关注内/外部状态、关注线程安全问题;使系统、程序的逻辑复杂化
  • 扩展:内部状态(在享元内部不会随着环境的改变而改变的共享部分);外部状态(随着环境改变而改变,是不可共享的部分)
  • 享元模式和代理模式:;享元模式和单例模式:;

组合模式:

  • 定义:将对象组合成树形结构以表示“部分--整体”的层次结构;组合模式使客户端对单个对象和组合对象保持一致的方式处理
  • 类型:结构型
  • 适用场景:希望客户端可以忽略组合对象与单个对象的差异时;处理一个树形结构时
  • 优点:清楚的定义分层次的复杂对象,表示对象的全部或部分层次;让客户端忽略了层次的差异,方便对整个层次结构进行控制;简化了客户端代码;符合开闭原则
  • 缺点:限制类型时会较为复杂;使设计变得更加抽象
  • 组合模式和访问者模式;

桥接模式:

  • 定义:将抽象部分与它的具体实现部分分离,使他们都可以独立地变化;通过组合地方式建立两个类之间联系,而不是继承
  • 类型:结构型
  • 适用场景:抽象和具体实现之间增加更多的灵活性;一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展;不希望使用继承,或因为多层继承导致系统类的个数剧增
  • 优点:分离抽象部分及其具体实现部分;提高了系统的可扩展性;符合开闭原则;符合合成复用原则
  • 缺点:增加了系统的理解与设计难度;需要正确地识别出系统中两个独立变化地维度
  • 桥接模式和组合模式:组合模式更注重部分和整体之间的组合,桥接模式强调的是平行级别上不同类的组合;桥接模式和适配器模式:都是是两个部分配合完成工作,适配器模式改变已有接口、桥接模式是分离抽象和具体的实现,目的就是分离
  • java.sql.Driver,java.sql.DriverManager;

代理模式:

模板方法模式:

  • 类型:行为型

迭代器模式:

  • 定义:提供一种方法,顺序访问一个集合对象中的各个元素,而又不暴露该对象的内部表示
  • 类型:行为型
  • 适用场景:访问一个集合对象的内容而又无需暴漏它的内部表示;为便利不同的集合结构提供一个统一的接口
  • 优点:分离了集合对象的遍历行为
  • 缺点:类的个数成对增加
  • 迭代器模式和访问者模式:都是迭代的访问一个集合对象的各个元素,访问者模式扩展开放的部分侧重在于对象的造作部分上,迭代器模式扩展开放的是在集合对象的种类上
  • java.util.Iterator;org.apache.ibatis.cursor;

策略模式:

  • 定义:定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户;if...else...
  • 类型:行为型
  • 适用场景:系统有很多类,而他们的区别仅仅在于他们的行为不同;一个系统需要动态地在几种算法中选择一种;
  • 优点:符合开闭原则;避免使用多重条件转移语句;提高算法地保密性和安全性;
  • 缺点:客户端必须知道所有的策略类,并自行决定使用哪一个策略类;产生很多策略类
  • 策略模式和工厂模式(工厂方法和抽象工厂);策略模式和状态模式
  • java.util.TreeMap;java.util.Arrays;org.srpingframework.core.io.Resource;

解释器模式(属于低频设计模式):

  • 定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子;为了解释一种语言,而为语言创建的解释器
  • 类型:行为型
  • 适用场景:在某个特点类型问题发生频率足够高的时候;
  • 优点:语法由很多类表示,容易改变及扩展此”语言“
  • 缺点:当语法规则数目太多时,增加了系统复杂度
  • 解释器模式和适配器模式;
  • java.util.regex.Pattern;

观察者模式:

  • 定义:

备忘录模式:

  • 定义:

命令模式:

  • 定义:

中介者模式:

  • 定义:

责任链模式:

  • 定义:

访问者模式:

  • 定义:

状态模式:

  • 定义:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值