Heim  >  Artikel  >  Web-Frontend  >  Was ist saubere Architektur? Wie implementiert man es mit Node?

Was ist saubere Architektur? Wie implementiert man es mit Node?

青灯夜游
青灯夜游nach vorne
2023-02-22 19:39:462286Durchsuche

Was ist saubere Architektur? Dieser Artikel führt Sie durch Clean Architecture und spricht darüber, wie Sie Clean Architecture mit Node.js implementieren. Ich hoffe, er wird Ihnen hilfreich sein!

Was ist saubere Architektur? Wie implementiert man es mit Node?

Clean Architecture

Clean Architecture ist ein von Robert C. Martin vorgeschlagenes Software-Architekturmuster. Der Zweck besteht darin, das System zu schichten und eine Trennung der Belange zu erreichen, wodurch das System leichter zu verstehen, zu warten und zu erweitern ist. Diese Architektur unterteilt das System von innen nach außen in vier Ebenen: Entitätsschicht, Anwendungsfallschicht, Präsentationsschicht, Infrastruktur (Repository, Framework usw.).

Was ist saubere Architektur? Wie implementiert man es mit Node?

In diesem Artikel stellen wir vor, wie man Clean Architecture mit Node.js implementiert, und stellen einige Beispielcodes zur Verfügung, um die Schlüsselkonzepte der Architektur zu demonstrieren.

Als nächstes verwenden wir das TypeScript-Projektbeispiel (github.com/lulusir/cle…). Das Projekt verwendet eine Monorepo-Struktur und wird mit Rush.js verwaltet. Der Serverordner enthält drei Unterprojekte: Core, Koa und NestJS-App. Core ist die Kerngeschäftslogik, Koa verwendet Koa + Prisma als zugrunde liegendes Framework-Webprojekt und NestJS-App verwendet NestJS + Typeorm zugrunde liegendes Gerüst. Der Zweck besteht darin, zu demonstrieren, wie dieselbe Geschäftslogik verschiedene Frameworks überbrücken kann. [Verwandte Tutorial-Empfehlungen: nodejs-Video-Tutorial, Programmierlehre]

In diesem Projekt enthält die Entitätsschicht Entitätsobjekte und zugehörige Geschäftsregeln und -logik, die Anwendungsfallschicht enthält die Anwendungsfälle und die Geschäftslogik des Systems. und die Repository-Schicht ist dafür verantwortlich, Daten zu speichern und abzurufen. Die Präsentationsschicht wird der externen http-Schnittstelle ausgesetzt.

Projektfunktionen:

Realisieren Sie eine Funktion zum Veröffentlichen und Durchsuchen von Beiträgen.

  • Benutzererstellung, Abfrage.

  • Veröffentlichung, Bearbeitung, Abfrage und Löschung von Beiträgen

    ├── server
    │   ├── core // 核心业务逻辑
    │   │   └── src
    │   │       ├── domain
    │   │       ├── repository
    │   │       └── useCase
    │   ├── koa
    │   │   └── src
    │   │       ├── post
    │   │       └── user
    │   └── nestjs-app
    │       ├── src
    │           ├── post
    │           │   ├── dto
    │           │   └── entities
    │           └── user
    │               └── entities
    └── web

Kern: Kern ist der Code der Kerngeschäftslogik.

Domäne: Speichert entitätsbezogenen Code, z. B. geschäftsspezifische Modelle usw.
  • Anwendungsfälle: Speichert geschäftslogikbezogenen Code, z. B. die Verarbeitung von Geschäftslogik und Daten Überprüfung und Aufruf des Repositorys usw.

    Repository: Speicher und zugehörige Schnittstellen für externe Speichersysteme
    • koa/nestjs-app: Der tatsächliche Verbraucher des Kerns
    implementiert spezifische Router und Repository entsprechend der Schnittstelle des Kerns
    • Projektfunktionen
Verwenden Sie die Ideen von DDD und Clean Architecture, um Geschäftslogik von der Framework-Implementierung zu trennen.

Verwenden Sie die Monorepo-Projektstruktur, um mehrere zusammengehörige Projekte einfach zu verwalten.

Es werden mehrere Beispielanwendungen bereitgestellt, um den schnellen Einstieg zu erleichtern.
  • Basiert auf TypeScript und verbessert die Lesbarkeit und Wartbarkeit des Codes.
  • Im Kern haben wir den Kerngeschäftslogikcode. Diese Ebene enthält Domänen, Repository-Schnittstellen und Anwendungsfälle. Domänen enthalten Code, der sich auf Entitäten bezieht, beispielsweise auf ein bestimmtes Geschäftsmodell. Das Repository enthält relevante Schnittstellen zu externen Speichersystemen. Anwendungsfälle enthalten Code im Zusammenhang mit der Geschäftslogik, z. B. zur Handhabung der Geschäftslogik, zur Datenvalidierung und zum Aufrufen von Repositorys.
  • Auf der Koa/NestJS-App-Ebene haben wir tatsächliche Verbraucher auf der Kernebene. Sie implementieren spezifische Router und Repositorys basierend auf den von der Kernschicht bereitgestellten Schnittstellen. Einer der Hauptvorteile der Verwendung von Clean Architecture besteht darin, dass die Geschäftslogik von der technischen Implementierung getrennt wird. Dies bedeutet, dass Sie problemlos zwischen verschiedenen Frameworks und Bibliotheken wechseln können, ohne die Kerngeschäftslogik zu ändern. In unserem Beispiel können wir zwischen koa und nestjs-app wechseln und dabei die gleiche Kerngeschäftslogik beibehalten.
Code-Implementierung

Entitätsschicht definieren

// server/core/src/domain/post.ts
import { User } from "./user";

export class Post {
  author: User | null = null;
  content: string = "";
  updateAt: Date = new Date(); // timestamp;
  createdAt: Date = new Date(); // timestamp;
  title: string = "";
  id: number = -1;
}

// server/core/src/domain/user.ts
export class User {
  name: string = ''

  email: string = ''

  id: number = -1
}

Speicherschnittstelle definieren

import { Post } from "../domain/post";

export interface IPostRepository {
  create(post: Post): Promise<boolean>;

  find(id: number): Promise<Post>;

  update(post: Post): Promise<boolean>;

  delete(post: Post): Promise<boolean>;

  findMany(options: { authorId: number }): Promise<Post[]>;
}

...
import { User } from "../domain/user";

export interface IUserRepository {
  create(user: User): Promise<boolean>;
  find(id: number): Promise<User>;
}

Anwendungsfallschicht definieren

import { User } from "../domain/user";
import { IUserRepository } from "../repository/user";

export class UCUser {
  constructor(public userRepo: IUserRepository) {}

  find(id: number) {
    return this.userRepo.find(id);
  }

  create(name: string, email: string) {
    if (email.includes("@test.com")) {
      const user = new User();
      user.email = email;
      user.name = name;
      return this.userRepo.create(user);
    }
    throw Error("Please use legal email");
  }
}

koa. Projekt

im Koa-Projekt implementierte Storage-Layer-Schnittstelle

// server/koa/src/user/user.repo.ts
import { PrismaClient } from "@prisma/client";
import { IUserRepository, User } from "core";

export class UserRepository implements IUserRepository {
  prisma = new PrismaClient();

  async create(user: User): Promise<boolean> {
    const d = await this.prisma.user_orm_entity.create({
      data: {
        email: user.email,
        name: user.name,
      },
    });

    return !!d;
  }

  async find(id: number): Promise<User> {
    const d = await this.prisma.user_orm_entity.findFirst({
      where: {
        id: id,
      },
    });

    if (d) {
      const u = new User();
      u.email = d?.email;
      u.id = d?.id;
      u.name = d?.name;
      return u;
    }
    throw Error("user id " + id + "not found");
  }
}

Implementieren von HTTP-Routing (Präsentationsschicht) im Koa-Projekt

// server/koa/src/user/user.controller.ts
import Router from "@koa/router";
import { UCUser } from "core";
import { UserRepository } from "./user.repo";

export const userRouter = new Router({
  prefix: "/user",
});

userRouter.get("/:id", async (ctx, next) => {
  try {
    const service = new UCUser(new UserRepository());
    if (ctx.params.id) {
      const u = await service.find(+ctx.params.id);
      ctx.response.body = JSON.stringify(u);
    }
  } catch (e) {
    ctx.throw(400, "some error on get user", e.message);
  }
  await next();
});

nest-js-Projekt

nestjs-Projektbeispiele finden Sie in diesem Pfad (

github.com/lulusir/cle…

Ich werde es nicht veröffentlichen hier Code

Abschließend

Bitte beachten Sie, dass wir im eigentlichen Projekt die Kerngeschäftslogik nicht in einem separaten Lager (d. h. Kern) ablegen, sondern lediglich die Verwendung derselben Geschäftslogik unter verschiedenen Frameworks demonstrieren.

Indem wir das Geschäft platzieren Die Logik ist vom Framework getrennt und Sie können problemlos zwischen verschiedenen Frameworks und Bibliotheken wechseln, ohne die Kerngeschäftslogik zu ändern. Wenn Sie skalierbare und wartbare Anwendungen erstellen möchten, ist Clean Architecture auf jeden Fall eine Überlegung wert.

Wenn Sie demonstrieren möchten, wie Sie eine Verbindung zu anderen Frameworks herstellen, können Sie es im Kommentarbereich vorlegen.

Projektadresse (github.com/lulusir/cle… Wenn Sie es gut finden, können Sie ihm einen Stern geben , danke

Weitere Node-bezogene Informationen. Weitere Informationen finden Sie unter: nodejs-Tutorial!

Das obige ist der detaillierte Inhalt vonWas ist saubere Architektur? Wie implementiert man es mit Node?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen