架构师_设计模式之六大原则,及其模式总结

设计模式六大原则:

  1.单一职责   2.开闭原则  3.里氏替换原则  4.依赖倒置原则  5.接口隔离原则 6.迪米特法则

模式总结:

  1.创建型模式总结 2.结构型模式总结 3.行为型模式总结

设计模式:

  创建型模式:1.简单工厂  2.单例模式  3.原型模式  4.建造者模式  

  结构型模式:6.桥接模式   7.组合模式  8.装饰器模式   9.外观模式    10.享元模式  11.适配器模式  12.代理模式

  行为型模式:12.模板方法  13.责任链模式  14.命令模式  15.迭代器模式  16.中介者模式

        17.备忘录模式  18.观察者模式  19.状态模式  20.策略模式  21.访问者模式

六大原则:只是对我们写代码的一种指导性建议,也可以不遵守,按照自己风格写,但是写完之后,维护起来就是一团乱麻,而遵守了六大原则,就是提高代码的稳定性 可拓展,健壮性

     

为什么很多设计模式都差不多? 解决的问题不同,所以取了不同的名字,(就像水库抽水和放水,它们都是水没了,一个抽水是为了抓鱼,一个放水是为了泄洪,但是解决办法都是把水减少)

一:单一职责:类的内部定义

  定       义:一个类只负责一项职责,不要存在多余一个导致类变更的因素

  反面例子:A类游泳池,负责游泳功能和跳水功能,当某一天,游泳功能改为跑步, 那么A类势必要进行改造,从而影响跳水功能

  解决方案:遵循单一职责,游泳就为游泳类,跳水就为跳水类

  好处:类遵循单一职责,增加代码扩展性,代码很简单,不一定需要遵守。方法遵循单一职责增加程序稳定性,每个方法都可以独立演变

二:开闭原则

  定       义:类,函数,模块, 拓展开发,修改关闭

  反面例子:一个类,如果是祖传代码,你直接去修改,不知道他涉及到什么功能

  解决方案:软件需要变化的时候,尽量拓展来满足需求,而不是直接去修改它,拓展之后的业务逻辑都是自己的,改起来so easily

三:里氏替换法则:父类与子类之间的关系

  定       义:子类可以扩展父类的功能,但不能改变父类原有的功能

  反面例子:继承带来好处,但是也带来了弊端,当一个类被其他类继承到时候,修改这个类,必须要考虑到所有的子类功能是否会产生问题

  解决方案:

  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
  • 子类中可以增加自己特有的方法。
  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
  • 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
  • 子类继承父类的时候,不要使用new这个关键字去隐藏
  • 尽量左边使用父类申明  父类=new 子类  不要用 子类=new子类 如果子类使用了new隐藏了方法,那么就会出现问题

四:依赖倒置

  定义; 核心思想就是面向接口编程,高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。

  反面例子:三层 ui>bll>dal  ui高层非常依赖bll层

  解决方案: ui和bll层中间抽象一个IBll层 这样改动bll层就不会直接印象ui层,同理dal和bll也可以抽象出一个IDAL层 

五:接口隔离原则

  定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。

  反面例子:类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法。

  解决方案:将臃肿的接口I拆分为独立的几个接口 按功能划分(接口分拆),类去继承多个分拆的接口(接口多继承)。也就是采用接口隔离原则。

  接口隔离原则的意义:就是需要按照业务怎么去拆分成小粒度的接口,合适自己的业务就行

六:迪米特法则: 类与类之间的联系

  定义:一个对象应该对其他对象保持最少的了解。高内聚 低耦合

  反面例子:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。

  解决方案:尽量降低类与其他类之间的耦合。 只和自己直接的类联系  三层架构就是迪米特法则的最佳例子 

 

创建型模式总结:关注对象的创建,把对象的创建进行转移,复制,克隆        

       目的就是降低对象与对象直接的耦合

结构型模式总结: 关注类与类之间的关系,继承,组合,依赖,  包一层,用新的类来进一步封装原先的类

        并且组合优于继承   目的就是降低类与类直接的耦合   

        1.为什么组合会优于继承?,因为子类继承父类,父类会把所有方法都给子类,不管要不要

      2.只能为单一类型服务

 三种组合方式:属性字段注入  构造函数注入 方法注入

行为型模式总结:关注对象和行为的分离                                                    

      目的就是降低对象和行为直接的耦合

类与类之间的关系

  孤立存在的类是没有意义的 面向对象思想决定了类与类是交互的

  类与类之间的关系的分为纵向与横向:

  纵向:层级关系,继承与实现(is-a-kind-of) 横向:平级关系,组合-聚合-关联-依赖

 

1.工厂模式_创建型模式

  对        象:产品类  工厂类 抽象产品类

  使用条件: 复杂的对象创建 用户不自己创建对象,而是由工厂来创建。 传一个值给工厂,工厂给你创建对应的对象

  例       子:  用户class去工厂class买鞋class,  鞋clss是由工厂实例化的   而不是你用户来生产的,你只需要找到工厂 说明你要买的那种鞋,工厂就是给你需要的鞋

2.抽象工厂模式_创建型模式  

  对        象:产品类  抽象产品类  工厂类  抽象工厂类 

  使用条件:比简单工厂复杂的对象创建 用户不自己创建对象,而是由抽象工厂里面的具体工厂来创建

  例       子:  用户去小米买键盘产品,  键盘产品是继承与,抽象小米产品的, 抽象小米产品下面 有很多小米手机,红米手机, 

3.单例模式_创建型模式

  对        象: 实例化当前类的时候 只需要实例化一次 

  使用条件:多个对象,其需要实例化一个对象,全局只允许存在一个实例class 

  例       子:数据库连接

4.原型模式_创建型模式

  对       象: 原型类 具体原型类1.2.3 实现克隆

  使用条件:创建重复对象,保证性能,为什么性能快(因为使用的是内存拷贝,对象直接拷贝,而不是去重新构造一个函数,并且计算机内存操作速度是最快的)

  例       子:qqvip,,qqvip每个有都有这个对象,但是每个qq vip等级不同,就会展示不同东西,

       围棋棋子对象,都是用的棋子对象,只是颜色位置不一样

5.建造者模式_创建型模式

  对       象:指挥者 具体建造者(工人)  抽象建造者(工人)  产品

  使用条件:比工厂方法更加复杂的对象创建。流程固定,

  例       子: 建一栋房子, 有水泥工, 砌墙工,钢筋工, 他们的建造流程都由指挥者控制,先造地基,再建框架,流程不能乱  工人配好水泥钢筋产品   

  

 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

6.桥接模式_结构型

   class: 苹果手机类,抽象手机类 ,系统类,抽象系统类  

  使用条件:  解决多维度的变化,多重继承与变化封装

  例       子:  苹果,华为,手机,都有自己的系统, 但是也可以刷机成,ios和andor系统, 如果手机和系统耦合太高,那么每一个系统和型号的改变,苹果手机类就要发生改变

7.组合模式_结构型:

  class:  

  使用条件: 适用于 树形结构,递归自己

  例       子:   我们的C盘里面就是一个树形结构,你不知道里面有多少个文件夹,但是现在要找出来c盘下面A文件里面的文件数量 就可以用递归实现 你只需要知道C://A文件盘位置

      组合模式分为安全和透明模式  有父类和子类

      安全:就是子类自己有递归方法

      透明:就是父类自己有递归方法,这就造成了,子类继承父类的时候必须继承它的递归方法,会报错,需要忽略这个错误

8.装饰器模式_结构型:面向切面编程 (AOP) 动态的添加功能 结构模式的巅峰之作:组合+继承

  class:   类与类直接的关系 降低耦合

  使用条件: 希望能够动态增加功能+只有调整功能只需顺序

  例       子:   动态的添加功能 动态的给对象添加 层级功能  每一层都是单独的 可变顺序的,就像人穿衣服一样,每一件衣服都是独立的,材质,品质不同,也可以先穿外套,再穿内衣 

9.外观模式_结构型:

  class:     UI  BLL DAL

  使用条件: 比较简单,就是多一层接口,降低UI与DAL层的直接交互

  例       子:   经典的三层架构, 就是避免了ui层直接访问DAL数据层, 从而有了BLL业务逻辑层

       旧有的系统与新系统之间的联系,可以使用外观模式, 都访问中间facade 来避免旧有系统持续扩大,和业务逻辑的管理 减少类之间的依赖

 10.享元模式_结构型:

  class:      类, 抽象类   抽象类中有公用的属性    类里面有自己私有的属性

  使用条件: 把对象相同的属性归于一个类,其他不同属性通过外部类传递进来, 减少对象的重复创建   

  例       子:  就像斗地主一样,56张牌  new56个对象,三个人就占了56个内存地址, 那么一个棋牌平台估计经不起这么折腾,

         他们区别就是里面的数字 花色不同,把这个提出来, new一个扑克对象, 里面包含一个类   而这个类的属性字段有:数字花色

 

 

11.适配器模式_结构型:  不需要在项目刚设计的时候使用  是属于一种项目已经设计好,后期需求补救的一种方式

  对       象:  (江西人class,新疆人class 抽象class类)   适配器类   美国人类

  使用条件: 把不能用的类,通过适配,变的可以一起使用

  例       子:   江西人,新疆人都是中国人都会说中国话,但是如果想要使用美国人,那么久需要适配器(相当于翻译人员),这样就可以放在一起使用

12.代理模式_结构型: 

  对       象:        类  代理类    实现类

  使用条件:  类不直接与实现类关联,而是创建一个代理来执行。代理类不能扩展业务逻辑,代理是没资格更改本来实现的业务逻辑,但可以扩展公共逻辑,加日志,缓存之类的

  例       子:   火车站售票处,彩票窗口, 不可能自己直接去火车上买吧, 当然也有这种情况,那么就会出现堵塞,权限也控制不了,还没有秩序  

      缓存代理:封装一个第三方缓存, 在代理里面进行缓存操作 提升性能 性能提升 优先考虑缓存
      单例代理: 代理类里面做好单例
      异常代理:  代理类里面做好异常控制
      延迟代理:队列 前端延迟加载 一切可以推迟的东西晚点再做 按需加载 类初始化的时候为空,在方法执行的时候再去实例化
      权限代理:鉴权-授权-认证 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的酒 没拖的买啤酒    最后让你坐下嗨皮     访问者把你客户需要做的 都给你拆解好了 最终你过去直接坐下就好   普通客户来了也只需要交给酒保 直接坐下  给你安排的合理    

                         

 


 10.享元模式 

posted @ 2020-05-21 18:25  12不懂3  阅读(663)  评论(0编辑  收藏  举报
创作不易,请勿抄袭,欢迎转载!