累成一条狗

设计模式入门

一、设计模式

1、什么是设计模式

  设计模式是一套被反复使用、多数人知晓、代码设计经验的总结。

2、目的

  设计模式的目的是为了让软件具有更好的代码重用性、可读性、可扩展性、可靠性,同时使程序间出现高内聚、低耦合的特性。

3、六大原则

(1)六大原则

【七大原则:】
    单一职责原则(Single-Responsibilitiy Principle,简写为 SRP)
    接口隔离原则(Interface Segregation Principle,简写为 ISP)
    依赖倒置原则(Dependence Inversion Principle,简写为 DIP)
    里氏替换原则(Liskov Substitution Principle,简写为 LSP)
    开闭原则(Open-Close Principle,简写为 OCP)
    迪米特法则(Law of Demeter,简写为 LOD)
注:
    有时提到的七大原则,包括 合成复用原则(Composite Reuse Principle,简写为 CRP)

 

(2)单一职责原则

【单一职责原则:】
定义:
    Single-Responsibilitiy Principle,简写为 SRP。
    There should nerver be more then one reason for a class to change.
    直译:类改变的理由不超过一个。
简单理解:
    对于一个类,只负责某项职责(功能),并不是指一个类只有一个方法。
    若一个类职责过多,等同于将多个功能耦合在一起(耦合度高)。此原则可以对类进行解耦。
实际工作中:
    应保证 接口符合单一职责,类尽量符合单一职责。
举例:
    某个人,其兼职了几个不同的工作,按照单一职责原则,每个工作应该都由一个专门的人来完成。

 

(3)里氏替换原则

【里氏替换原则:】
定义:
    Liskov Substitution Principle,简写为 LSP。
    Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it。
    直译:引用基类的地方必须能透明的(在使用者不知道的情况下)使用其派生类的对象。
简单理解:
    多态,子类可拓展父类,但是不能改变父类原有的功能。
    任何父类能出现的地方,子类一定能出现,且子类可以扩展父类的功能,但是不能改变父类原有的功能。
实际工作中:
    可以重写父类的方法,但是尽量避免重载父类的方法(实际调用中,可能会跳过父类的方法或子类重写的方法,直接运行子类的重载方法)。
举例:
  一个父类 A,一个子类 B,子类 B 重写了父类 A 的某个方法 D1,
    在一个类 C 中需要使用父类 A 的方法时,若此时传入的是子类 B,仍能正常工作。

 

(4)依赖倒置原则

【依赖倒置原则:】
定义:
    Dependence Inversion Principle,简写为 DIP。
    High level modules should not depend upon low level modules.Both should depend upon abstractions.Abstractions should not depend upon details.Details should depend upon abstractions.
    直译:高层模块不应该依赖于低层模块,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。
简单理解:   
    依赖倒置原则的中心思想是面向接口编程。
其中:
    抽象指的是 接口 或者 抽象类, 细节指的是 具体的实现类。
实际工作中:
    每个类尽量都有 接口 或者 抽象类。
    声明类时使用 接口或者抽象类(表面类型为抽象,实际类型为 细节)。
    可与 里氏替换原则 结合使用(接口多态)。
举例:
    以医院检查为例,如下代码所示。
class Teacher{
}
class Hospital{
    // 高层依赖于低层
    public void check(Teacher teacher){ // 采用具体的实现类,只能传入Teacher类的实例
    }
}
// 若医院想检查其他人,比如:医生。可以对代码进行如下修改。
interface Person{
}
class Teacher implements Person{
}
class Doctor implements Person{
}
class Hospital{
    // 高层不依赖于低层,而依赖于抽象
    public void check(Person person){ // 采用接口,方便复用,可以传入Teacher类或Doctor类的实例
    }
}
// 此时 check() 方法传入的是 Person 接口(抽象),此时医院若想检查其他人,只需要让其实现 Person 即可。
// 即 高层、底层均依赖于抽象。

 

(5)接口隔离原则

【接口隔离原则:】
定义:
    Interface Segregation Principle,简写为 ISP。
    Clients should not be forced to depend upon interfaces that they don’t use.The dependency of one class to another one should depend on the smallest possible interface.
    直译:不应该强制客户端依赖它们不使用的接口。一个类对另一个类的依赖应该依赖于尽可能小的接口。
简单理解:
    类间的依赖关系需建立在最小的接口上。
    使用多个单一功能的接口组合的方式 比 使用一个多功能接口 耦合度低。此原则可以对接口进行解耦。
实际工作中:
    尽量在不违反单一职责原则的情况下,保证接口粒度尽量小。
举例:
    一个接口里面有 10 个抽象方法,当类 A 需要使用某个方法时,需要实现该接口,并重写 10 个方法。
    此时其余的 9 个方法,类 A 其实并不需要,按照接口隔离原则,可以将这个方法单独的抽出来写成一个接口 B,然后让类 A 去实现接口 B,此时类 A 只需重写一个方法即可。 

 

(6)迪米特法则

【迪米特法则:】
定义:
    Law of Demeter,简写为 LOD。
    又称为最少知识原则(Least Knowledge Principle,简写为 LKP)。
    Only talk to your immedate friends。
    直译:只和你的直接朋友交谈。
简单理解:
    一个对象应该对其他对象有最少的了解,即不管你内部有多复杂,我能调用你的方法就行。
  一个实体应尽量少的与其他实体之间发生相互作用(降低耦合),使系统功能模块相互独立。
实际工作中:
    某个类对外尽量不要暴露太多的 public 方法,使用 privateprotected 等修饰。 
    与其他类无关的操作,不要在其他类中进行实现。
举例:
    一个类 A 的某个方法中出现某个类 B,且对类 B 做了一些无关类 A 的操作,
    按照迪米特法则,需要将这些操作封装在类 B 的一个方法中,然后在类 A 中调用该方法。

 

(7)开闭原则

【开闭原则:】
定义:
    Open-Close Principle,简写为 OCP。
    Software entities like classes, modules and functions should be open for extension but closed for modifications.
    直译:类、模块和函数等软件实体应该对扩展开放,对修改关闭。
简单理解:
    抽象架构、拓展实现。
    软件功能发生变化时,应该通过拓展去实现,而非通过修改原有代码去实现(尽量少改动原有代码)。
    使用抽象类与接口对代码进行重构,当扩展代码功能时,实现抽象类或接口并实现相关方法即可。

 

(8)合成复用原则

【合成复用原则:】
    简单理解为 尽量避免使用 继承(耦合度高),将其改为 组合、聚合的方式。

 

4、常用设计模式分类(23种)

(1)三大类:

  创建型模式(五种),

  结构型模式(七种),

  行为型模式(十一种)
(2)创建型模式:(强调对象创建时,如何去更好的设计)
  工厂模式,抽象工厂模式,单例模式,建造者模式,原型模式。

(3)结构型模式:(设计更好的软件结构)
  适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模式,享元模式。

(4)行为型模式:(设计更好的方法调用模式)
  策略模式,模板方法模式,观察者模式,迭代器模式,责任链(职责链)模式,命令模式,备忘录模式,状态模式,访问者模式,中介者模式,解释器模式。

 

二、UML图

1、什么是UML图

(1) Unified Modeling Language,统一建模语言,用来对软件密集系统进行可视化建模的一种语言。简单的说就是 帮助软件开发人员记录、交流的一个图形化语言。
(2)UML图本身是一组符号的规定,用于描述软件模型间各元素以及各元素间的联系。

2、UML分类

(1)用例图
(2)静态结构图:类图,对象图,包图,组件图,部署图。
(3)动态行为图:交互图(时序图、协作图)、状态图、活动图。

3、类图(常用)

【类图:】
    类图 用于描述程序中 类、接口 之间的关系。

【元素:】
    类、接口

【关系:】
依赖:
    若在某个类 A 中使用到类 B,且若没有类 B,类 A 编译会报错,则称 A 与 B 之间有依赖关系。
  线条表示:虚线普通箭头("<",">")
  
继承(泛化):
    属于依赖关系的一种特例,如果类 A 继承(extends)了类 B,则称 A 与 B 间存在泛化关系。
    线条表示:实线空心三角箭头。

实现:
    属于依赖关系的一种特例,如果类 A 实现(implements)了类 B,则称 A 与 B 间存在实现关系。
    线条表示:虚线空心三角箭头。
    
关联:
    属于依赖关系的一种特例,如果类 A 与类 B 间有联系。比如类 B 作为类 A 的成员变量,则称 A 与 B 间存在关联关系。
  线条表示:实线(直线),普通箭头("<",">")可选。如果强调方向,则加一个普通箭头。否则只需要一条实线。
  
聚合:
    属于关联关系的一种特例,如果类 A 与类 B 间可以分离且可以独立存在,则称 A 与 B 间存在聚合关系。比如:人与衣服,可以分离,则为聚合关系。
  线条表示:实线空心菱形箭头。
  
组合:
    属于关联关系的一种特例,如果类 A 与类 B 间不可以分离,则称 A 与 B 间存在组合关系。比如:人与人头,不可分离,则为组合关系。
  线条表示:实线实心菱形箭头。

 

 

   在线编辑UML图的工具(ProcessOn):https://www.processon.com/

 

posted on 2019-08-01 19:42  累成一条狗  阅读(416)  评论(0编辑  收藏  举报

导航