赞
踩
设计模式目标 — 可复用
设计模式假设条件 — 存在稳定点
设计模式真谛 — 编译时复用,运行时变化。
思维方式 | 作用 | 内容 |
---|---|---|
底层思维 | 把握机器底层微观构造 | 语言构造、编译转换、内存模型、运行机制 |
抽象思维 | 将现实世界抽象为程序代码 | 面向对象、组件封装、设计模式、架构模式 |
向下
封装 — 隐藏内部代码
继承 — 复用已有代码
多态 — 改写对象行为
向上
软件设计复杂性根本原因 — 变化(客户需求、技术平台、开发团队、市场)
分解 — 分而治之,大问题分解为多个小问题,复杂问题分解为多个简单问题(独立实现每个小类,分别实现相应的功能)
抽象 — 由于不能掌握全部复杂对象,选择忽视一些非本质的细节。而去处理泛化和理想化的对象模型。(抽象一个虚基类,每个具体小类继承并重写)
几乎所有的设计模式都采用类内部组合一个对象指针的形式(指针指向多态对象以解耦合)
面向对象设计最大优势 — 抵御变化
依赖倒置原则(DIP)
高层模块(稳定)不应该依赖于低层模块(变化),二者均依赖于抽象(稳定)。
抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)。
开放封闭原则(OCP)
对扩展开放,对更改封闭
类模块应该是可扩展的,但不可修改。
单一职责原则(SRP)
Liskov替换原则(LSP)
接口隔离原则(ISP)
优先使用对象组合,而不是类继承
封装变化点
针对接口编程,而非针对实现。
产业强盛标志 — 接口标准化
由设计原则归纳、总结出的点
设计习语(Design Idioms) — 与特定编程语言相关的底层模式、技巧惯用法
设计模式(Design Patterns) — 类与对象之间的组织关系,包括角色、职责、协作方式
架构模式(Architectural Patterns) — 系统中与组织结构关系密切的高层模式,包括子系统划分、职责、组织关系。
23个设计模式的分类原则
目的
创建型 — 对象创建
结构型 — 对象需求变化对结构造成的冲击
行为型 — 多个类交互
范围
封装变化
Template Method、Strategy、Observer/Event
Decorator、Bridge
Factory Method、Abstract Factory、Prototype、Builder
Singleton、Flyweight
Facade、Proxy、Mediator、Adapter
Memento、State
Composite、Iterator、Chain of Resposibility
Command、Visitor
Interpreter
由于时代的发展,一些设计模式已不常用:
Builder、Mediator、Memento、Iterator、Chain of Resposibility、Command、Interpreter、Visitor
重构获得模式
是普遍认为最好的使用设计模式方法
Refactoring to Patterns
)通过晚期绑定,实现框架与应用程序之间的松耦合。实现「框架与应用程序之间的划分」
模板方法。定义一个操作中的算法的骨架(稳定),将一些步骤延迟(变化)到子类。使得子类可以不改变一个算法的结构(复用),同时重定义该算法的某些特定步骤。
软件构造过程中,对于某项任务,有稳定的整体操作结构,但各个子步骤却有很多改变的需求;或者由于固有原因而无法和任务整体结构同时实现。
模板方法能够在稳定操作的前提下,灵活应对各个子步骤的变化及晚期实现需求。
AbstractClass
— 稳定的流程ConcreteClass
— 实现时会变化的步骤Template Method
是非常常用的基础设计模式,面向对象系统中大量使用。Template Method
机制简洁(虚函数的重载),为许多应用程序架构提供了灵活扩展点,是代码复用层面的基本实现结构。Template Method
内含反向控制结构(App
调用Lib
中的方法 → \to → Lib
调用App
重写的方法)Template Method
调用的虚方法可以不做实现,但一般设计为protected
方法。(流程中的一部分,不供外界调用)基类(Lib)实现执行流程,关于具体细节部分(步骤的详情),通过相应的派生类(App)去重写。
步骤的具体功能改变,不需要重写框架中的执行流程
//库 class Library{ public: //具体执行流程(定) void Run() { Step1(); if(Step2()) { Step3(); } } virtual ~Library() { ...} protected: // 定 void Step1() { ...} void Step3() { ...} // 变 virtual bool Step2() = 0; }; //使用 class Application : public Library { protected: virtual bool Step2() { ...} }; int main() { Library* pLib = new Application(); pLib->Run(); delete pLib; }
策略模式。定义一系列算法,分别封装,并且使他们可以相互替换(变化)。该模式使得算法「独立」于使用他的客户程序(稳定)而变化。
软件构造过程中,某些对象使用的算法多种多样,经常改变。如果将算法都编码到对象中,会使得对象异常复杂且冗余。
策略模式能够在运行时根据需求透明的更改对象的算法,将算法与对象解耦合。
Context
与Strategy
— 稳定的共有算法(都需要计算某个项)ConcreteStrategy
— 具体的算法细节(计算的方式可能不同)银行支持多个国家税额的计算。具体的支持国家会根据银行的发展改变。
增加新的国家税额计算方式时(具体实现细节、客户程序),无需改变框架(算法)。
//计算策略 定 class TaxStrategy{ TaxBase tax; public: virtual double CalculateTax(...) = 0; virtual ~CalculateTax(); }; //具体国家的计算式 变 class CNTax : public TaxStrategy { virtual double CalculateTax(...) { ... } }; //订单类 需要计算的值 class SalesOrder{ private: TaxStrategy* strategy; public: //传入国家,新增 SalesOrder(...) { this->strategy = new ...; } }
Strategy
及其子类为组件提供一系列可重用算法,使得运行时方便切换。Strategy
提供了条件判断语句以外的选择,消除判断本身以解耦合。Strategy
对象不实例化,那么 各个上下文共享一个Strategy对象以节省开销。观察者模式。定义一种对象间的一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖它的对象都得到通知并自动更新。
软件构造过程中,需要为某些对象创建一种“通知依赖关系” — 一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)随之改变。若此依赖关系过于紧密,则软件不能很好的抵御变化。
观察者模式能够弱化这种依赖关系,形成稳定依赖关系、解耦合。
Subject Observer
为稳定的框架部分ConcreteObserver ConcreteSub
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。