设计模式

141 阅读6分钟

refactoringguru.cn/design-patt…

设计模式

[设计模式]是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
项目中有变化的部分,也有不变的部分。引入设计模式的前提是在变化(实现)中寻找稳定(接口)。

开闭原则

即对扩展开放对修改关闭。即在不改变本身代码的情况下其行为能扩展。我们在写代码的时候,一定不要着急开始写,而要多思考可能面临的问题,在需求可能改动的情况下,如何尽量减少代码的改动,而是通过扩展的方式实现。
当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。

单一职责

单一职责原则(Single Responsibility Principle, SRP):一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。
例如:类 A 负责两个不同职责:职责 1,职责 2。当职责 1 需求变更而改变 A 时,可能造成职责 2 执行错误,所以需要将类 A 的粒度分解为 A1,A2. 典型模式:
桥模式(Bridge),装饰模式(Decorator)

装饰模式

问题: 在某些情况下我们可能会过度地使用继承来扩展对象的功能,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。
定义: 动态(组合)地给一个对象增加一些额外的职责。就增加功能而言, Decorator模式比生成子类(继承)更为灵活(消除重复代码&减少子类个数). image.png 装饰模式的适用性
1)在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
2)处理那些可以撤消的职责。
3)当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

桥模式

问题: 由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个维度的变化。 定义: 将抽象部分实现部分分离,使他们都可以独立的变化(这里提到的内容与编程语言中的接口或抽象类无关。 它们并不是一回事。)
image.png 要点总结

  • Bridge模式使用对象间的组合关系解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自纬度的变化,即"子类化"它们。
  • Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单职责原则(即一个类只有一个变化的原因),复用性比较差。
  • Bridge模式是比多继承方案更好的解决方法。Bridge模式的应用一般在两个非常强的变化维度,有时一个类也有多于两个的变化维度,这时可以使用 Bridge的扩展模式。 模式必须由一方使用抽象类,持有使用接口的一方.
    桥接模式的适用性
    1).如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。
    2).设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。
    3).一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。
    4).虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
    优点是:
  • 抽象与实现分离,扩展能力强
  • 符合开闭原则
  • 符合合成复用原则
  • 其实现细节对客户透明
    缺点是:由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,能正确地识别出系统中两个独立变化的维度,这增加了系统的理解与设计难度。

桥模式对比装饰模式: 桥接模式是为了实现两个没有关联的维度的东西的自由组合,这里没有关联是指各自拥有自己的属性和方法,没有相同点(使用聚合或者组合)。装饰者模式使用了继承必然是两个种类具有相同的一些属性和方法,它不是为了实现两个维度的自由组合,是为了实现对对象的一层一层又一层包装,调用方法时,每一层包装递归的调用上一层的包装。

责任链模式

责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。 WeChataadefba7cdae763d8c11fa076bfffeb2.png

场景

责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
如果所需处理者及其顺序必须在运行时进行改变,可以使用责任链模式。
责任链模式的优点
责任链模式非常显著的优点是将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌,两者解耦,提供系统的灵活性。
责任链有两个非常显著的缺点
一是性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候,性能是一个非常大的问题。
二是调试很不方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。