设计模式总结

发布于: 2020 年 06 月 21 日

1、设计模式定义

每一种模式都描述一种问题的通用解决方案;

设计模式是一种可重复使用的解决方案;

设计模式的四个部分:

  • 模式名称 - 简短的名称描述;

  • 待解决的问题 - 描述何时需要运用这种模式,以及运用模式的环境(上下文);

  • 解决方案 - 描述组成设计的元素(类和对象)、它们之间的关系、职责及合作。这种解决方案是抽象的,不代表具体的实现;

  • 结论 - 运用这种方案带来的利与弊;主要是指对 系统 弹性、扩展性 和 可移植性 的影响;

2、设计模式分类

2-1、从功能分

  • 创建模式(Creational Patterns),对类的实例化过程的抽象;

  • 结构模式(Structural Patterns),将类或对象结合在一起形成更大的结构;

  • 行为模式(Behavioral Patterns),对在不同对象之间划分责任和算法的抽象化;

2-2、从方式分

  • 类模式,以继承的方式实现模式,静态的;

  • 对象模式,以组合的方式实现模式,动态的;

3、本周学习的设计模式

3-1、 简单工厂模式(Simple Factory)

解决的问题:

简单工厂模式并不是真正意义上的模式,从创建型模式来看,参考 工厂模式 或 抽象工厂模式(一般很少用,因为不同类型的产品族在公司内部业务较少);

可以通过定义静态Map对象,存放 Type 和 实现类的关系;

优点:

  • 客户端不再依赖具体实现;

  • 对客户端来说是开放闭合(OCP)的;

缺点:

  • 工厂本身不具备开发闭合(OCP),因为新增类型需要修改;

3-2 单例模式(Singleton)

单一模式保证一个类只产生一个实例,使用Singleton有两个原因:

  • 性能需求:因为只有一个实例,可以减少实例的频繁创建和销毁带来的资源损耗;

  • 功能需求:当多个用户使用这个实例时,便于进行统一控制;

代码上,有如下几种实现:

1、使用static初始化对象实例;尽量使用这个方法构造单实例

2、使用synchronized关键字修饰获取对象方法,当static对象为null是初始化;

3、双重检查方式,但是注意 修饰 【实例引用】时必须使用 【volatile】关键字 保证可见性;

说明:

一定要有【私有构造函数】,保证实例只能通过方法获得;

3-3、组合模式

组合模式是一种“对象结构模式”,是用于把一组相似的对象当作一个单一的对象;

将对象组合成树形结构以表示【"部分-整体"】的层次结构。

组合模式使得用户对单个对象和组合对象的使用具有一致性;

解决的问题:在树型结构的问题中,客户程序可以像处理简单元素一样来处理复杂元素,从而使得【客户程序】与【复杂元素】的内部结构解耦。

何时使用: 1、表示对象的部分-整体层次结构(树形结构)。 2、希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。

优点: 1、高层模块调用简单。 2、节点自由增加。

缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

应用场景:部分、整体场景,如树形菜单,文件、文件夹的管理,操作页面展示。

3-4、适配器模式

作用:系统需要使用现在的类,这个类和我们所需要的不同;【继承类】或【依赖已有对象】;

何时使用:

 1、系统需要使用现有的类,而此类的接口不符合系统的需要;

2、想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有一致的接口;

3、通过接口转换,将一个类插入另一个类系中;

应用场景:

JDBC Driver,对具体数据库的适配;

优点:

1、可以让任何两个没有关联的类一起运行;

2、提高了类的复用;

3、增加了类的透明度;

4、灵活性好。

缺点: 

1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构;

2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。

3-5、装饰器模式

对象结构模式

适配器配称为包装器

装饰器 与 策略模式、模板方法比较:

  • 装饰器保持对象的功能不变,扩展其外观功能;

  • 模板方法和策略模式则保持算法的框架不变,而扩展其内部实现;

装饰器和继承的比较:

  1. 都可用来扩展对象的功能;

  2. 装饰器是动态的,继承是静态的;

  3. 装饰器可以任意组合,但也更加复杂;

3-6、 策略模式

对象的【行为型模式】;

系统在【多种算法中选择一种】;

解决的问题:在有多种算法相似的情况下,使用条件语句( if...else )所带来的复杂和难以维护;

何时使用:

一个系统有许多许多类,而区分它们的只是他们直接的行为;

优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。

缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。必须由客户端来决定何时调用;

3-7、模板方法(Template Method)

定义:类的行为模式;通过【继承】的方法来实现扩展,基类负责算法的轮廓和骨架,子类负责算法的具体实现;

组合VS继承

使用“继承”的模板方法比组合更容易实现;

何时使用:

  • 将一个大方法,变成多个可扩展的步骤;

  • 将 if/else 或者 switch 语句变成多态性;

问题:

  1. 将抽象算法和具体步骤耦合在一起,不能独立演化;

  2. 造成类的数量很多、类的层次很深;例如:Spring的测试工具类;

4、JUnit中的设计模式

1、模板方法

所有测试类需要继承TestCase这个类,运行runBare方法,各个子类继承 TestCase类,需要实现3个方法

(1) setUp()方法,包括,这里包括参数准备或者数据库连接初始化;

(2) runTest() 方法,在继承TestCase的类中,实现类的测试方法都以“test”开始,runTest()方法会执行这些测试方法;

(3) tearDown()方法,可以包含 资源释放,或测试数据回滚;

public abstract class TestCase extends Assert implements Test {
public void runBare() throws Throwable {
Throwable exception= null;
setUp();
try {
runTest();
} catch (Throwable running) {
exception= running;
} finally {
try {
tearDown();
} catch (Throwable tearingDown) {
if (exception == null)
exception= tearingDown;
}
}
if (exception != null)
throw exception;
}
protected void setUp() throws Exception { }
protected void runTest() throws Throwable { }
protected void tearDown() throws Exception { }
}

5、Spring中的设计模式:

包括Spring中的单例模式,Spring的MVC模式,以及Spring的依赖注入方式如何实现依赖倒置原则;

发布于: 2020 年 06 月 21 日 阅读数: 23
用户头像

Albert

关注

还未添加个人签名 2018.08.31 加入

还未添加个人简介

评论

发布
暂无评论
设计模式总结