软件设计模式总结 01

什么是设计模式

设计模式是一套被反复使用、多数人知晓、经过分类编目的代码设计经验的总结。使用设计模式是为了重用代码,让代码更容易被他人理解,保证代码可靠性。

基本要素

  • 模式名称(Pattern Name)

  • 问题(Problem)

  • 解决方案(Solution)

  • 效果(Consequences)

分类

  • 目的

    • 创建型模式
    • 结构型模式
    • 行为型模式
  • 作用范围

    • 类模式
    • 对象模式

OOP 设计原则

  1. Single Responsibility Principle 单一职责原则

  2. Open Closed Principle 开闭原则

  3. Liskov Substitution Principle 里氏替换原则

  4. Interface Segregation Principle 接口隔离原则

  5. Dependency Inversion Principle 依赖倒置原则

  6. Composite Reuse Principle 合成复用原则

  7. Law of Demeter 迪米特法则

参考:

  • SOLID - wikipedia

  • 设计原则 - 极客教程

认识 ClassDiagram

参考链接:

  • 中文

  • 英文

要素:

  • 标题

  • 符号

  • 连线

  • 箭头

  • 注释

---
title: Animal example
---
classDiagram
    note "From Duck till Zebra"
    Animal <|-- Duck
    note for Duck "can fly\ncan swim\ncan dive\ncan help in debugging"
    Animal <|-- Fish
    Animal <|-- Zebra
    Animal : +int age
    Animal : +String gender
    Animal: +isMammal()
    Animal: +mate()
    class Duck{
        +String beakColor
        +swim()
        +quack()
    }
    class Fish{
        -int sizeInFeet
        -canEat()
    }
    class Zebra{
        +bool is_wild
        +run()
    }

类、接口、抽象类

classDiagram
    class NormalClass1{
        +int age
        +String
        +isMammal() boolean
        +mate() void
    }
    class interface1{
        <<interface>>
        +int age
        +String
        +isMammal() boolean
        +mate() void
    }
    class abstract1{
        <<abstract>>
        +int age
        +String
        +isMammal() boolean
        +mate() void
    }

在一些图中,接口会显示为一个 -o 的标记,不是直接显示 <<interface>>

符号

1
2
3
4
+ Public // 公共
- Private // 私有
# Protected // 保护
~ Package/Internal // 包内

连线

classDiagram
    class A
    class B
    A -- B

    class C
    class D
    C .. D

连线可以使用 --..,前者表示实线,后者表示虚线。代表不同的关系。

箭头

classDiagram
    class A
    class B
    A --> B

    class C
    class D
    C --o D

    class E
    class F
    E --|> F

    class G
    class H
    G --* H

箭头有多种类型,代表不同的关系。配合不同的连线,代表不同的关系,目前有 8 种不同的关系。

符号含义中文
<|–Inheritance继承
*–Composition组合
o–Aggregation聚合
–>Association关联
Link (Solid)链接(实线)
…>Dependency依赖
…|>Realization实现
Link (Dashed)链接(虚线)
classDiagram
classA <|-- classB : Inheritance继承
classC *-- classD : Composition组合
classE o-- classF : Aggregation聚合
classG <-- classH : Association关联
classDiagram
classI -- classJ : Link实线
classK <.. classL : Dependency依赖
classM <|.. classN : Realization实现
classO .. classP : Link虚线

一条带有箭头的线表示两个类之间的关系,一条连线可以有2个箭头,分别指向不同的类。

简单工厂模式

classDiagram
    class chart {
        <<interface>>
        +display() void
    }
    class HistogramChart {
        +HistogramChart()
        +display() void
    }
    class PieChart {
        +PieChart()
        +display() void
    }
    class LineChart {
        +LineChart()
        +display() void
    }
    class ChartFactory {
        +getChart(String type) chart
    }

    chart <|.. HistogramChart
    chart <|.. PieChart
    chart <|.. LineChart
    ChartFactory ..> HistogramChart : create
    ChartFactory ..> PieChart : create
    ChartFactory ..> LineChart : create

简单工厂模式:一个工厂类根据传入的参数决定创建哪一种产品类的实例。

结构

  • 工厂

  • 抽象产品

  • 具体产品

工厂方法模式

classDiagram
    class Client
    class Factory {
        <<interface>>
        +create() Product
    }
    class ConcreteFactoryA {
        +create() Product
    }
    class ConcreteFactoryB {
        +create() Product
    }
    class Product {
        <<interface>>
        +display() void
    }
    class ConcreteProductA {
        +display() void
    }
    class ConcreteProductB {
        +display() void
    }

    Factory <|.. ConcreteFactoryA
    Factory <|.. ConcreteFactoryB
    Product <|.. ConcreteProductA
    Product <|.. ConcreteProductB
    ConcreteProductA <.. ConcreteFactoryA : create
    ConcreteProductB <.. ConcreteFactoryB : create
    Client --> Factory : factory
    Client --> Product : product

工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

结构

  • 抽象工厂

  • 具体工厂

  • 抽象产品

  • 具体产品

反射与配置文件

  • 反射:在运行状态中,动态获取类的信息并创建对象。

  • 配置文件:将参数放置在配置文件中,用户通过输入数字来决定选择哪个具体的工厂对象。

工厂方法的重载与隐藏

  • 重载:在一个类中定义多个同名方法,参数列表不同。

  • 隐藏:在工厂中直接调用产品类业务方法,客户端无需调用工厂方法创建产品对象。

抽象工厂模式

classDiagram
    class Client
    class SkinFactory {
        <<interface>>
        +createButton() Button
        +createTextField() TextField
    }

    class SpringSkinFactory {
        +createButton() : Button
        +createTextField() TextField
    }

    class SummerSkinFactory {
        +createButton() : Button
        +createTextField() TextField
    }

    class Button {
        <<interface>>
        +display() void
    }

    class SpringButton {
        +display() void
    }

    class SummerButton {
        +display() void
    }

    class TextField {
        <<interface>>
        +display() void
    }

    class SpringTextField {
        +display() void
    }

    class SummerTextField {
        +display() void
    }

    SkinFactory <|.. SpringSkinFactory
    SkinFactory <|.. SummerSkinFactory
    Button <|.. SpringButton
    Button <|.. SummerButton
    TextField <|.. SpringTextField
    TextField <|.. SummerTextField

    SpringButton <.. SpringSkinFactory : create
    SpringTextField <.. SpringSkinFactory : create
    SummerButton <.. SummerSkinFactory : create
    SummerTextField <.. SummerSkinFactory : create

    Client ..> SkinFactory : factory
    Client ..> Button
    Client ..> TextField

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

结构

  • 抽象工厂

  • 具体工厂

  • 抽象产品

  • 具体产品

开闭原则的倾斜性

  • 开闭原则:对扩展开放,对修改关闭。

  • 倾斜性:抽象工厂模式在增加新产品时,需要修改抽象工厂接口和所有具体工厂类。

建造者模式

classDiagram
    class Actor {
        +type : String
        +gender : String
        +face : String
        +costume : String
        +hairstyle : String
        +setType(String type) void
        +setGender(String gender) void
        +setFace(String face) void
        +setCostume(String costume) void
        +setHairstyle(String hairstyle) void
        +getType() String
        +getGender() String
        +getFace() String
        +getCostume() String
        +getHairstyle() String
    }
    class ActorBuilder {
        <<abstract>>
        #actor : Actor
        +buildType() void
        +buildGender() void
        +buildFace() void
        +buildCostume() void
        +buildHairstyle() void
        +createActor() Actor
    }
    class HeroBuilder {
        +buildType() void
        +buildGender() void
        +buildFace() void
        +buildCostume() void
        +buildHairstyle() void
    }
    class AngelBuilder {
        +buildType() void
        +buildGender() void
        +buildFace() void
        +buildCostume() void
        +buildHairstyle() void
    }
    class ActorController {
        +construct(ActorBuilder ab) Actor
    }

    Actor <--* ActorBuilder
    ActorBuilder <|-- HeroBuilder
    ActorBuilder <|-- AngelBuilder
    ActorController ..> ActorBuilder : builder

建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

结构

  • 抽象建造者

  • 具体建造者

  • 产品

  • 指挥者

Hook方法

  • Hook方法:在抽象建造者中定义一个或多个方法,让子类实现。

原型模式

classDiagram
    class Cloneable {
        <<interface>>
    }
    class Object {
        +clone() Object
    }
    class ConcretePrototype {
        +clone() Object
    }
    class Client {
        +operation(Prototype prototype) void
    }

    Object <|-- ConcretePrototype
    Cloneable <|.. ConcretePrototype
    Client <--o ConcretePrototype : prototype

原型模式:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。

结构

  • 抽象原型

  • 具体原型

  • 客户端

序列化与反序列化

  • 序列化:将对象转换为字节序列。

  • 反序列化:将字节序列转换为对象。