设计模式六大原则:
1.单一职责 2.开闭原则 3.里氏替换原则 4.依赖倒置原则 5.接口隔离原则 6.迪米特法则
模式总结:
1.创建型模式总结 2.结构型模式总结 3.行为型模式总结
设计模式:
创建型模式:1.简单工厂 2.单例模式 3.原型模式 4.建造者模式
结构型模式:5.适配器模式 6.桥接模式 7.组合模式 8.装饰器模式 9.外观模式 10.享元模式
行为型模式:11.代理模式 12.模板方法 13.责任链模式 14.命令模式 15.迭代器模式 16.中介者模式
17.备忘录模式 18.观察者模式 19.状态模式 20.策略模式 21.访问者模式
一:单一职责:类的内部定义
定 义:一个类只负责一项职责,不要存在多余一个导致类变更的因素
反面例子:A类游泳池,负责游泳功能和跳水功能,当某一天,游泳功能改为跑步, 那么A类势必要进行改造,从而影响跳水功能
解决方案:遵循单一职责,游泳就为游泳类,跳水就为跳水类
二:开闭原则
定 义:类,函数,模块,开放拓展功能,关闭,修改功能 因为修改的时候,你不知道有哪几个地方调用它
反面例子:软件,一个类,函数,基本都是二次开发,迭代,很少是一手代码,对应一手程序员,所以修改会引起很大危险
解决方案:软件需要变化的时候,尽量拓展来满足需求,而不是直接去修改它,拓展之后的业务逻辑都是自己的,改起来so easily
三:里氏替换法则:类与类之间的关系
定 义:子类可以扩展父类的功能,但不能改变父类原有的功能
反面例子:继承带来好处,但是也带来了弊端,当一个类被其他类继承到时候,修改这个类,必须要考虑到所有的子类功能是否会产生问题
解决方案:
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
- 子类中可以增加自己特有的方法。
- 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
- 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
四:依赖倒置
定义; 核心思想就是面向接口编程,高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。
反面例子:员工依赖公司, 如果员工想离开,变成老板, 则必须要和公司接触依赖,
解决方案:都依赖一个接口平台, 只要符合接口平台原则,想变老板就老板
五:接口隔离原则
定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
反面例子:类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法。
解决方案:将臃肿的接口I拆分为独立的几个接口 按功能划分,类A和类C分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则。
六:迪米特法则: 类与类之间的联系
定义:一个对象应该对其他对象保持最少的了解。
反面例子:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
解决方案:尽量降低类与其他类之间的耦合。 只和自己直接的类联系
创建型模式总结:关注对象的创建,把对象的创建进行转移,复制,克隆 ,
目的就是降低对象与对象直接的耦合
结构型模式总结: 关注类与类之间的关系,继承,组合,依赖,
并且组合优于继承 目的就是降低类与类直接的耦合
1.为什么组合会优于继承,因为子类继承父类,父类会把所有方法都给子类,不管要不要
2.只能为单一类型服务
三种组合方式:属性字段注入 构造函数注入 方法注入
行为型模式总结:关注对象和行为的分离
目的就是降低对象和行为直接的耦合
类与类之间的关系
孤立存在的类是没有意义的 面向对象思想决定了类与类是交互的
类与类之间的关系的分为纵向与横向:
纵向:层级关系,继承与实现(is-a-kind-of) 横向:平级关系,组合-聚合-关联-依赖
1.简单工厂_创建型模式:
对 象:产品类 工厂类 抽象产品类
使用条件: 复杂的对象创建 用户不自己创建对象,而是由工厂来创建。 传一个值给工厂,工厂给你创建对应的对象
例 子: 用户class去工厂class买鞋class, 鞋clss是由工厂实例化的 而不是你用户来生产的,你只需要找到工厂 说明你要买的那种鞋,工厂就是给你需要的鞋
2.工厂方法_创建型模式:
对 象:产品类 抽象产品类 工厂类 抽象工厂类
使用条件:比简单工厂复杂的对象创建 用户不自己创建对象,而是由抽象工厂里面的具体工厂来创建
例 子: 用户去小米买键盘产品, 键盘产品是继承与,抽象小米产品的, 抽象小米产品下面 有很多小米手机,红米手机,
3.单例模式_创建型模式:
对 象: 实例化当前类的时候 只需要实例化一次
使用条件:多个对象,其需要实例化一个对象,全局只允许存在一个实例class
例 子:数据库连接,
4.原型模式_创建型模式:
对 象: 原型类 具体原型类1.2.3 实现克隆
使用条件:有重复对象,或相同对象,不同属性
例 子:qqvip,,qqvip每个有都有这个对象,但是每个qq vip等级不同,就会展示不同东西,
围棋棋子对象,都是用的棋子对象,只是颜色位置不一样
5.建造者模式_创建型模式:
对 象:指挥者 具体建造者(工人) 抽象建造者(工人) 产品
使用条件:比工厂方法更加复杂的对象创建。流程固定,
例 子: 建一栋房子, 有水泥工, 砌墙工,钢筋工, 他们的建造流程都由指挥者控制,先造地基,再建框架,流程不能乱 工人配好水泥钢筋产品
6.适配器模式_结构型: 不需要在项目刚设计的时候使用 是属于一种项目已经设计好,后期需求补救的一种方式
对 象: oracle类 抽象数据库类 适配器 第三方产品
使用条件: 第三方产品无法更改的情况下, 我们系统需要用, 可以用适配器转接
例 子: 本国人 抽象人, 翻译, 外国人 ,外国人不会说汉语,如果会说汉语就不需要翻译了,拿也就不需要适配器模式了
7.桥接模式_结构型:
class: 苹果手机类,抽象手机类 ,系统类,抽象系统类
使用条件: 解决多维度的变化,多重继承与变化封装
例 子: 苹果,华为,手机,都有自己的系统, 但是也可以刷机成,ios和andor系统, 如果手机和系统耦合太高,那么每一个系统和型号的改变,苹果手机类就要发生改变
8.组合模式_结构型:
class:
使用条件: 适用于 树形结构,递归自己
例 子: 我们的C盘里面就是一个树形结构,你不知道里面有多少个文件夹,但是现在要找出来c盘下面A文件里面的文件数量 就可以用递归实现 你只需要知道C://A文件盘位置
组合模式分为安全和透明模式 有父类和子类
安全:就是子类自己有递归方法
透明:就是父类自己有递归方法,这就造成了,子类继承父类的时候必须继承它的递归方法,会报错,需要忽略这个错误
9.装饰器模式_结构型:面向切面编程 (AOP) 动态的添加功能
class: 类与类直接的关系 降低耦合
使用条件: OOP设计的流程已经满足不了系统需求,需要用AOP来实现
例 子: 动态的添加功能 动态的给对象添加 层级功能 每一层都是单独的 可变顺序的,就像人穿衣服一样,每一件衣服都是独立的,材质,品质不同,也可以先穿外套,再穿内衣
10.外观模式_结构型:
class: UI BLL DAL
使用条件: 比较简单,就是多一层接口,降低UI与DAL层的直接交互
例 子: 经典的三层架构, 就是避免了ui层直接访问DAL数据层, 从而有了BLL业务逻辑层
旧有的系统与新系统之间的联系,可以使用外观模式, 都访问中间facade 来避免旧有系统持续扩大,和业务逻辑的管理 减少类之间的依赖
11.享元模式_结构型:
class: 类, 抽象类 抽象类中有公用的属性 类里面有自己私有的属性
使用条件: 把对象相同的属性归于一个类,其他不同属性通过外部类传递进来, 减少对象的重复创建
例 子: 就像斗地主一样,56张牌 new56个对象,三个人就占了56个内存地址, 那么一个棋牌平台估计经不起这么折腾,
他们区别就是里面的数字 花色不同,把这个提出来, new一个扑克对象, 里面包含一个类 而这个类的属性字段有:数字花色
12.代理模式_行为型:
class: 类 代理类 实现类
使用条件: 类不直接与实现类关联,而是创建一个代理来执行
例 子: 火车站售票处,彩票窗口, 不可能自己直接去火车上买吧, 当然也有这种情况,那么就会出现堵塞,权限也控制不了,还没有秩序
缓存代理:封装一个第三方缓存, 在代理里面进行缓存操作 提升性能 性能提升 优先考虑缓存
单例代理: 代理类里面做好单例
异常代理: 代理类里面做好异常控制
延迟代理:队列 前端延迟加载 一切可以推迟的东西晚点再做 按需加载 类初始化的时候为空,在方法执行的时候再去实例化
权限代理:鉴权-授权-认证 CallContxt 一个写 一个查 放在一个共享的地方
AOP:面向切面核心追求,不破坏封装的前提下,动态扩展功能
13.模板方法_行为型:
class: 类,抽象类 定义一个抽象父类,实现通用的处理流程 对于不同业务在抽象父类提供抽象方法,由不同子类去实现
使用条件: 应对在一个长业务固定流程中,环节可扩转变化就可以使用模板方法,对于部分相同业务在抽象父类提供虚方法,默认为父类方法,子类可重新定制个性化需求
例 子: 可变的和不可变的混在一起,把不可变的提取出来,做成公共的 同样的车,有公共的配置,大家都是四个轮胎,一个方向盘,但是有的人的车,需要车内饰个性化定制
14. 责任链_行为型:
class: 请求人, 请求的数据, 审批人
使用条件: 一条请求,需要流传到各个对象手里,但是各个对象审批顺序可以变化。
可以把请求结构包装存到一个第三方contenxt 也是责任链模式的标致, 审批过程中的节点动态扩展及更改
例 子: 请假审批,给主管 经理 ceo
15. 命令模式_行为型:
class: 请求者 抽象命令 具体命令, 执行者
使用条件: 需要发送一个请求,并且这个请求有相关命令,且数据很重要,需要实时备份 调用者将请求封装,>请求封装成命令对象,>最后发送给执行者,
命令>执行者 中间就可以做成异步队列服务,保存好命令集,哪怕数据库崩了,也可以执行命令集来恢复
例 子: 各种app付款指令>到数据库。如果每天凌晨0点备份 万一早上九点数据库损坏, 那么0点-9点的这段时间 就可以用命令来执行恢复
16.迭代器_行为型:
class:
使用条件: 需要循环的数据集合 list,数组,提供统一访问方式 如果不用foreach 迭代他们是需要不同的访问方式的
例 子: foreach 就是c# 完美实现了迭代器模式
17.中介者_行为型:
class: 发送类 中介类 接收类 (用户 角色 权限)
使用条件: 点到点需要变成点到面,
例 子: 群发消息下班,如果人事说要下班,没有中介者,那么需要一个个找到并通知,现在只需要通过邮件这个中介发送给大家
常见的就是我们系统程序的 用户 角色 和UI 管理者和普通用户展现的页面菜单不一样 用户拥有管理者角色 可以访问后台菜单 但是后台菜单可以给多个角色
18.备忘录_行为型:
class: 发起人 备忘录(第三方容器),管理者(负责发起人的存档和加载行为)
使用条件: 保存某种进度,备份行为
例 子: 游戏保存进度
19.观察者_行为型:
class: 观察者 抽象观察者 主题 具体主题
使用条件: 发布订阅的时候 一个接口需要把数据分发给不同的数据平台
例 子: 委托是最好的解决方案
20.状态_行为型:
class: context state 具体state
使用条件: 不同状态,执行不同行为,消除庞大的分支判断条件
例 子: 地铁闸门。投票行为, 避免恶意刷票
21.策略_行为型:
class: contenxt 抽象算法策略类 具体算法策略类
使用条件: 各种运用到算法的地方
例 子: 计算器,商场打折,营销活动
22.访问者_行为型:
class: 抽象客户 普通客户 VIp客户 访问者 客户的具体行为
使用条件: 固定场景, 客户这个类型是固定的不能变化,因为这个是最底层,
例 子: 表达式目录树就是使用访问者模式,我们使用表达式目录树的时候 把lambda ()=> m*n+1给访问者 他首先会使用递归一步步进行二元化拆解放进去进去是 左边:M*n 和右边:+1 第一步拆解下就是 左边M 右边N
去酒吧, 酒保就是访问者 当VIP客户去酒吧的时候 酒保会自动把你带到VIP客户区 然后VIP客户区 又分为 有拖的 和没拖的 然后有拖的买1W的酒 没拖的买啤酒 最后让你坐下嗨皮 访问者把你客户需要做的 都给你拆解好了 最终你过去直接坐下就好 普通客户来了也只需要交给酒保 直接坐下 给你安排的合理