设计模式读书笔记

希望通过记录一些关键点做到实际开发中能够得心应手。

目录

状态模式

策略模式

观察者模式

装饰者模式

适配器模式 

外观模式

抽象工厂模式

工厂方法模式 

单例模式

命令模式

模板方法模式 

迭代器模式 

组合模式 

代理模式

建造者模式 

桥接(Bridge)模式

责任链模式

中介者模式

原型模式(Prototype)

模型-视图-控制器


状态模式

这个模式可能工作中会遇到,将可以互换的行为封装起来,然后使用委托的方法,决定使用哪一个行为,状态基转移场景

这种设计会大量新增状态类,对于一些复杂场景会非常管用;对一些简单场景,比如状态里面只有一个处理函数,状态基转换也比较简单,顺序递增,可能只需要封装函数即可。

int state = 0;
switch (state) {
    case 0:
        DoStateStart();
        break;
    case 1:
        DoStateProcess();
        break;
    case 2:
        DoStateStop();
        break;
    default:
        break;
}

void DoStateStart()
{
    ...
    state++;
}

void DoStateProcess()
{
    ...
    state++;
}

void DoStateStop()
{
    ...
    state = 0;
}

策略模式

定义算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。这也是“多用组合,少用继承”的设计原则,用HAS-A(有一个)代替IS-A(是一个)

继承:

组合: 

 

观察者模式

定义了对象只看的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新

        观察者是否需要持有被观察者对象的实例?持有的话,由观察者调用被观察者的注册接口和取消注册接口,但是被观察者的生命周期需要关注和管理

        观察者通过notifyObserver接口通知被观察者,这是push,而不是被观察者来调用观察者的接口,这是pull。

        这里的被观察者可以搞个继承,需要被观察的的都继承自Observalbe,它里面包含必须要实现的两个函数:registerObserver()和notifyObserver()

装饰者模式

目的是想在原来的基类的基础上增加些功能,一种设计思想是通过继承的方式不断增加子类,而且需要不可避免的修改基类的函数,可能代码长这样

class Base
{
    virtual int Cost()
    {
        int cost = 0;
        if (HasTea()) {
            cost += 2;
        }

        if (HasMilk()) {
            cost += 3;
        }
    }

    virtual bool HasTea() = 0;
    virtual bool HasMilk() = 0;
}

class A : public Base
{
    virtual bool HasTea() {return false;}
}

class B : public Base
{
    virtual bool HasMilk() {return true;}
}

这种设计违反了设计原则:开放-关闭原则,类应该对扩展开放,对修改关闭 。也就是基类在稳定之后尽可能不要再修改

装饰者和被装饰者应该具有相同的基类,或者装饰者要继承被装饰者,这样做的目的是为了在使用被装饰者的地方可以使用装饰者替代;这里使用继承的目的仅此而已;装饰者内部需要引用被装饰者,装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以打到特定的目的。装饰者定义;我们平时使用I/O相关类使用的就是装饰者设计模式,另外可以有多层包装,

Component* component = new Decorator2(Decorator1(ConcreteComponent()));

适配器模式 

将一个类的接口,转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以合作

外观模式

提供了一个统一的接口,用来访问子系统中的 一群接口,外观定义了一个高层接口,让子系统更容易使用

 

抽象工厂模式

 允许客户使用抽象的接口来创建一组相关的产品,而不需要知道实际产出的具体产品是什么,这样一来,客户就从具体的产品中被解耦。

该模式解决了一种依赖:客户代码不再依赖具体的产品子类,只依赖工厂类返回的抽象类。这叫做依赖倒置原则,客户代码依赖抽象类,产品子类也依赖这个抽象类。这也是我们说的的要依赖接口编程,而不是依赖实现编程

工厂方法模式 

抽象工厂模式和工厂方法模式的区别:

抽象工厂模式-与-工厂方法模式区别_wangwenhui11的博客-CSDN博客_工厂方法模式和抽象工厂模式的区别

它的里面是一堆工厂方法,每个工厂方法返回某种类型的对象。

比如说工厂可以生产鼠标和键盘。那么抽象工厂的实现类(它的某个具体子类)的对象都可以生产鼠标和键盘,但可能工厂A生产的是罗技的键盘和鼠标,工厂B是微软的。

这样A和B就是工厂,对应于抽象工厂;
每个工厂生产的鼠标和键盘就是产品,对应于工厂方法;

用了工厂方法模式,你替换生成键盘的工厂方法,就可以把键盘从罗技换到微软。但是用了抽象工厂模式,你只要换家工厂,就可以同时替换鼠标和键盘一套。如果你要的产品有几十个,当然用抽象工厂模式一次替换全部最方便(这个工厂会替你用相应的工厂方法)

所以说抽象工厂就像工厂,而工厂方法则像是工厂的一种产品生产线

单例模式

 确保一个类只有一个实例,并提供一个全局访问点。单例模式相较于全局或静态变量来说,有个好处是可以延迟实例化。单例模式的代码看着比较简单,但是有很多的注意事项,比如用构造函数需要private,全局访问点需要加锁互斥等

还有个问题,单例模式就真的能确保单例吗?如果不同的动态库通过静态链接的方式引用,那这几个动态库是指向同一个单例吗?答案不是,动态库 静态库 混合使用下的单例模式bug - 知乎

 解决方案也就是将单例静态库编译成动态库,其他动态库通过动态库链接到该单例实例

命令模式

将请求和接收者封装成一个对象,这个对象只暴露出execute()方法,当此方法被调用时,接受者会执行一系列动作。工作中经常用到一个场景是将命令对象丢进一个队列里,有一个单独的线程从该队列里取出命令对象执行。

模板方法模式 

在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤

 钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现。钩子的存在,可以让子类有能力对算法的不同点进行挂钩。要不要挂钩,由子类自行决定。

迭代器模式 

提供一种方法能够顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

组合模式 

允许将对象组成树形结构来表现“整体/部分”层次结构,组合能让客户以一致的方式处理个别对象以及对象组合。

代理模式

远程代理好比远程对象的本地代表

 代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问,被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象

经常讲到的一个例子是显示图像,在创建开销大的对象的时候,如果没有创建好先返回一个提示,同事创建异步线程创建对象,当对象真正创建完成之后再重新显示。

建造者模式 

设计模式之建造者(Builder)模式 - 阿Jay - 博客园

造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。建造者模式属于对象创建型模式。

桥接(Bridge)模式

将抽象与实现分离,使它们都可以独立变化

 桥接模式如果抽象不变化的话,只有一个抽象和多个实现的话,那它就是最简单的接口与实现分离;Adapter模式和Bridge模式具有一些共同的特征,他们都给另一对象提供了一定程度的间接性,因而有利于系统的灵活性。它们的不同之处在于用途。Adapter主要为了解决两个已有接口之间不匹配的问题。Bridge模式是软件设计之初就考虑的,

责任链模式

责任链(Chain of Responsibility)模式的定义:为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

注意:责任链模式也叫职责链模式。

在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程,请求会自动进行传递。所以责任链将请求的发送者和请求的处理者解耦了。

中介者模式

中介者(Mediator)模式的定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用。

中介者模式是一种对象行为型模式,其主要优点如下。

  1. 类之间各司其职,符合迪米特法则。
  2. 降低了对象之间的耦合性,使得对象易于独立地被复用。
  3. 将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。


其主要缺点是:中介者模式将原本多个对象直接的相互依赖变成了中介者和多个同事类的依赖关系。当同事类越多时,中介者就会越臃肿,变得复杂且难以维护。 

中介者模式和观察者模式的区别:中介者需要封装复杂的语义,

原型模式(Prototype)

 提供clone函数复制自己

C++是静态语言,运行时刻只能得到很少或者得不到任何类型信息。

一开始我的疑问点是为什么不直接调用该类的复制构造函数,但想想你拿到的指向子类的父类指针或引用,不可能调用子类的复制构造函数。

原型模式和抽象工厂模式在某些方面是竞争的,但原型模式有个好处是不需要增加新类。

享元模式

解释器模式

备忘录模式

访问者模式 

模型-视图-控制器

Model-View-Control,里面涉及的模式包括:

观察者模式:模型是被观察者,视图和控制器是观察者

策略模式:视图可以有不同的控制器

Mixin模式

多重继承

什么是Mixin模式:带实现的协议 - 走看看

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值