一. 设计模式的分类和功能
设计模式的分类主要可以根据模式作用的目的和模式作用的范围来进行区分。
- 根据模式的目的进行区分
- 根据模式的作用范围来区分
1.1 根据模式目的进行划分
根据模式主要用来完成什么工作进行划分,主要分为三种创建型, 结构型,行为型。
- 创建型模式:主要用于描述怎样创建对象,将对象的创建和使用分离。(填写创建型模式包含哪些)
- 结构型模式:主要用于描述如何将类和对象组成更大的结构。 (填写结构型模式包含哪些)
- 行为型模式:主要用于描述类和对象如何协同完成单个对象无法完成的任务,及如何分配职责。(填写行为模式包含哪些)
1.2 根据模式作用范围划分
看模式作用于类上还是对象上,分为类模式和对象模式。
- 类模式, 用于处理类与子类的关系, 这些关系通过继承来建立, 是静态的, 在编译期就可以确定的。
- 对象模式,用于处理对象之间的关系, 通过聚合或组合实现。
二. 创建型模式
2.1 单例模式
懒汉式(获取时再创建)
饿汉式(事先创建好)
2.2 原型模式
定义:用一个已经创建的实例作为原型,通过复制该原型对象创建一个类似的新对象。
优点:
- java自带的原型模式基于内存二进制流的复制, 性能比new优良
- 深克隆,简化对象的创建。
模式:
浅克隆:创建一个新对象,非基本类型的属性指向原对象的内存地址。
深克隆:创建一个新对象,同时新对象指向其他对象也会被克隆。
使用场景:对象创建的资源耗费太大,需要提升性能的时候。spring中的scope=’prototype’, JSON.parseObject()等都是原型模式的应用。
2.3 简单工厂模式
又叫做静态工厂模式,用于需要创建的产品不多的时候。直接一个类方法进行创建。
客户放只需要知道具体的工厂类,便可以创建出对应的产品。
2.4 工厂方法模式
抽象出一个抽象的具体工厂类, 无序关心其实现类。创建一个新产品的时候只需要添加一个新的具体工厂类,无序修改获取产品的接口。
抽象工厂方法模式组成套路:
- 抽象工厂
- 抽象产品
- 具体工厂
- 具体产品
afa-console中的命令行实现便是使用的抽象工厂方法模式。
三. 结构型
结构型模式描述的是如何通过类结构或者对象按照某种布局组成更加庞大的结构。
**1. 类结构型模式:通过继承机制来组织接口或者类 **
2. 对象结构型模式:通过组合或聚合来组织对象
组合和聚合的耦合度比继承的耦合度低,满足复用结构原则,所以对象结构类型比类结构类型更灵活,复用性更强
主要分为7种结构型模式:
- 代理模式Proxy:为某个对象提供一种代理来控制这个对象的访问。
- 适配器模式Adapter:将一个类的接口转换成客户端希望使用的另一个接口,从而达到兼容的效果。
- 桥接模式Bridge:将抽象和实现分离, 使用组合的方式代替继承关系来实现。
- 装饰模式Decorator:动态给对象增加一些职责功能。
- 外观模式Facade:为多个负责的子系统提供一个一致的结构。
- 享元模式Flyweight:通过共享技术支持大量的细粒度对象的复用。
- 组合模式Composite:将对象这成树状结构,
3.1 代理模式
代理模式主要是不想直接访问某个对象或者访问某个对象有困难需要中间对象的时候。
应用场景
- 远程代理,rpc实现的经典模式,jdk自带动态代理和cglib动态代理
- 虚拟代理,
3.2 适配器模式
解决的问题
某些接口不兼容的时候, 雷电接口转网口,usb的时候需要转接器,这个就是适配器做的事情。
适配器模式分为类结构型模式和对象结构型模式,类结构型模式的适配器耦合程度高,且要求对内部结构连接更透彻。
3.3 桥接模式
解决的问题
某些类具有两个或者以上的变化维度, 例如图形既可以按照形状也可以按照颜色进行划分,当有m种形状和n种颜色的时候, 如果使用集成的方式进行实现, 则需要实现m*n个具体的图形实现类。造成扩展困难,子类多的问题。
桥接就是解决这种问题, 当一个类有两个以上的方向需要变化拓展的时候,就可以通过桥接的方式,将抽象与实现分离,通过组合的形式代替继承的实现方式来降低耦合度。
桥接模式的拆分步骤:
- 抽象化类, 定义一个抽象类,真实的工程中可能还会有多级抽象化,这个抽象化中包含了那些需要变化的维度的抽象。
- 拓展抽象化类,抽象化类的子类,在这个类里面实现这些变化的维度的组合。
- 变化方向类,变化的维度的抽象类,供抽象化类使用
- 拓展变化方向类,变化的维度的具体的拓展实现,供拓展抽象化类使用。
实践案例
afa监控的推送–推送的维度分两个位图, 推送的方式(单虚拟机和多虚拟机模式的不一样), 推送的内容(总控和工作组推送的内容不一样),所以监控的推送实现就是通过桥接模式进行实现。
使用场景
- 当一个类存在两个独立变化的维度,且这两个维度都需要拓展的时候。
- 当一个系统不希望使用集成的时候,或者一个系统因为多层次集成导致类的数目急剧增加的时候。
- 当一个系统的抽象化角色和具体实现化角色之间需要更多的灵活性的时候。
3.4 装饰器模式
解决的问题
早餐煎饼,可以不加任何东西,也可以加蛋加肠等,但始终都是一个煎饼。房子装修加xxx都是一样,始终都是一个房子。
定义
不改变类的现有的结构的前提下,动态地拓展其功能,这些就可以通过装饰器模式来实现。
装饰器模式和桥接模式的区别:
装饰器模式是没有固定范围的拓展,事先不知道的。
桥接模式是一个又固定的拓展方向的,事先就已经知道的了。
装饰器的经典场景, jdk的io流的实现, 对InputStream做的各种增强, 可以直接读出流的字符串, 流的基本类型,缓存流等。
3.5 外观模式
解决的问题
注册一家公司需要去多个部门登记备案, 如果可以去一个综合部门统一办理就好了, 这个就是外观模式。
定义
外观模式又叫做门面模式,多个子系统或者独立的不同的实现统一走这一个接口对外开放。
3.6 享元模式
3.7 组合模式
四. 行为型
行为型模式用于描述程序运行时复杂的流程控制,设计算法和职责的分配。
行为型模式又分为类行为模式和对象行为模式,前者通过类的继承关系在类间分派行为, 后者采用组合或聚合在对象间分配行为。
11种行为型模式
- 模板方法Template,定义一个操作的算法骨架, 将算法的一些步骤延迟到子类的实现中。
- 策略模式Strategy, 定义一系列的算法,将每个算法封装起来
- 命令模式command,讲一个请求封装成一个命令对象
- 责任链ResponsibilityChain,将一个对象传导到下一个对象,知道请求被响应
- 状态模式state, 将一个对象在其内部记录一个状态, 在这个状态改变的时候改变对象的行为。
- 观察者模式Observer, 当对象间存在一对多的关系的时候, 当一个对象发生改变的时候, 将这个改变通知其他的对象。
- 中介者模式,两个对象之间的交互不需要直接耦合对方的引用, 通过一个中介对象进行简化。
- 迭代器模式, 提供一个
- 备忘录模式, 在不破坏封装性的前提下,获取一个对象的内部状态, 方便以后恢复它。
- 访问者模式,
- 解释器模式,
4.1 模板方法模式
解决的问题
银行办理业务, 取号, 排队,办理业务, 对柜员评价打分,流程都是一样的, 但是具体做的事情可能会不一样。
经典案例
生命周期实现。
4.2 策略模式
解决的问题
去一个地方可以坐火车,坐飞机或者其他的交通工具,都是一个个的策略、
拆分步骤:
- 抽象策略, 公共策略
- 策略实现
- 环境类, 根据环境的不同持有一个策略给客户端调用。
4.3 命令模式
五. 软件架构
什么是软件架构