设计模式总结四(外观模式、建造者模式、观察者模式和抽象工厂模式)

        这么多天里,我已经读完了《大话设计模式》。放寒假了,没有了通过学业考试的重担,阅读技术书籍的时间页多出来了不少。

        在今天我刚阅读了《kafka权威指南》的第一章,关于介绍kafka这个消息发布与订阅系统的概念。在之前的一份实习中,我曾经接触到了kafka,但是我一知半解,也没有深入的了解为什么会有kafka的存在。恰巧前几天我在市图书馆看到一本名为《kafka权威指南》的书,于是就看了一小会。回来的时候意犹未竟,但也没有借回来,于是从网上找了本电子书继续学习。

        好了,现在切入正题,先总结外观模式。

外观模式

        书中在P108页给出的定义是这样的:外观模式为子系统的一组接口提供了一个一致的界面,此模式定义了一个高层接口,这个接口使得这一个子系统更加容易使用。结构图如下:

        外观类包含了所有的子系统的方法或者属性,进行组合,方便其他人进行调用。外观模式是之前的迪米特法则和依赖倒转原则的很好体现。

        依赖倒转原则是指:高层模块不应该依赖低层模块,高层模块和低层模块都应该依赖于抽象。抽象不应该依赖于细节,而细节应该依赖于抽象。

        迪米特法则也叫最少知识原则,迪米特法则(LoD)的和心思想是如果两个类不用通信,那么这两个类就不应当发生直接的相互作用。但如果其中一个类必须要调用另一个类的某个方法的时候,需用第三者转发这个调用,及尽量可能的将成员函数和成员设置成private类型。

        外观模式可以用来解耦合,对于一个不是太大的项目,他的代码已经有坏掉的味道时(尤其是我以前写的那些项目,啊哈哈哈,有空我想根据设计模式的思想改一下),可以用外观模型进行重构和解耦合。即使用面向对象的方法,将许多功能函数归到一类里去,尤其是变量都是差不多的那些功能函数,建立起包含了成员和成员函数的类。之后,再考虑用工厂模式等方式进行进一步改进。

        或者,遇到一个较复杂的项目,也可以用外观模式进行设计,用来给原来的一楼代码提供比较清晰简单的接口。这样不用改动原来的代码,也能提供新的功能,且能降低耦合度。

扫描二维码关注公众号,回复: 13982689 查看本文章

建造者模式

        建造者模式是在创建复杂对象算法应该独立于该对象的组成部分时,且创建复杂对象的步骤独立于装配该对象时。书中举了装配小人玩具的例子,装配小人玩具的步骤都是装脑袋、身体、胳膊和大腿这些步骤,不同的地方是脑袋、身体、胳膊和大腿是不一样长不一样外观这样,但步骤都是一样的,装配方式也是一样的,于是就可以使用建造者模式。换到代码中,我们实际上只要重写人物建造的抽象类的抽象方法即可。

        书中P115页给出的定义如下所示:建造者模式将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。

        建造者模式的好处在于使得建造小人的代码与表示小人结构的代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要定义一个具体的建造者就可以了。

观察者模式

        观察者模式又叫发布-订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使得他们能够自己更新自己。(书P131)

        观察者模式结构图如下所示:

        为什么GoF会想到观察者模式呢?当许多类组成一个相互协同作用的系统时,程序员必然需要维护各个不同,但相关的类之间的一致性。于是这就形成了一种紧耦合的类间关系,维护这样的代码会很累,这是我们所不期望出现的,于是就有了观察者模式。

        通过设定一个抽象观察者类,进而具体化出各种形形色色的观察者类,用于生成一个个不同的观察者。每一个观察者拥有一个update成员函数(方法),用于更新被观察对象的状态。Subject类则是提供了添加观察者的方法Attach和绑定观察者与被观察者的方法Detach,以及一个Notify方法用于通知所有相关的被观察者。所谓”相关的被观察者是用引用的方法将其写入subject的具体类中里来实现的。所以,当情况有变化时,就可以通过Notify方法通知所有相关的“被观察者”。

抽象工厂模式

        先给出书上P149页的定义:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。抽象工厂结构图如下所示:

         抽象工厂模式是对工厂方法模式的进一步改进。当有两种不同的、且类似的子类时使用。就像让一条流水线生产两种或者多种类似的商品一样,如果可以对流水线进行模块化设计,当要生产另一种商品时,能通过切换模块进行迅速转换生产对象。

        如果你不理解这句话,你就想想这个具体的例子,当一个Django项目本来用默认的SQLite写的,然后某个不写代码的又能管事的,要求你改用MySQL或者Oracle、SQL server、Access。诸如此类的事情一旦发生,对于一个没有事先使用抽象工厂模式的项目(或者那时候编码者还不知道这个模式的存在),那一定会被气的抓狂。尤其是从MySQL改成SQL server时,这意味着好多不支持的SQL语句都得修改,还得一句句的找,绝对气死人又累死人(哈哈哈好吧不吐槽了,切入正题)。

        如果项目一开始摸不准会不会中途换数据库,那就用抽象工厂模式就对了!它的思路与从简单工厂模式到工厂方法模式的想法是类似的!就是进一步细分,如图所示,设置一个工厂抽象类,用于具体化出不同的工厂,对于上一自然段的例子来讲,例如MySQL工厂、SQLserver工厂等等。该工厂类可以进而生成创建MySQL对象的“创建用户方法”。于是使用MySQL就创建MySQL对象,使用SQLserver就创建SQLserver对象。

        然后,Client也是抽象类,用于抽象出具体的用户类,例如MySQL用户类。可以用写各个具体的增删改查操作的方法了。由于各个数据库的SQL语句有差异,因此在这里分开来写就可以解决问题了。


以上就是这么多。最近几天一是有点累,但主要的是忙。是教资复习繁忙,主要是背诵很难搞,又要练物理题,实在是累死了,所以没有太多时间继续写博客。好在这篇博客分了好几天,终于是写完了。

END

猜你喜欢

转载自blog.csdn.net/qq_41938259/article/details/122541304
今日推荐