设计模式(一)

179 阅读7分钟

设计模式概述

由来

源于建筑领域,由Christopher Alexander模式之父提出,发现人们对舒适住宅和城市环境共同认识规律。

每个模式都从前提条件(Context)、目标问题(Theme或Problem)、解决方案(Solution)三方面来阐述。

Christopher Alexander 给出定义:每个模式都描述了一个我们环境中不断出现的问题,然后描述了该问题的解决方案的核心,通过这种方式,我们可以无数次地复用已有的成功解决方案。

1990年,软件工程界开始关注其在建筑领域的突破,在1991~1992由“四人组”(GOF)引入,在1994年归纳了在开发中使用频率较高的23种设计模式,旨在用模式统一沟通面向对象方法在分析、设计和实现间的鸿沟。

设计模式是什么

软件模式基础结构:

设计模式包含模式名称、问题、目的、解决方案、效果等组成要素。

设计模式每个都为某一类可重复问题提供了一套解决方案。根据它们用户。设计模式可分为:创建型(「Creational」)、结构型(「Structual」)和行为型(「Behavioral」)。创建型包括描述如何创建对象;结构型主要用于描述如何实现类或对象的组合;行为型主要用于描述类或对象怎样交互以及怎样分配职责。

设计模式有什么用

  1. 设计模式来源于优秀经验的总结。
  2. 设计模式提供了一套通用的设计词汇和一种通用的形式来方便开发人员之间的交流。
  3. 大部分设计模式都兼顾了系统的可重用性和可扩展性。
  4. 合理使用设计模式及文档化,有助于更快理解系统。
  5. 学习设计模式将更有助于初学者深入理解面向对象思想。

类与对象及原型

对象(Object)」具有三个概念是唯一性 (identity)、状态(state)、行为(behavior)的实体。

「类(Class)」 封装了数据的状态和行为、是面向对象的重要组成部分,它是具有相同属性、操作、关系的对象集合的总称。

「原型(Prototype)」是更接近人类认知的描述对象的方法,通过「clone」来创建对象。

「面向对象设计(Object-oriented programming,OOP)」基于对象的编程范式。

「基于原型(Prototype-based programming)」 采用“相似”去描述对象,通过原型属性从其他对象去继承。有两种分支「委托(Delegation)」(JavaScript的原型是基于委托去实现的。)和「串联(Concatenation)」

「基于类(Prototype-based programming)」 有两种分支分类和归类。类可以被实例化对象(Object),对应对应具体的事物,是类的实例(Instance)。

基于类通过类的构造函数去创造一个对象,基于原型是通过复制现有对象(其原型)的行为来构造新对象的过程。 下面有两段简单的JavaScript代码看看他的区别。

基于原型


const foo = { name'foo'age20sex'male' }
const bar = { name'bar'age30 }

Object.setPrototypeOf(foo, bar)

bar.name // resolves bar
bar.sex // resolves male
const foo = { name: 'foo', age: 20, sex: 'male' }
const bar = Object.create(foo)

基于类


class Animal {
    constructor (name, age) {}
}

class Person extends Animal {
    constructor (name, age) {
        super(name, age)
    }
    say () {
        console.log('Chinese')
    }
}

UML(Unified Modeling Language)概述

UML特性

  1. UML融合了多种优秀的面向对象建模方法。
  2. UML是一种通用的可视化建模(Modeling)语言。
  3. UML是一种语言,有自己的标准表达。

UML结构

  1. 视图(View):UML视图用于不同角度来表示待建模系统。包括:用户视图、结构视图、行为视图、实现视图和环境视图。
  • 用户视图以用户的观点表示为系统的目标,它是所有视图的核心,用于描述系统需求。
  • 结构视图描述系统的静态元素以及它们之间的关系。
  • 行为视图描述系统的动态行为,描述系统组成元素在系统运行时的交互关系。
  • 实现视图表示系统逻辑元素的分布,描述系统中物理文件以及它们之间的关系。
  • 环境视图表示系统中物理元素的分布,描述系统硬件之间的关系。
  1. 图(Diageam):UML图是指描述UML视图内容的图形。
  • 用例图对应用户视图。
  • 类图、对象图、包图和组合结构图对应结构视图。
  • 状态图、活动图、顺序图、通信图、定时图和交互概览图对应行为视图。
  • 组件图对应实现视图。
  • 部署图对应环境视图。
  1. 模型元素(Model Elmment): 类、对象、消息以及这些概念之间的关系。
  2. 通用机制(General Mechanism):UML提供的通用机制为模型元素提供额外的注释、信息和语义及相对应扩展。

类图UML图示

「类图(Class Diagram)」是出现在系统中的不同类来描述系统的静态结构,主要用来描述不同类以及它们之间的关系。 UML图示 类图组成结构:

  1. 类名。
  2. 类的属性(Attributes)由可见性、名称、类型、默认值。
  3. 类的操作(operations)由可见性、名称、参数列表、返回类型。

类之间的关系

  1. 关联关系
    关联(Association)关系是类与类之间的一种结构化关系。表示一类对象与另一类对象之间有联系。
  • 单项关联
    顾客(Customer)拥有地址。 对应的TypeScript代码如下:

class Customer {
    private address: Address
}

class Address {

}
  • 双向关联
    顾客(Customer)购买商品(Product)并拥有商品,反之卖出的商品与某个顾客总有关联。 对应的TypeScript代码如下:

class Customer {
    private products: Product[]
}

class Product {
    private customer: Customer
}
  • 自关联
    一些类的属性对象类型为该类本身。 对应的TypeScript代码如下:

class Node {
  private subNode: Node
}
  • 多重性关联
    一个界面(Form)可拥有零个或者多个Button类。 对应的TypeScript代码如下:

class Form {
    private buttons: Button[]
}

class Button {

}

2. 聚合关系
聚合(Aggregation)关系表示整体与部分的关系。在聚合关系中,成员对象是整体对象的一部分,但是成员对象可以脱离整理对象独立存在。
汽车发动机(Engine)是汽车(Car)的组成部分。 对应的TypeScript代码如下:


class Car {
    private engine: Engine

    // 构造注入
    constructor(engine: Engine) {
        this.engine = engine
    }

    // 设值注入
    public set SetEngine(engine: Engine) {
        this.engine = engine
    }
}

class Engine {}

3. 组合关系
组合(Composition)关系也表示类之间整体和部分的关系,但是组合关系可以控制成员对象的生命周期。
人的头(Head)和嘴巴(Mouth)。 对应的TypeScript代码如下:


class Head {
    private mouth: Mouth
    constructor() {
        this.mouth = new Mouth()
    }
}

class Mouth {}

4. 依赖关系
依赖(Dependency)是一种使用关系,表示一个事物使用另一个事物的方法。
驾驶员开车。Driver类中dirve()调用Car类中move()。 对应的TypeScript代码如下:


class Driver {
    public driver(car: Car) {
        car.move()
    }
}
class Car {
    public move() {
    }
}

5. 泛化关系
泛化(Dependency)是继承关系,描述父类和子类的关系。
Student类和Teacher类继承了Person类的属性方法,另外Student类增加了属性学号(studentNo)与方法study(),Teacher类新增了属性教师编号(teacherNo)与方法teach()。 对应的TypeScript代码如下:


class Person {
    protected name: string
    protected age: bigint

    public move(): void {}
    public say(): void {}
}

class Teacher extends Person {
    private teacherNo: bigint

    public teach(): void {}
}

class Student extends Person {
    private studentNo: bigint

    public study(): void {}
}

6. 接口与实现关系
接口与类之间存在一种实现(Realization)关系。
对应的TypeScript代码如下:


interface Vehicle {
    move(): void
}

class Ship implements Vehicle {
    public move(): void {}
}

class Car implements Vehicle {
    public move(): void {}
}

参考

  1. <设计模式的艺术>。PS:本文所有UML图都来自于这本书。
  2. wikipediaPrototype-based programmingClass-based programmingObject-oriented programming三文。