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!
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.).
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.
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
// 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 }
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>; }
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"); } }
// 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"); } }
// 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(); });
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!