用Typescript在Node.js中实现模式规范
#编程 #教程 #node #ddd

该模式是一种软件设计模式,可让您以可清晰可重复使用的格式定义业务规则。尤其是在应用程序中需要实施涉及动作实体的复杂业务规则。在本文中,让我们看看如何在用打字稿的Node.js应用程序中实现规范标准。

定义实体

为了体现规范模式的使用,让我们创建一个称为koud1的简单实体。它具有交易:datedate(transaion的日期)和description(跨性别的描述)。

在Koud6文件夹中创建一个名为Koud5的文件,其中包含以下内容:

export class Transaction {
  constructor(
    public readonly amount: number,
    public readonly date: Date,
    public readonly description: string,
  ) {}
}

此类代表具有以下属性的财务转换:

amount:transaion的价值
date:数据da datransaã§o
description:Transaion的描述

创建业务规则

现在我们拥有Transaion实体,让我们创建业务规则,以验证交易是否是多种多样的。在src/specifications文件夹中创建一个名为specification.ts的文件,其中包含以下内容:

export interface Specification<T> {
  isSatisfiedBy(candidate: T): boolean;
  and(other: Specification<T>): Specification<T>;
  or(other: Specification<T>): Specification<T>;
  not(): Specification<T>;
}

export class CompositeSpecification<T> implements Specification<T> {
  public isSatisfiedBy(candidate: T): boolean {
    throw new Error("Not implemented");
  }

  public and(other: Specification<T>): Specification<T> {
    return new AndSpecification(this, other);
  }

  public or(other: Specification<T>): Specification<T> {
    return new OrSpecification(this, other);
  }

  public not(): Specification<T> {
    return new NotSpecification(this);
  }
}

class AndSpecification<T> extends CompositeSpecification<T> {
  constructor(
    private readonly left: Specification<T>,
    private readonly right: Specification<T>
  ) {
    super();
  }

  public isSatisfiedBy(candidate: T): boolean {
    return (
      this.left.isSatisfiedBy(candidate) && this.right.isSatisfiedBy(candidate)
    );
  }
}

export class OrSpecification<T> extends CompositeSpecification<T> {
  constructor(
    private readonly left: Specification<T>,
    private readonly right: Specification<T>
  ) {
    super();
  }

  public isSatisfiedBy(candidate: T): boolean {
    return (
      this.left.isSatisfiedBy(candidate) || this.right.isSatisfiedBy(candidate)
    );
  }
}

export class NotSpecification<T> extends CompositeSpecification<T> {
  constructor(private readonly specification: Specification<T>) {
    super();
  }

  public isSatisfiedBy(candidate: T): boolean {
    return !this.specification.isSatisfiedBy(candidate);
  }
}


此文件定义了一个规范接口,该界面代表了业务规则和类综合委员

和指定类,ORSPECIFICATION和NOTSPECIFICATION是分别实施羊毛操作而非或不能分别实施羊毛操作的复合材料规范子类。

在Koud11文件夹中创建一个名为Koud5的文件,其中包含以下内容:


import { Transaction } from "../entities/transaction";
import { CompositeSpecification } from "./specification";

export class TransactionSpecification extends CompositeSpecification<Transaction> {
  public isSatisfiedBy(candidate: Transaction): boolean {
    return TransactionSpecification.amountIsGreaterThan(50)
      .and(TransactionSpecification.dateIsGreaterThan(new Date(2022, 0, 1)))
      .and(TransactionSpecification.descriptionContains("supermercado"))
      .isSatisfiedBy(candidate);
  }

  public static amountIsGreaterThan(value: number): TransactionSpecification {
    return new (class extends TransactionSpecification {
      public isSatisfiedBy(candidate: Transaction): boolean {
        return candidate.amount > value;
      }
    })();
  }

  public static amountIsLessThan(value: number): TransactionSpecification {
    return new (class extends TransactionSpecification {
      public isSatisfiedBy(candidate: Transaction): boolean {
        return candidate.amount < value;
      }
    })();
  }

  public static dateIsGreaterThan(value: Date): TransactionSpecification {
    return new (class extends TransactionSpecification {
      public isSatisfiedBy(candidate: Transaction): boolean {
        return candidate.date > value;
      }
    })();
  }

  public static dateIsLessThan(value: Date): TransactionSpecification {
    return new (class extends TransactionSpecification {
      public isSatisfiedBy(candidate: Transaction): boolean {
        return candidate.date < value;
      }
    })();
  }

  public static descriptionContains(value: string): TransactionSpecification {
    return new (class extends TransactionSpecification {
      public isSatisfiedBy(candidate: Transaction): boolean {
        return candidate.description.includes(value);
      }
    })();
  }
}


Transactions Percification类是复合材料规范的一个子类,它定义了交易实体的特定业务规则。

静态函数量量,量,dateisgreaterthan,dateisslessthan和描述返回代表每个业务规则的Transactions Peccification Instinctions。整个isSatisfiedBy包含规则的组成。该类具有子类在创建另一个规则时只能调整并扩展以撰写以撰写的方式。

使用业务规则

现在我们已经定义了谈判规则,我们可以使用它们来验证跨界。在Koud16文件夹中创建一个名为Koud5的文件,其中包含以下内容:

import { Transaction } from './Transaction';
import { TransactionSpecification, Specification } from './TransactionSpecification';

export class TransactionValidator {
  constructor(private readonly specification: Specification<Transaction>) {}

  public validate(transaction: Transaction): boolean {
    return this.specification.isSatisfiedBy(transaction);
  }
}

// testando o validator
const transaction = new Transaction(100, new Date(), 'Compra no supermercado');

const validator = new TransactionValidator()

console.log(validator.validate(transaction)); // true

此文件定义了TransactionValidator类,该类在构建器中接收一个Specification<Transaction>的实例,并具有一个完整的验证,该级别接收转移并返回布尔值,以指示是否已读取Transaion是否已读。

>

在上面的示例中,我们创建了一个带有Value 100的Transaion,Data New()并描述了“在超市中的购买”。然后,我们创建了一个TransactionValidator实例,业务规则验证了Transaion的价值是否大于50,如果交易日期大于01/01/2022,以及交易的描述是否包含“超市”一词。最后,我们通过传递创建的转移并将结果显示在控制台上。

包括£o

在本文中,我们已经看到了如何在Koud22的Koud0应用程序中实现Specification模式。我们创建了一个Transaction实体,定义了业务规则,以使用TransactionSpecification类验证过渡,并使用TransActionValidator类创建了交易验证器。

Specification模式可以在各种情况下应用,当我们需要实施涉及Motiple实体的复杂业务规则时,这是一个不错的选择。有了它,我们可以使模块化,维护和可扩展的方式更加模块化。

segue exemplo no github:https://github.com/jhonesgoncalves/example-specification-ts