23中设计模式

模式分类

创建型模式

作用:将对象的创建和使用分离

结构型模式

作用:将类或者对象组成一个更大的结构

行为型模式

作用:用于多个对象之间的相互协同工作;主要是分配职责

基础概念

接口 若干抽象方法的集合;
作用:

  1. 限制继承接口的类,必须实现其所有的方法。用于统一规范具有相似功能的多个类
  2. 对高层模块隐藏了类的内部实现(高层代码不用关注每个实现类的逻辑,只需要关心其统一的接口的定义规范就可以了)

OOP七大原则

单一职责原则(Single Responsibility Principle)
一个类只负责一件事。一个类中应该是一组相关性很高的函数及数据的封装;原则,一个类只能因为一个需求的改变而进行修改。
优点:
控制类的颗粒度大小、将类解耦、提高其内聚性

开闭原则(Open Close Principle)
对扩展开放,对修改关闭;增加新功能,不会对之前的功能造成影响;
优点:
修改代码需要考虑,对此处逻辑的影响,对其他调用方的影响,可能会导出bug出现,或者让代码越来越臃肿。因此需要尽量避免代码的修改,尽可能新增逻辑来实现新功能。
实施案例:

  1. 主要目标是减少调用方的代码修改。仅仅需要提供方去扩展代码。调用方少量修改代码就可以。比方提供方的具有相同功能的类使用统一的接口来对类进行限制。那么调用方就可以减少代码的修改了。
  2. 尽量不要修改原来的类,而是新增或继承原来的类。但是如果发现来源的类已经烂到不行了,当然也可以进行重构。

里氏替换原则(Liskov Substitution Principle)
继承必须保证父类所拥有的性质在子类仍然成立。如果一个类可以作为参数运行成功,那么其子类也不应该报错。
实施原则:

  1. 尽量不要重写父类的方法。而是新增特有方法。
  2. 如果要重写,需要考虑里氏替换原则。会不会对调用方造成困扰。业务逻辑应该考虑对其他方法调用是否有影响。接受参数应该更加宽松,返回参数应该更加严格。
    优点:
  3. 规范了父类与子类之间安全的继承,继承是安全的,代码的复用才是安全的。

依赖倒置原则(Dependence Inversion Principle)
面向接口编程,不要面向实现编程。(将具体实现通过抽象后的更加通用的接口来实现,这样底层代码更加统一,依赖于接口的底层代码修改之后,不会影响调用的地方)
实现:

  1. java中,高层代码中使用抽象类来接收。只调用对象中和抽象类中公共的方法和属性
  2. python中,只需要传递进来的对象都根据抽象类来调用就可以了
    优点:
  3. 降低高层代码对细节的依赖。降低耦合度。

接口隔离原则(Interface Segregation Principle)
为各个类建立他们专用的接口;站在接口的角度实现高内聚;避免实现类中实现不必要的方法;
实现:

  1. python可以通过多继承的方式需要继承哪些接口就继承哪些,避免不必要的方法,(类似mixin)实现起来更加灵活
  2. java虽然没有多继承,但接口的实现可以多继承。可以实现多个相互隔离的接口,让具体实现类中同时实现多个需要的接口。
    优点:
    和单一职责原则具有相同功效。

迪米特原则(Least Knowledge Principle)
尽可能少的使用调用类中的细节逻辑。降低各个类之间的耦合性;
实现:
类中尽可能将常用的方法高内聚到类中,避免高级代码中还需要考虑如何如何来调用实现类。一旦实现类发生修改,就会对高层代码产生影响。
优点:
属于该类的知识内聚到该类中,降低与调用方的耦合度。

合成复用原则(CARP)
尽量使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现;包含原则;
继承有很多局限性:

  1. 继承属于一种硬编码。如果没有遵守里氏替换原则,父类一旦修改,所有子类都需要进行改变
  2. 如果父类增加了子类中不需要的方法,子类就比较尴尬,只能平白无故多出不需要的方法。
  3. 过多层级的继承关系会让多个层级之间的类过度耦合。改动牵一发动全身
    使用组合方式优点:
  4. 各个类可以遵循单一职责原则,实现各自的功能,更加清晰。同时也可以提供代码的复用度
  5. 组合方式使用方,不用担心更改代码会影响到其父类。没有继承关系,不需要遵循里氏替换和依赖倒置原则。
  6. 可以动态替换使用到的组合类。
工厂模式

作用:实现创建者和调用者的隔离
oop原则:开闭原则

简单工厂模式

定义: 工厂中有多个方法用来创建很多的产品
优缺点: 非常灵活;隐藏了产品创建的参数及细节。但是如果新增产品需要修改工厂方法。不符合开闭原则。
具体实现过程:

  1. 定义接口
  2. 通过接口实现具体的类(工厂可以生产的产品)
  3. 通过工厂类的一个方法实现产品的实例化,可以隐藏掉具体产品类的实例化过程;
工厂方法模式

定义: 工厂的工厂;定义多个系列工厂的抽象工厂;每个工厂都会实现抽象工厂的所有接口,每个工厂都有自己的产品;
优缺点: 不太符合开闭原则;修改抽象工厂之后所有的工厂都要跟着修改,不符合开闭原则;
具体实现过程:

  1. 在简单工厂的基础上,需要定义工厂的接口,每个工厂都通过工厂接口来实现自己的工厂,做到所有工厂都有相同的方法,调用方式保持一致;
抽象工厂模式

定义: 创建一个工厂接口,让工厂子类来创建一系列相关或相互依赖的产品。
一个工厂可以生产一套产品。
优缺点:
限制多个产品的依赖关系。让多个产品具有一致性,而不需要高层代码关心。

建造者模式

定义:
建造者模式与抽象工厂模式相比更加注重一步步构建产品的过程。或顺序或细节
实现过程:

  1. 创建一个工厂(建造者builder)接口,让实现工厂接口的工厂创建一系列的零件,并赋值给初始化的产品的属性。
  2. 另外会有Director,用于控制零件制造的顺序,最终返回一个拼装好的产品。
  3. client首先实例化一个工厂,然后将工厂对象作为参数传递给Director,实例化返回一个产品对象。
    优点
  4. 可以对构建过程进行更精细的控制(director)
  5. 将构造代码(director)和表示代码(实际工厂类)分开
  6. 隐藏了内部结构和装配过程

单例模式

定义:
保证一个类只有一个实例,并提供一个全局的访问点
实现过程:

优点:

  1. 对实例进行控制,保证全局唯一
  2. 避免了使用全局变量情况下,变量被污染的可能;

适配器模式

定义:
保证两个方法不同的功能类似的类,可以适配为同一的方法名称;
实现方式:

  1. 多继承方式实现,继承一个接口及另外一个类 (继承方式为硬编码,不够灵活)
    在接口必要方法中调用另外一个类的方法
  2. 组合的方式(类的一个属性是其他类的实例化),在该类中的指定方法中调用属性类中的对应方法

桥模式

定义:
使一个事物的两个维度,分离,并且独立的变化(服从高耦合,低内聚的原则)
角色:
抽象者, 实现者
实现:

  1. 分别定义这两个维度的接口,将抽象角色使用组合的方式建立与实现角色的关系;将实现角色使用方法传参的方式与抽象角色建立关系。即二者之间建立了松耦合的关系
  2. 按照定义的接口分别实现对应的维度类的实现
  3. 将实现者实例化之后作为参数传给抽象者,调用抽象者统一的方法来实现具体的逻辑。建立了两个维度松耦合的关系,符合开闭原则
    优点:
    抽象和实现相分离,
    松耦合,易扩展,满足开闭原则

组合模式

定义:
将多个对象组合成树形结构,以表示‘部分整体’的层次结构;组合模式使得组合对象和单个对象的操作保持一致性,因为其根据统一的接口实现;
角色

  1. 抽象组件,叶子组件和复合组件都通过抽象组件实现。保证了叶子组件和复合组件都有公共的方法。
  2. 叶子组件
  3. 复合组件
  4. 客户端
    使用场景
  5. 单个对象和组合对象同时存在的情况
  6. 有递归形式存在的更加使用
  7. 让单个组件和复合组件有共同的表现

外观模式

定义
在底层代码和高层代码之间封装一层逻辑,屏蔽底层代码的更多细节。方便高层代码的调用。在外观类中统一调用封装好的底层代码,从而避免高阶代码中使用的错误。
角色
外观(客户端直接调用),子系统类(外观中调用的对象)
实现:
组合方式
隐藏了底层代码的细节。降低了高层代码和底层代码的耦合度

代理模式

定义
为其他实体建立一个可以访问指定实体的代理
分类
远程代理:访问一个远程的资源;隐藏了代理为位于远程的实时。
虚代理:按照需要进行访问,优化访问资源。
权限代理:为访问做一个权限控制。
角色
抽象代理, 用于统一所有代理类的方法
实体,直接访问实体的类。实现了抽象代理
代理,实现了抽象代理,并且组合的方式对接实体
优点:
分离了实体访问 和 访问的细节

行为型模式

责任链模式

定义:
多个对象都有机会处理请求,从而避免发送者和接受者的耦合关系。使用组合方式将这些对象连成一条链,并沿着这条链递归下去,直到有一个对象可以处理它。所有的处理者都是根据统一接口实现的。
角色
抽象处理者;保证所有具体处理者具有相同的调用方式。
具体处理者;每个处理者使用组合方式和更高层的处理者链接,在本处理者无法处理时,调用更高层的处理者的同样的处理方式。
客户端;调用最低层次处理者,直到情况被处理。
优点
降低耦合度;
根据运行时来决定由哪个接受者来处理,而无需客户端来判断调用哪个接收者。客户端统一调用第一个接受者

观察者模式

定义
对象间的一个一对多的订阅关系;当发布者发生改变时,所有订阅者都会发生改变;观察者和订阅者之间是一种松耦合的状态;
角色
抽象主题;可以不是一个接口。一般需要有attach(添加观察者方法),detach(删除观察者方法),notify(通知观察者方法)。
抽象观察者;使观察者具有统一的更新数据方法,方便主题中进行调用。
具体主题:在设置观察者的属性时,通过notify方法通知其所有绑定的观察者。
具体观察者:通过实现update方法来接受主题的通知及消息内容。
场景:
将事物的两个维度封装在两个独立的对象中,使两个维度可以独立改变,同时可以建立某种关联关系
一对多的关系,并且不知道多个对象是谁,观察者和主题是松耦合的关系

策略模式

定义
将策略和数据分开,并且可以切换使用不同的策略
角色
抽象策略;使多个具体策略具有统一的方法。方便上下文的调用。
具体策略;实现具体的策略算法
上下文;有用户切换策略的方法和执行策略的方法。方便客户端切换多个策略和使用具体的策略。为高层代码屏蔽了底层代码的细节。
缺点:
高层代码必须直到不同策略的优缺点。

模板方法模式

定义
在接口中定义模板方法,该模板方法中实现了算法的骨架,通过抽象出来的其他通用的方法来实现具体的步骤
一次性实现算法中不变的部分
角色
抽象类:定义算法的骨架(包含的子算法,子步骤),及子算法执行的步骤和具体的细节。
具体类:实现抽象类中需要实现的具体的子步骤。
适用场景
抽取多个算法中共共同的部分,实现代码的复用。
控制子类扩展。仅仅让合适的子类去继承。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岳大博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值