- 单例模式
它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。
class User {
static #instance: User;
#name: string;
constructor(name: string) {
this.#name = name
if (new.target !== User) {
return
}
if (!User.#instance) {
User.#instance = this
return User.#instance
} else {
// 提示
console.error("不能重复初始化")
}
return User.#instance
}
get getName() {
return this.#name
}
}
const u1 = new User("张三")
const u2 = new User("李四")
console.log(u1 === u2); // true
console.log(u2.getName); // 张三
- 工厂模式
它在创建对象时提供了一种封装机制,将实际创建对象的代码与使用代码分离
abstract class Shape {
abstract draw(): void;
}
class Rectangle implements Shape {
draw() {
console.log("draw rectangle")
}
}
class Square implements Shape {
draw() {
console.log("draw square")
}
}
class Circle implements Shape {
draw() {
console.log("draw circle ")
}
}
class ShapeFactory {
public getShape(shapeType: "Rectangle" | "Square" | "Circle"): Shape {
switch (shapeType) {
case "Rectangle":
return new Rectangle();
case "Square":
return new Square();
case "Circle":
return new Circle();
default:
throw new Error("没有这个形状")
}
}
}
const shapeFactory = new ShapeFactory()
const rectangle = shapeFactory.getShape("Rectangle")
const square = shapeFactory.getShape("Square")
const circle = shapeFactory.getShape("Circle")
rectangle.draw() // draw rectangle
square.draw() // draw square
circle.draw() // draw circle
- 原型模式
复用原型上的方法和属性以提高性能
const shapePrototype = {
name: "",
draw: function () {
console.log(this.name);
}
};
const shape1 = Object.create(shapePrototype, {
name: {
value: "square"
}
});
const shape2 = Object.create(shapePrototype, {
name: {
value: "circle"
}
});
shape1.draw() // square
shape2.draw() // circle
console.log(shape1.draw === shape2.draw) // true
采用ES6的class是同样的效果
class Shape {
name: string
constructor(name: string) {
this.name = name
}
draw(): void {
console.log(this.name)
}
}
const shape1 = new Shape("square")
const shape2 = new Shape("circle")
shape1.draw() // square
shape2.draw() // circle
console.log(shape1.draw === shape2.draw) // true
- 适配器模式
可用来在现有接口和不兼容的类之间进行适配。它被添加到现有代码中来协调两个不同的接口
class NewAPI {
newGetList() {
return [1, 2, 3]
}
}
class OldAPI {
oldGetList() {
return [2, 3, 4]
}
}
class APIAdapter extends OldAPI {
constructor() { super() }
newGetList() {
return this.oldGetList()
}
}
function getList(api: NewAPI) {
return api.newGetList()
}
getList(new NewAPI())
getList(new APIAdapter())
getList(new OldAPI()) // 报错
- 依赖注入模式
将一个对象所依赖的其他对象的创建过程,从该对象本身中分离出来,以便更好地实现解耦和可测试性。
// 定义一个容器类
class Container {
bindings: { [key: string]: Function };
constructor() {
this.bindings = {};
}
bind(abstract: string, concrete: Function) {
this.bindings[abstract] = concrete;
}
make(abstract: string | number) {
const concretion = this.bindings[abstract];
if (typeof concretion === 'function') {
console.log(this)
return concretion(this);
}
return concretion;
}
}
// 创建容器实例
const container = new Container();
// 绑定服务到容器
container.bind('logger', () => {
return {
log(message: any) {
console.log(message);
}
};
});
// 使用依赖注入
function serviceWithDependency(container: Container) {
const logger = container.make('logger');
logger.log('This is a dependency injection example.');
}
// 解析依赖并执行函数
serviceWithDependency(container);
采用装饰器模式
import "reflect-metadata"
const requiredMetadataKey = Symbol("required");
function required(target: Object, propertyKey: string | symbol, parameterIndex: number) {
let existingRequiredParameters: number[] = Reflect.getOwnMetadata(requiredMetadataKey, target, propertyKey) || [];
existingRequiredParameters.push(parameterIndex);
Reflect.defineMetadata(requiredMetadataKey, existingRequiredParameters, target, propertyKey);
}
function validate(target: any, propertyName: string, descriptor: TypedPropertyDescriptor<Function>) {
let method = descriptor.value!;
descriptor.value = function () {
let requiredParameters: number[] = Reflect.getOwnMetadata(requiredMetadataKey, target, propertyName);
console.log(propertyName)
if (requiredParameters) {
for (let parameterIndex of requiredParameters) {
if (parameterIndex >= arguments.length || arguments[parameterIndex] === undefined) {
throw new Error("Missing required argument.");
}
}
}
return method.apply(this, arguments);
};
}
class BugReport {
type = "report";
title: string;
constructor(title: string) {
this.title = title;
}
@validate
print(@required verbose: boolean) {
if (verbose) {
console.log(`type: ${this.type}\ntitle: ${this.title}`)
return;
} else {
console.log(`title: ${this.title}`)
}
}
@validate
log(@required log: string) {
console.log(log)
}
}
const bugReport = new BugReport("test")
bugReport.print(true)
bugReport.log("this is a example")