架构师训练营第 0 期第 3 周学习总结
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、装饰器模式
对象结构模式
适配器配称为包装器
装饰器 与 策略模式、模板方法比较:
装饰器保持对象的功能不变,扩展其外观功能;
模板方法和策略模式则保持算法的框架不变,而扩展其内部实现;
装饰器和继承的比较:
都可用来扩展对象的功能;
装饰器是动态的,继承是静态的;
装饰器可以任意组合,但也更加复杂;
3-6、 策略模式
对象的【行为型模式】;
系统在【多种算法中选择一种】;
解决的问题:在有多种算法相似的情况下,使用条件语句( if...else )所带来的复杂和难以维护;
何时使用:
一个系统有许多许多类,而区分它们的只是他们直接的行为;
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。必须由客户端来决定何时调用;
3-7、模板方法(Template Method)
定义:类的行为模式;通过【继承】的方法来实现扩展,基类负责算法的轮廓和骨架,子类负责算法的具体实现;
组合VS继承
使用“继承”的模板方法比组合更容易实现;
何时使用:
将一个大方法,变成多个可扩展的步骤;
将 if/else 或者 switch 语句变成多态性;
问题:
将抽象算法和具体步骤耦合在一起,不能独立演化;
造成类的数量很多、类的层次很深;例如:Spring的测试工具类;
4、JUnit中的设计模式
1、模板方法
所有测试类需要继承TestCase这个类,运行runBare方法,各个子类继承 TestCase类,需要实现3个方法
(1) setUp()方法,包括,这里包括参数准备或者数据库连接初始化;
(2) runTest() 方法,在继承TestCase的类中,实现类的测试方法都以“test”开始,runTest()方法会执行这些测试方法;
(3) tearDown()方法,可以包含 资源释放,或测试数据回滚;
5、Spring中的设计模式:
包括Spring中的单例模式,Spring的MVC模式,以及Spring的依赖注入方式如何实现依赖倒置原则;
版权声明: 本文为 InfoQ 作者【Arthur】的原创文章。
原文链接:【http://xie.infoq.cn/article/a7a20b16a5d3bcd6bc4b0bb9c】。未经作者许可,禁止转载。
评论