谈谈我工作中的23个设计模式
叙述
从基础的角度看,设计模式是研究类本身或者类与类之间的协作模式,是对抽象归纳的一个比较好的解决思路。在日常工作中,运用 Java 设计模式思路,可以更好地去思考理解这些设计模式。
抽象工厂(Abstract Factory):多套方案
抽象工厂就是围绕一个超级工厂创建其他工厂。这个超级工厂也被称为其他工厂的工厂。 抽象工厂模式 属于创造性模式,它提供了创建对象的最佳方式。在抽象工厂中,接口是负责创建相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都可以根据工厂模式提供对象。
介绍
意图: 提供一个创建一系列相关或相互依赖对象的接口方法,无需指定它们具体的类。
主要解决: 解决接口选择的问题。
何时使用: 系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决: 在一个产品族里面,定义多个产品。
关键代码: 在一个工厂里聚合多个同类产品。
在工作中,我们应该具备提供多套设计方案的能力,提供多种选择性。需要有这样的前瞻意识,扩展自己的思维方式。
以下是抽象工厂概述图
生成器(Builder):善于分解
构建器,也称为构建器模式,使用几个简单的对象逐步构建一个复杂的对象。构建器模式属于创造性模式,它提供了创建对象的最佳方式。
介绍
意图: 将一个复杂的构建与其具体实现相分离,使得同样的构建过程可以创建不同的表现形式。
主要解决: 主要解决在软件系统中,有时候面临着”一个复杂对象”的创建工作。
何时使用: 一些基本部件不会变,而其组合经常变化的时候。
如何解决: 将变与不变分离开。
关键代码: 创建和提供实例,管理建造出来的实例的依赖关系。
工厂方法(Factory Method):抽象思考
工厂模式 (Factory Pattern)是 Java 中最常用的设计模式之一。工厂模式属于创建型模式,它提供了一种创建对象的最佳方式。
总的来说,在工厂模式中,我们创建对象的过程中,不会对客户端暴露创建逻辑,通过使用共同的接口,来指向新创建的对象。
工厂方法模式 是将提供某一产品的过程进行抽象,通过接口的模式去规范出来。如果我们转换思维,处理问题的思维逻辑,终究是发现事物的本质:
- 到底在做什么
- 我们的职责是什么
- 提供什么样的价值。
原型( Prototype ):传承知识
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这原型模式属于创建型模式,它提供了一种创建对象的最佳方式。
原型模式是实现了一个原型接口,该接口用于创建当前对象的克隆。 原型模式是说,利用拷贝对象的方法,减少一些复杂的创建过程。
单件(Singleton):专注
单例模式 (Singleton Pattern)是 Java 中最简单的设计模式之一。单例模式属于创建型模式,提供了一种创建对象的方式。单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。
注意:
- 1、单例类只能有一个实例。
- 2、单例类必须自己创建自己的唯一实例。
- 3、单例类必须给所有其他对象提供这一实例。
介绍
意图: 一个类仅有一个实例,具备全局访问点。
主要解决: 全局使用的类频繁进行创建与销毁。
何时使用: 当节省系统资源。
如何解决: 判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
关键代码: 构造函数 是私有的
单件模式是说在多线程的情况下,要保证对象只创建一遍,作为独一无二的资源。
单例模式的几种实现方式
单例模式的实现有多种方式,如下所示:
1、懒汉式, 线程 不安全
是否 Lazy 初始化: 是
是否 多线程 安全: 否
实现难度: 易
2、懒汉式,线程安全
是否 Lazy 初始化: 是
是否多线程安全: 是
实现难度: 易
3、饿汉式
是否 Lazy 初始化: 否
是否多线程安全: 是
实现难度: 易
4、双检锁/双重校验锁( DCL ,即 double-checked locking)
JDK 版本: JDK1.5 起
是否 Lazy 初始化: 是
是否多线程安全: 是
实现难度: 较复杂
5、登记式/静态内部类
是否 Lazy 初始化: 是
是否多线程安全: 是
实现难度: 一般
6、枚举
JDK 版本: JDK1.5 起
是否 Lazy 初始化: 否
是否多线程安全: 是
实现难度: 易
适配器 (Adapter):适应能力
适配器模式(Adapter Pattern)作为两个不兼容的接口之间的桥梁。适配器模式属于结构型模式。适配层往往不是提前的设计,而是基于现有现有的系统进行的妥协和适配。
结构图
介绍
意图: 将一个类的接口转换成客户希望的另外一个接口。
主要解决: 解决在软件系统中,将一些”现存的对象”放到新的环境中,而新环境要求的接口是现对象不能满足的应用场景。
何时使用:
1、系统需要使用现有的类,而此类的接口不符合系统的需要。
2、通过接口转换,将一个类插入另一个类系中。
如何解决: 继承或依赖。
关键代码: 适配器继承或依赖已有的对象,实现想要的接口。
总的来说,适配器是为了结合原来的能力,适配新的接口服务,比如适配不同的协议入口。
桥接(Bridge):合理关系
桥接 (Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。桥接设计模式属于结构型模式.
结构图
介绍
意图: 将抽象与实现分离,都可以独立的变化。
主要解决: 在有多种可变的情况下,用继承会造成类扩展性不高,运用起来不灵活。
何时使用: 实现系统可能有多个角度分类,每一种角度都可能变化。
如何解决: 把这种多角度分类分离出来,让它们独立变化,减少它们之间 耦合 。
关键代码: 抽象类依赖实现类。
桥接模式是将原来相互依赖的部分,通过上层接口再往抽象层提一下,减少类之间的直接合作,形成间接关系。
组合(Composite):递归思考
组合模式 (Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。
结构图
介绍
意图: 使用户对单个对象和组合对象的使用具有一致性。
主要解决: 客户程序可以处理复杂元素,从而使得客户程序与复杂元素的内部结构 解耦 。
何时使用:
1、对象的部分-整体层次结构(树形结构)。
如何解决: 树枝和叶子实现统一接口,树枝内部组合该接口。
关键代码: 树枝内部组合该接口,并且含有内部属性 List,里面放 Component。
组合模式通过继承和孩子节点,可以递归地去描述一个对象层次。