柴毛毛大话设计模式——开发常用的设计模式梳理

扫一扫订阅我的文章

写在最前

  • 本文是笔者的一点经验总结,主要介绍几种在Web开发中使用频率较高的设计模式。
  • 本文篇幅较长,建议各位同学挑选感兴趣的设计模式阅读。
  • 在阅读的同时,也麻烦各位大佬多多分享!有你们的肯定,才有我继续分享的动力
  • 如需转载,请与我联系!

人工智能看面相

  • 最近忙里偷闲,对人工智能看面相进行了一些优化,欢迎各位大佬体验!
  • 体验后恳请各位大佬分享朋友圈!

这里写图片描述

基础学习:UML四种关系

耦合度大小关系

泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖

依赖(Dependency)

title

  • 一个人(Person)可以买车(car)和房子(House),那么就可以称:Person类**依赖于**Car类和House类
  • 这里注意与下面的关联关系区分:Person类里并没有使用Car和House类型的属性,Car和House的实例是以参量的方式传入到buy()方法中。
  • 依赖关系在Java语言中体现为局域变量方法的形参,或者对静态方法的调用。

关联(Association)

title

  • 它使一个类知道另一个类的属性和方法
  • 关联可以是双向的,也可以是单向的。
  • 在Java语言中,关联关系一般使用成员变量来实现。

聚合(Aggregation)

title

  • 聚合是关联关系的一种,是强的关联关系。
  • 聚合是整体和个体之间的关系,但个体可以脱离整体而存在。
  • 例如,汽车类与引擎类、轮胎类,以及其它的零件类之间的关系便整体和个体的关系。
  • 与关联关系一样,聚合关系也是通过成员变量实现的。但是关联关系所涉及的两个类是处在同一层次上的,而在聚合关系中,两个类是处在不平等层次上的,一个代表整体,另一个代表部分。

组合(Composition)

title

  • 组合是关联关系的一种,是比聚合关系强的关系,也以成员变量的形式出现。
  • 在某一个时刻,部分对象只能和一个整体对象发生组合关系,由后者排他地负责生命周期。
  • 部分和整体的生命周期一样。
  • 整体可以将部分传递给另一个对象,这时候该部分的生命周期由新整体控制,然后旧整体可以死亡。

策略模式

什么是策略模式

一个类中的一些行为,可能会随着系统的迭代而发生变化。为了使得该类满足开放-封闭原则(即:具备可扩展性 或 弹性),我们需要将这些未来会发生动态变化的行为从该类中剥离出来,并通过预测未来业务发展的方式,为这些行为抽象出共有的特征,封装在抽象类或接口中,并通过它们的实现类提供具体的行为。原本类中需要持有该抽象类/接口的引用。在使用时,将某一个具体的实现类对象注入给该类所持有的接口/抽象类的引用。

类图描述

title

如果类A中有两个行为X和Y会随着业务的发展而变化,那么,我们需要将这两个行为从类A中剥离出来,并形成各自的继承体系(策略体系)。每个继承体系(策略体系)的顶层父类/接口中定义共有行为的抽象函数,每个子类/实现类中定义该策略体系具体的实现。

其中,每一个被抽象出来的继承体系被称为一个策略体系,每个具体的实现类被称为策略

此时,策略体系已经构建完成,接下来需要改造类A。
在类A中增加所需策略体系的顶层父类/接口,并向外暴露一个共有的函数action给调用者使用。

在Spring项目中,策略类和类A之间的依赖关系可以通过依赖注入来完成。

到此为止,策略模式已经构建完成,下面我们来看优缺点分析。

策略模式的优点

1. 满足开放封闭原则

如果类A需要更换一种策略的时候,只需修改Spring的XML配置文件即可,其余所有的代码均不需要修改。

比如,将类A的策略X_1更换成X_2的方法如下:

<bean id="a" class="类A">
    <!-- 将原本策略实现类X_1修改为策略实现类X_2即可 -->
    <property name="策略接口X" class="策略实现类X_2" />
</bean>

此外,如果需要新增一种策略,只需要为策略接口X添加一个新的实现类即可,并覆盖其中的commonAction函数。然后按照上面的方式修改XML文件即可。

在这个过程中,在保持原有Java代码不发生变化的前提下,扩展性了新的功能,从而满足开放封闭原则。

2. 可方便地创建具有不同策略的对象

如果我们需要根据不同的策略创建多种类A的对象,那么使用策略模式就能很容易地实现这一点。

比如,我们要创建三个A类的对象,a、b、c。其中,a使用策略X_1和Y_1,b使用策略X_2和Y_2,c使用策略X_3和Y_3。
要创建这三个对象,我们只需在XML中作如下配置即可:

<bean id="a" class="类A">
    <property name="策略接口X" class="策略实现类X_1" />
    <property name="策略接口Y" class="策略实现类Y_1" />
</bean>

<bean id="b" class="类A">
    <property name="策略接口X" class="策略实现类X_2" />
    <property name="策略接口Y" class="策略实现类Y_2" />
</bean>

<bean id="c" class="类A">
    <property name="策略接口X" class="策略实现类X_3" />
    <property name="策略接口Y" class="策略实现类Y_3" />
</bean>

答疑

问:如何实现部分继承?也就是类Son1只继承Father的一部分功能,Son2继承Father的另一部分功能。

这是设计上的缺陷,当出现这种情况时,应当将父类再次拆分成2个子类,保证任何一个父类的行为和特征均是该继承体系中共有的!

title

问:随着需求的变化,父类中需要增加共有行为时怎么办?这就破坏了“开放封闭原则”。

这并未破坏“开放封闭原则”!在系统迭代更新的过程中,修改原有的代码是在所难免的,这并不违背“开放封闭原则”。
“开放封闭原则”要求我们:当系统在迭代过程中,第一次出现某一类型的需求时,是允许修改的;在此时,应该对系统进行修改,并进行合理地设计,以保证对该类型需求的再次修改具备可扩展性。当再一次出现该类型的需求时,就不应该修改原有代码,只允许通过扩展来满足需求。


观察者模式

观察者模式是什么

如果出现如下场景需求时,就需要使用观察者模式。

如果存在一系列类,他们都需要向指定类获取指定的数据,当获取到数据后需要触发相应的业务逻辑。这种场景就可以用观察者模式来实现。

在观察者模式中,存在两种角色,分别是:观察者被观察者。被观察者即为数据提供者。他们呈多对一的关系。

类图描述

title

  • 被观察者是数据提供方,观察者是数据获取方
  • 一个普通的类,如果要成为观察者,获取指定的数据,一共需要如下几步:
    • 首先,需要实现Observer接口,并实现update函数;
    • 然后,在该函数中定义获取数据后的业务逻辑;
    • update(Observable, Object)一共有两个参数:
      • Observable:被观察者对象(数据提供方)
      • Object:数据本身
    • 最后,通过调用 被观察者 的addObservable()或者通过Spring的XML配置文件完成观察者向被观察者的注入。此时,该观察者对象就会被添加进 被观察者 的List中。
  • 调用者才是真正的数据提供方。当调用者需要广播最新数据时,只需调用 被观察者 的notidyObservers()函数,该函数会遍历List集合,并依次调用每个Observer的update函数,从而完成数据的发送࿰
  • 13
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值