设计模式的理解:对23个设计模式的总结


设计模式名 ,链接可用

文档可下载:https://download.csdn.net/download/superSmart_Dong/16625368

  设计模式 意图 适用的场景 关键实现过程 优点 缺点 备注
1 模板模式 通常定义出一个稳定的骨架,特定的内容的实现延迟至子类中去实现 易变,容易根据实际需求改动的代码块,对此代码块进行延迟到子类中实现 不变的算法在基类中保留,易变的算法变成虚函数由子类实现 把不确定部分剥离开来,实现确定的部分。让将来的调用者简单实现不确定的方法就可以达到想要的效果 对调用者屏蔽了稳定的代码,使调用者虽了解使用方法但不易理解底层实现的逻辑 例如,线程:用户不需要理解与硬件的关联关系,只需要知道实现run方法就可以让程序达到高效,并行的目的
2 策略模式 定义一系列算法,把他们用一个个类封装起来,并使它们可以动态地相互替换. 业务场景无法穷举,却要根据不同的场景做出不同的操作。 根据枚举或者其他标志创建具体的派生类。用基类接收派生类,调用基类的方法。 减少了if..else的判断,把各个分支的实现变成了派生类方法的实现。避免代码臃肿,减小了需求变动、扩展的影响性 采用动态绑定会比编译时绑定性能低些,但是可以忽略 可以穷举的if...else 可以不需要用策略模式
3 观察者模式 当下层结构需要向上层结构传递信号时,不应该将上层的变量传递到下层的方式实现。因为下层结构不应该依赖于上层结构 上层结构接收来自下层结构的信号,而返回值类型又不确定时 定义一个对信号操作的接口,信号数组是下层结构中的成员。上层结构继承该接口,并将自身添加进下层结构的信号数组,从而接收下层结构的传递的信号 下层结构不直接依赖与上层结构   例如进度条展示,下层架构需要对 已下载数量占总大小的百分比传递到上层。但是进度条可以是条状的也可以菊花状的,接收信号的数据类型并不确定。所以下层将信号传进接口中,上层结构实现接口方法,操作 接口的输入参数。
4 装饰模式 动态的给对象扩展一些额外的职责 给基类添加功能后还是属于基类的范畴 定义一个功能装饰类继承基类,同时成员属性又包含基类类型。具体功能类继承装饰类,实现基类的方法,在实现过程中先实现自身的逻辑,最后再调用基类的方法。而成员基类抽象对象的赋值通过构造函数实现。 定义一个功能类,将原先的派生类传递到功能对象中,功能对象调用方法就可以达到目的。此模式可以随意组合任意的方法,摆脱了继承的滥用   例如文件流,网络流都继承流这个对象,现新增一个加密功能来加密流的读写操作。那么这个加密功能封装成类,继承于流,并流又是加密类的成员。实现加密流的读、写方法后再调用流的抽象方法。
5 桥模式 当基类从多个不同维度派生时,不同维度间的联系应该解耦 当基类需要从多个不同维度派生时 将基类的功能按照维度去拆分出不同的基类,各个基类时另外基类的成员 将基类的功能按照维度拆分后,各个维度进行了解耦。   例如,一个类中用登录功能和发送消息,播放声音和播放动画功能。当操作系统不一样时播放声音和播放动画的功能不一样,当用户VIP等级不一样时登录功能和发送消息效果不一样。那么就需要将类按照者两个维度进行拆分成两个基类,这两个基类相互是对方的成员。
6 工厂模式 利用抽象类去动态地创建对象 与策略模式配合        
7 抽象工厂模式 利用抽象类动态地创建一系列的对象 需要动态地创建一组对象时,每一组中的对象之间有紧密的联系 对类中的每个对象用工厂模式创建。将创建标志用成员变量去存,之后就直接调用函数就行 用统一的创建标志保证了一系列对象间的关联性   例如DBConnection对象和DBCommand对象,不能将SQLConnection和DBCommand创建起来。
8 原型方法 通过深拷贝克隆出一个新的对象。操作时用新对象去操作,不影响原先对象 怕指针传递和指针传递的间接改变未知代码的实参 实现抽象类的clone方法,进行深拷贝     在C++中还需需要实现深拷贝的拷贝构造函数
9 构造器模式 将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示 成员参数之间有一定的关联性,会根据情况不同初始化不同部分的成员参数。并不是所有参数都必须初始化时。 创建内部类Builder,所有成员拷贝到Builder中,把必须初始化的参数设成Builder的构造函数,可选初始化的用链式set进行初始化。最后调用build方法,build方法把自身传递近原对象的构造函数中 把复杂的对象初始化变得简单。    
10 单例模式 ①一个类只能初始化出一个对象 ②保证对象是线程安全的。 要求只能被创建一次对象的类 所有成员和成员方法设成静态,静态成员有自身的引用,私有的构造函数和拷贝构造函数,静态初始化函数需要保证线程安全。可以用返回局部静态对象的方式来保证线程安全,但是在C++11不支持 保证了结构的规范化 线程安全是一个难题  
11 享元模式 使用大量细粒度对象时,代价过高性能变低的问题 粒度大的对象的创建,并且该对象的值经常使用的情况 对粒度大的对象或者对象属性用引用的形式封装起来,用缓存的形式让对象或者对象属性减少创建次数 减小创建对象的开销 如果对象属性每次都不一样,对应的key值每次都不一样一样也会创建不少对象  
12 门面(外观)模式 避免外部程序直接调用内部方法,对内部方法进行有效的屏蔽。 对外开放的内部方法多。并且容易根据需求而改变 用一个提供些专门进行对外访问的接口,比如三层架构的BLL层      
13 代理模式 可以新增些特有的操作,而不用去修改原有对象逻辑 特例多 代理对象继承于基类且成员有基类的引用,代理类可以实现基类的方法也可以使用基类的方法还可以新增特有的方法。 隔绝了外界用户对实际对象的访问   例如:银行卡、存折等不方便让外界用户访问,但是外界用户想存取钱,可以访问支票对象。由支票对象间接的操作
14 适配器模式 为了转变接口方式的一种模式。即通过一个中介,作为两个不兼容接口之间的桥梁(老接口与新接口),使原先的老对象不仅可以使用自身的老接口,而且还可以通过适配器类,用新接口对老对象进行操作。 接口不一致 适配器类实现新接口,成员有原始类的引用。     例如电灯工作的输入是电,如果用人想要让电灯工作的输入是声音.那么定义输入声音的接口,适配器实现该接口,输入是声音,然后把声音转成电,最后再调用电灯的方法
15 中介者模式 降低多个对象和类之间的通信复杂性 类之间相互引用 实体抽象类引用中介抽象接口,实体中介引用所有实体类。实体类中调用中介方法,并传入特有的标识,实体中介类根据传进来特有的标识进行不同的处理,可以用策略模式进行搭配 减少了原先实体类之间的耦合性 实体中介类容易变得臃肿  
16 状态模式 允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类 调用自身方法来改变自身的状态,又会根据不同的状态来调用不同的方法。避免if...else显得臃肿 对原先的Context中每个状态创建一个状态类,状态接口类需要实现和Context相同的方法。状态类中的每个方法返回值都是下一个状态。Context成员有下一个状态和状态接口的引用。Context方法中就是根据下一个状态来初始化状态对象,调用状态对象中的方法并且再获得下一个状态。 避免Context类臃肿,状态类可以与单例模式进行配合    
17 备忘录模式 存储原先对象的属性,又称之为快照。方便之后回退。即游戏进度的存档和读档 需要有回退功能的类 可以用内部类的形式表现,成员是原实体中重要的属性,可以和原型模式搭配     现如今,储存/读取对象有更方便的方式。备忘录模式在如今有些过时。更有效的方式可以替代备忘录模式,例如对象序列化,对象编码等。
18 组合(整体)模式 是用于把一组相似的对象当作一个单一的对象进行统一的处理 对不同对象类型的批量处理操作 建立一个容器类,成员是实体的抽象数组。并且自身也继承于抽象类,对于容器来说操作要对抽象数组进行遍历递归调用方法,对于非容器来说,专心实现自己的方法就行。     容器相当于根节点,非容器相当于叶子节点。RadioButton,Button,GroupBox的关系一样,当GroupBox进行disable时,GroupBox包含的RadioButton,Button,GroupBox也一样要disable
19 迭代器模式 提供一种方法顺序访问一个集合对象中的各个元素,而又不需要暴露该对象的内部表示。 遍历容器又不向暴露内部 迭代器类成员包含实体的引用,可用构造函数初始化。迭代器中实现最基本的first,next,isdone,currentItem方法,实体类中getIterator(){ return MyIterator(*this);}     STL库中等其他类库有现成的
20 职责链模式 为请求创建了一个接收者对象的链 有连续传递请求的需求 通常每个接收者都包含对另一个接收者的引用。判断自身能否接收请求,如果能就处理不能它就会把相同的请求传给下一个接收者,依此类推     例如Winform的单击请求,你想触发布局在底层的控件事件时,那么就要设置上层的控件都无法处理单击请求
21 命令模式 把用户可以触发的功能当成一个命令 方法参数个数,参数的数据类型,返回值可能不统一。用户却想要统一的接口 创建用户想要的命令接口,保留原实体的成员变量和getter&setter。
把方法变成类,并继承和实现命令接口,成员包含原先的输入参数和返回值,可用构造函数初始化。
创建命令执行类,成员是 List <ICommand*> ,方法是添加ICommand 和遍历执行ICommand中的方法
方法与实体分离,可以被接收者统一处理。    
22 访问器模式 改变基类的方法会影响到派生类的实现 稳定层次结构,易变的基类方法需求 把原来基类和派生类的实现放在访问器类中,各个派生类成员包含访问器的引用,用来访问这些访问器的操作方法。而访问器中的操作方法传入派生类的实体,对派生类的属性进行操作,返回值用成员变量保存。这样要变更操作方法只需要变更具体的访问器,而不需要变更基类和派生类。   如果层次结构不稳定,那么使用访问者模式就得不偿失.  
23 解释器模式 定义一个语言,用户可以用这语言来执行相应的操作   非终结符和终结符的解析。实际的难点是先学会编译原理   解析算法才是难点 如正则表达式等

猜你喜欢

转载自blog.csdn.net/superSmart_Dong/article/details/115610908
今日推荐