# docker

# linux docker
# https://github.com/docker/docker-install

make shellcheck
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh

# docker 加速
# https://developer.aliyun.com/article/1131834

# docker manager
potainer & lazydocker

# 编程范式

OOP:

Object Oriented Programming 对象式编程

知识点树形图-入门
面向对象编程 (OOP) - 入门知识点
│
├── 类与对象
│   ├── 定义类 (class)
│   ├── 创建对象 (new Class())
│   ├── 构造函数 (constructor)
│   ├── 实例属性与方法
│   ├── 静态属性与方法 (static)
│   └── this 关键字的指向
│
├── 属性类型
│   ├── 实例属性(每个对象独立)
│   ├── 静态属性(类级别共享)
│   └── 私有属性约定(_prop 命名)
│
├── 封装 (Encapsulation)
│   ├── 数据隐藏(通过 _ 表示私有)
│   ├── Getter / Setter 方法
│   ├── 控制属性访问权限
│   └── 示例:密码保护、余额封装
│
└── 基础方法
    ├── 实例方法定义与调用
    └── 静态方法的使用场景
知识点树形图-高阶
面向对象编程 (OOP) - 高阶知识点
│
├── 继承 (Inheritance)
│   ├── 子类 extends 父类
│   ├── super 关键字
│   │   ├── 调用父类构造函数 (super())
│   │   └── 调用父类方法 (super.methodName())
│   └── 方法重写(Override)
│
├── 多态 (Polymorphism)
│   ├── 同一接口不同实现
│   ├── 子类重写父类方法
│   ├── 运行时决定调用哪个方法
│   └── 示例:Animal、Dog、Cat 的 speak 方法
│
├── 抽象 (Abstraction)
│   ├── 隐藏复杂实现细节
│   ├── 只暴露必要接口
│   └── 用户无需了解内部逻辑
│
├── 对象关系
│   ├── 关联(Association)
│   ├── 聚合(Aggregation)
│   └── 组合(Composition)
│
├── 设计原则(SOLID)
│   ├── 单一职责原则 (SRP)
│   ├── 开闭原则 (OCP)
│   ├── 里氏替换原则 (LSP)
│   ├── 接口隔离原则 (ISP)
│   └── 依赖倒置原则 (DIP)
│
├── 设计模式(常见)
│   ├── 工厂模式
│   ├── 单例模式
│   ├── 策略模式
│   └── 观察者模式(部分 OOP 实现)
│
└── 高级特性(ES6+ / TypeScript)
    ├── 混入(Mixins)
    ├── 装饰器(Decorators)
    ├── 代理(Proxy)
    ├── 反射(Reflection)
    ├── 接口(Interfaces)— TypeScript
    └── 抽象类(Abstract Classes)— TypeScript
class User {
  // 静态属性
  static userCount = 0

  constructor(name, email, password) {
    // 实例属性
    this.name = name
    this.email = email
    this._password = '' // 使用 _ 表示私有属性

    // 初始化
    this.setPassword(password)
    User.userCount++
  }

  // 静态方法
  static getUserCount() {
    console.log(`Total users: ${User.userCount}`)
  }

  // 实例方法:登录验证
  login(email, password) {
    if (email === this.email && password === this._password) {
      console.log(`Welcome back, ${this.name}!`)
    } else {
      console.error('Login failed: invalid credentials.')
    }
  }

  // Getter
  get password() {
    return '********'
  }
  // Setter
  set password(value) {
    this.setPassword(value)
  }

  // 实例方法
  setPassword(newPassword) {
    if (newPassword.length >= 6) {
      this._password = newPassword
    } else {
      throw new Error('Password must be at least 6 characters')
    }
  }
}
// 创建用户,constructor 中自动调用 setPassword
const user1 = new User('Alice', '[email protected]', 'secret123')

// 使用 getter 查看密码(隐藏真实值)
console.log(user1.password) // 输出: ********
// 使用 setter 设置新密码
user1.password = 'newpass789' // 触发 setter,内部调用 setPassword

// 登录测试
user1.login('[email protected]', 'newpass789') // 输出: Welcome back, Alice!

// 查看静态属性
User.getUserCount() // 输出: Total users: 1

FP:

Functional Programming 函数式编程

FRP:

Functional Reactive Programming 函数式响应式编程

# AOP 与 Decorator

AOP:

Aspect Oriented Programming 面向切面编程

  AOP 是 OOP 的一种补充概念,核心思想是把业务逻辑与业务逻辑以外的代码分离,比如日志记录、权限验证、事务管理等。

  简单来说,就是 AOP 可以在不修改原有代码的情况下,在代码执行前后添加一些额外的功能。

# IoC 与 DI

IoC:

Inversion of Control 反转控制

  IoC 是一种设计思想和设计模式,其核心思想是将对象的创建和依赖关系交给外部容器,从而实现依赖关系的对象间的解耦。

DI:

Dependency Injection 依赖注入

  DI 是 IoC 的一种实现方式,它将依赖关系注入到对象中,从而实现依赖关系的对象间的解耦。

  常见的依赖注入方式有:

  • 构造函数注入:通过构造函数参数的形式将依赖关系注入到对象中。
class Controller {
  constructor() {
    this.service = new Service()
  }

  start() {
    this.service.start()
  }
}

// DI 容器
class Service {
  constructor() {
    this.prisma = new PrismaClient()
  }

  start() {
    this.prisma.start()
  }
}

class PrismaClient {
  start() {
    console.log('PrismaClient start')
  }
}

// 使用
const col = new Controller()
col.start()
代码示例
// database.js
class Database {
  save(data) {
    throw new Error("Abstract method 'save' must be implemented.")
  }
}
class MongoDBDatabase extends Database {
  save(data) {
    console.log(`[MongoDB] Persisted: ${data}`)
  }
}
class RedisDatabase extends Database {
  save(data) {
    console.log(`[Redis] Persisted: ${data}`)
  }
}

// user.service.js
class UserService {
  constructor(database) {
    this.database = database
  }

  registerUser(user) {
    this.database.save(user)
  }
}

// main.js
const mongoService = new UserService(new MongoDBDatabase())
mongoService.registerUser('Alice')
  • 装饰器注入:ts + nestjs 风格
代码示例
// database.ts
interface Database {
  save(data: any): void
}
class MongoDBDatabase implements Database {
  save(data: any): void {
    console.log(`[MongoDB] Persisted: ${JSON.stringify(data)}`)
  }
}
class RedisDatabase implements Database {
  save(data: any): void {
    console.log(`[Redis] Cached: ${JSON.stringify(data)}`)
  }
}

// user.service.ts
import { Injectable } from '@nestjs/common'

@Injectable()
class UserService {
  constructor(private readonly database: Database) {}

  registerUser(username: string): void {
    console.log(`Registering user: ${username}`)
    this.database.save({ username })
  }
}

// main.ts
const mongoService = new UserService(new MongoDBDatabase())
mongoService.registerUser('Alice')

# reflect-metadata

  - reflect-metadata (opens new window) 是一个元数据反射库,它允许开发者在运行时访问和修改类、方法、属性等元数据信息。

# 初始化项目
npm init -y
npm install reflect-metadata
npm install typescript ts-node --save-dev

# 创建tsconfig.json
tsc --init

# 追加:
# "experimentalDecorators": true,
# "emitDecoratorMetadata": true,

# 运行demo文件
npx ts-node simple.ts
import 'reflect-metadata'

function Inject(target: any, key: string) {
  target[key] = new (Reflect.getMetadata('design:type', target, key))()
}

class A {
  sayHello() {
    console.log('hello')
  }
}

class B {
  @Inject // 等同于执行了 @Reflect.metadata('design:type', A)
  a!: A

  say() {
    this.a.sayHello() // 不在需要 new A()
  }
}

new B().say() // hello

# DI 容器

  nestjs 中的 DI 容器,用于管理依赖注入。

  1. 注册所有有@Injectable 装饰器的类
  2. 通过 Constructor 了解类与类之间的依赖关系
  3. Nestjs 会自动创建@Injectable 装饰的类实例
  4. Nestjs 会自动创建依赖关系的类实例
  5. 按需进行调用

# @Module

  @Module 是 nestjs 的核心,用于管理模块之间的依赖关系。

管理:

  • imports: 引入其他 module 模块
  • controllers: 获取 DI 中具体的 class 类的实例

重点:

  • providers: 里面的 service 类会被放到 DI 中初始化
  • exports: 里面的 service 类可以在其他地方使用

# DTO / DAO

DTO:

Data Transfer Object 数据传输对象

DAO:

Data Access Object 数据访问对象

流程:

请求 -> DTO(对请求数据进行校验)-> 逻辑 -> DAO(对数据进行操作) -> 响应

  • create-cat.dto.ts
// 约定数据字段和类型
// 方便数据类型校验

export class CreateCatDto {
  name: string
  age: number
  breed: string
}
  • cat.schema.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
import { HydratedDocument } from 'mongoose'

export type CatDocument = HydratedDocument<Cat>

@Schema()
export class Cat {
  @Prop()
  name: string

  @Prop()
  age: number

  @Prop()
  breed: string
}

export const CatSchema = SchemaFactory.createForClass(Cat)
更新于 : 7/10/2025, 1:15:39 AM