Python微信订餐小程序课程视频
https://edu.csdn.net/course/detail/36074
Python实战量化交易理财系统
https://edu.csdn.net/course/detail/35475
前置条件
基础知识
学习设计模式之前我们需要具备一些基础知识,首先需要熟悉面向对象软件开发经历的三个阶段,即OOA(面向对象分析)、OOD(面向对象设计)、OOP(面向对象编程)。
- OOP中有两个最基础概念是类和对象,还有封装、继承、多态、抽象四大面向对象编程的特性。
- OOAD里需要会掌握使用UML(统一建模语言,简单、统一、图形化表达软件设计中动态和静态信息)常用的图如用例图、类图、状态图、活动图、时序图、构建图、部署图,UML是我们用来描述面向对象或设计模式的设计思路。
UML2.0
UML2.0包括以下14类图,本篇只是提出但不详细学习这些图,需要各自掌握类、接口、类图,并能运用自如画图,后续我们有时间再专门针对UML详细展开。
类图表示方法
- 类使用包含类名、属性和方法且带有分割线的矩阵来表示,如下图Employee类,它包含name,age和adress这三个属性,以及work()方法
- 属性/方法名称前加的加号和减号表示了这个属性/方法的可见性,UML类图中表示可见符号有三种:
- +:表示public
- -:表示private
- #:表示protected
- 属性的完整表示方式是:
- 可见性 名称 : 类型 [ = 缺省值 ]
- 方法的完整表示方式是:
- 可见性 名称(参数列表) [ : 返回类型],注意:
- 中括号中的内容表示可选
- 也有将类型放在变量名后面,返回类型放在方法名前面
类与类之间关系
在软件设计中类与类之间关系包括泛化、 实现、组合 、 聚合 、 关联 、 依赖 。
-
泛化、实现依赖关系强度相同,这两种关系也是依赖最强的系;泛化体现的是类与类的纵向关系,是父类与子类的继承关系,是is-a关系,采用实线+空心三角箭头;实现体现的是类与接口的纵向关系,实现采用虚线+空心三角箭头。
-
其他四种关系体现的是类和类、或者类与接口的横向关系,较难区分,强弱程度依次为:组合>聚合>关联>依赖,依赖的关系程度最强。
- 依赖关系是一种使用的关系,也是一种临时性关系,通常在代码层面体现为某个类通过局部变量、方法的参数、静态方法来调用访问另一个类(被依赖的类)中某些方法;采用带箭头虚线,箭头指向被依赖的类。
- 关联关系是对象之间的一种引用关系,是类与类之间最常用的一种关系;分为一般关联、组合、聚合关系;在代码中通常将一个类的对象作为另外一个类的成员变量(全局变量)来实现。
- 一般关联:也即是通常说的关联关系,可以单向的,也可以双向的;双向关联采用两个箭头或者没有箭头的实线,单向关联采用带一个箭头的实线,箭头从使用类指向被关联的类。
- 聚合:关联关系中的一种,整体和部分关系,也即是has-a关系,部分可以脱离整体单独存在。采用带空心菱形的实线,菱形指向整体。
- 组合:也是关联关系中的一种,整体和部分关系,也即是contains-a关系是一种更强烈的聚合关系,部分不能脱离整体单独存在。采用带实心菱形的实线,菱形指向整体。下面通过一张图涵盖上面6种类之间的关系的运用示例并加深理解。
七大设计原则
总体原则
软件设计有七大设计原则,分别是开闭原则、单一职责原则、接口隔离原则、里氏替换原则、依赖倒置原则、合成复用原则、迪米特法则,设计原则作为设计模式的指导思想,而设计模式则是基于设计原则实践发展沉淀的经验,目的是为了提高程序可靠性、可维护性、可复用性、可扩展性,实现面向对象编程的解耦,类与类做到低耦合高内聚;软件编程过程需综合考虑并尽量遵守这些设计原则。引用一句口诀:访问加限制、函数要节俭、依赖不允许、动态加接口、父类要抽象、扩展不更改。
开闭原则
定义
开闭原则(Open-Closed Principle,OCP)是规范我们程序员编程最基本、最重要的原则,强调对扩展开放、对修改关闭,即软件实体应尽量在不修改原有代码的情况下进行扩展。开闭原则是其他设计原则的总纲,是面向对象的可复用设计的首要基石,其他设计原则本质是围绕开闭原则在不同角度去展开。
例子
下面举一个违反开闭原则的例子:支持显示各种类型的图表,如饼状图和柱状图等,类图设计如下:
在ChartDisplay类的display()方法中有如下if else if的处理逻辑代码
if (type.equals("pie")) {
PieChart chart = new PieChart();
chart.display();
}
else if (type.equals("bar")) {
BarChart chart = new BarChart();
chart.display();
在上面ChartDisplay类代码中如果需要增加一个新的图表类如折线图LineChart,则需要修改ChartDisplay类的display()方法的源代码,增加新的判断逻辑,这样就违反了开闭原则;比如可采用策略模式的设计模式来解决上面这种违反开闭原则会变化if else的问题。
单一职责原则
概述
- 单一职责(Single Responsibility Principle,SRP),一个类只有一个引起它变化的原因。
- 主要是控制类的粒度大小实现高内聚和低耦合,它是最简单但又是最难运用的原则,单一职责是指如何定义一个模块、类、方法和实现其封装,可以说是比较依赖经验。
- 我们要根据需求和实际情况来灵活运用单一职责原则,需要设计人员有较强的面向对象业务分析能力和丰富实践经验进行职责分离,将不同变化原因的职责封装到不同的类中。
- 一个类不要太累,如果类承担职责过多则复用的可能性就越小,且多职责耦合一起当其中一个或几个职责发生变化可能影响其它职责的运行。
- 在实际过程中如果生搬硬套会引起类的增多,添加额外的维护成本,其实是很难全面做到类级别单一职责原则,如果代码的逻辑足够简单时,我们可以在代码级别违反单一职责原则,当类中的方法数量少,并且业务逻辑不是特别复杂时,可以降级到方法级别单一原则。
反例
吃类Eat.java,如果后续增加吃的方式那么就需要在Eat类修改,这样就有可能影响了原有功能,违反开闭原则。
package cn.itxs.principle.srp;
public class Eat {
public void doEat(String animal){
if ("狮子".equals(animal)){
System.out.println(animal+"在大口吃肉!");
}else if ("黄牛".equals(animal)) {
System.out.println(animal+"在细嚼慢咽吃草!");
}
}
}
测试类SrpMain.java
package cn.itxs.principle.srp;
public class SrpMain {
public static void main(String[] args) {
Eat animal = new Eat();
animal.doEat("狮子");
animal.doEat("黄牛");
}
}
正例
- 类级别
吃肉类EatMeet.java
package cn.itxs.principle.srp;
public class EatMeet {
public void doEat(String animal){
System.out.println(animal+"在大口吃肉!");
}
}
吃草类EatGrass.java
package cn.itxs.principle.srp;
public class EatGrass {
public void doEat(String animal){
System.out.println(animal+"在细嚼慢咽吃草!");
}
}