开闭原则

对扩展开放,对修改关闭 类模块应该是可扩展的,但是不可修改源代码 如下所示,如果想要扩展乘法、除法、取模等算法,就不用修改原码,只需增加新类 class AbstractCalculator{ public: virtual void setOperatorNum(int a, int b) = 0; virtual int getResult() = 0; }; class PlusCalculator:public AbstractCalculator{ public: void setOperatorNum(int a, int b)override{ m_a = a; m_b = b; } int getResult()override{ return m_a + m_b; } private: int m_a{0}; int m_b{0}; }; class MinusCalculator:public AbstractCalculator{ public: void setOperatorNum(int a, int b)override{ m_a = a; m_b = b; } int getResult()override{ return m_a - m_b; } private: int m_a{0}; int m_b{0}; }; int main() { AbstractCalculator* calculator = new PlusCalculator; calculator->setOperatorNum(10, 20); cout << calculator->getResult() << endl; delete calculator; calculator = nullptr; calculator = new MinusCalculator; calculator->setOperatorNum(10, 20); cout << calculator->getResult() << endl; delete calculator; calculator = nullptr; return 0; }

January 30, 2022 · 1 min · Rick Cui

面向对象设计原则

原则目的:高内聚,低耦合,隔离变化 依赖倒置原则 Dependence Inversion Principal(DIP) 依赖于抽象(接口),不要依赖具体的实现(类) 针对接口编程 开闭原则 Open-Closed Principal(OCP) 对扩展开放,对修改关闭 类的改动是通过增加代码进行的,而不是修改源代码 单一职责原则 Single Responsibility Principal(SRP) 类的职责单一,对外只提供一种功能 一个类应该仅有一个引起它变化的原因 变化的方向隐含着类的责任 里氏代换原则 Liskov Substitution Principal(LSP) 任何抽象类出现的地方都可以用他的实现类进行替换(多态) 子类必须能够替换它们的基类(IS-A) 继承表达类型抽象。 接口隔离原则 Interface Segregation Principal(ISP) 不应该强迫客户程序依赖他们不用的方法 接口应该小而完备 一个接口应该只提供一种对外功能,不应该把所有操作都封装到一个接口中去 合成复用原则 Composite Reuse Principal(CRP) 对于继承和组合,优先使用组合 类继承通常为 白箱复用,对象组合通常为 黑箱复用 继承在某种程度上破坏了封装性,子类父类耦合度高 而对象组合则只要求被组合的对象具有良好定义的接口,耦合度高 迪米特法则 Law of Demeter(LoD) 一个对象应当对其他对象尽可能少的了解(最小接口原则),从而降低各个对象之间的耦合。例如在一个程序中,各个模块之间相互调用时,通常会提供一个统一的接口来实现。这样其他模块不需要了解另外一个模块的内部实现细节(黑盒原理) 封装变化点,使用封装来创建对象之间的分界层,让设计者可以在分界层的一侧进行修改,而不会对另一侧产生不良的影响,从而实现层次间的松耦合 针对接口编程,而不是针对实现编程 不将变量类型声明为某个特定的具体类,而是声明为某个接口 客户程序无需获知对象的具体类型,只需要知道对象所具有的接口 减少系统中各部分的依赖关系,从而实现 高内聚、松耦合 的类型设计方案

January 30, 2022 · 1 min · Rick Cui

设计模式

设计模式 一、概念 设计模式是在特定环境下人们解决某类重复出现的问题的一套成功或有效的解决方案。 软件模式并非仅限于设计模式,还包括架构模式、分析模式、过程模式等。 在一定环境下,用固定套路解决问题。 设计模式的基础是多态。 二、目的 学习设计模式有助于更加深入的理解面向对象思想 如何将代码分散在几个不同的类中 为什么要有接口 何谓针对抽象编程 何时不应该使用继承 如何不修改源代码增加新功能 更好地阅读和理解现有类库与其它系统中的源代码 三、软件设计模式种类 GoF 提出的设计模式有 23 种,加简单工厂模式,一共 24 种 1、创建型模式 Creational 6种 如何创建对象 单例模式 简单工厂模式 工厂方法模式 抽象工厂模式 原型模式 建造者模式 2、结构型模式 Structural 7种 如何实现类或对象的组合 让类和类进行组合,获得更大的结构 适配器模式 桥接模式 组合模式 装饰模式 外观模式 享元模式 代理模式 3、行为型模式 Behavioral 11种 类或对象怎样交互以及怎样分配职责 职责链模式 命令模式 解释器模式 迭代器模式 中介模式 备忘录模式 观察者模式 状态模式 策略模式 模板方法模式 访问者模式

January 30, 2022 · 1 min · Rick Cui

UML 统一建模语言

一、用例图 用例代表系统的某项完整功能 从客户角度来描述系统功能 包括参与者、用例、关系 1. 泛化关系 Generalization 父类和子类的关系 2. 包含关系 Include 一个功能肯定会使用另一个功能 3. 扩展关系 Extend 完成某个功能的时候偶尔会执行另一个功能 二、类图 用来显示系统中的类,接口以及它们之间的关系 1. 泛化关系 Generalization(is a) 一种类与类之间的继承关系 2. 实现关系 Realization(is a) 类与抽象类之间的实现关系 3. 依赖关系 Dependence(use a) 两个相对独立的系统,一个系统负责构造另一个系统的实例,或者依赖另一个系统的服务 类 A 做为类 B 方法的形参,而不是类 B 的成员属性 4. 关联关系 Directed Association 两个相对独立的系统,一个系统的实例与另一个系统的一些实例存在固定的对应关系 聚合 Aggregation 聚合关系是关联关系的一种,是更强的关联关系 聚合是整体和部分之间的关系,例如汽车由引擎、轮胎以及其它零件组成 聚合关系也是通过成员变量来实现的,但是,关联关系所涉及的两个类处在同一个层次上,而聚合关系中,两个类处于不同层次上,一个代表整体,一个代表部分 整体与部分之间是可分离的,它们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享 组合 Composition 三、对象图 四、时序图 五、活动图

January 29, 2022 · 1 min · Rick Cui

面向抽象类编程

三层架构:业务逻辑层、抽象层、实现层 原则:依赖倒转 案例一:动物园 设计实现: 抽象层:Animal 提供接口 voice 实现层:Dog、Cat 分别实现 voice ,发出不同的声音 业务层:main 函数调用,只通过 Animal 的指针统一实现业务 案例二:编写一个 C++ 程序, 计算程序员( programmer )工资 要求能计算出初级程序员( junior_programmer ) 中级程序员 ( mid_programmer )高级程序员( adv_programmer )的工资 要求利用抽象类统一界面,方便程序的扩展,比如:新增,计算架构师( architect ) 的工资 设计实现: 抽象层:Programmer 提供计算工资的接口 实现层:JuniorProgrammer、MidProgrammer、AdvProgrammer 分别对计算工资接口进行实现 业务层:通过 Programmer 类统一管理,实现业务逻辑,同时业务的可扩展性更强,如新增架构师类型 案例三:电脑组装,面向抽象层编程 组装电脑有 3 个抽象类,抽象的 cpu,抽象的显卡,抽象的内存。 现在要求组装两台电脑,一台是 Intel 的 CPU,Intel 的显卡和 Intel 的内存。另一台是 Intel 的 CPU、Nvidia 的显卡和 Kingston 的内存条。 针对抽象层编程。 设计实现:...

January 9, 2022 · 1 min · Rick Cui