1.2 引入Service层

108 阅读1分钟

如上节所说,我们目前所有代码都堆砌在src/main.ts中,这在真正开发中是不可能的。

优化

新建一个src/user.service.ts,内容如下:

interface User {
  id: number;
  author: string;
  age: number;
}

class UserService {
  users: User[] = [
    { id: 1, author: "张三", age: 18 },
  ];
  getAll() {
    return this.users;
  }
  getUserById(id: number) {
    return this.users.find((user) => user.id === id);
  }

  addUser(user: Omit<User, "id">) {
    const id = this.users.length + 1;
    const newUser = {
      ...user,
      id,
    };
    this.users.push(newUser);
    return newUser;
  }

  removeUser(id: number) {
    this.users = this.users.filter((user) => user.id !== id);
  }

  updateUser(id: number, user: Omit<User, "id">) {
    const oldUser = this.getUserById(id);
    if (!oldUser) {
      throw new Error(`user not found`);
    }
    Object.assign(oldUser, user);
  }
}

export const userService = new UserService();

修改src/main.ts

import { Application, Router } from "https://deno.land/x/oak@v11.1.0/mod.ts";
import { userService } from "./user.service.ts";

const router = new Router();
router
  .get("/", (context) => {
    context.response.body = "hello world";
  })
  .get("/user", (context) => {
    context.response.body = userService.getAll();
  })
  .get("/user/:id", (context) => {
    const id = Number(context.params.id);
    const user = userService.getUserById(id);
    if (user) {
      context.response.body = user;
    } else {
      context.response.status = 404;
      context.response.body = "user not found";
    }
  })
  .post("/user", async (context) => {
    const result = context.request.body({
      type: "json",
    });
    const value = await result.value;
    const user = userService.addUser(value);
    context.response.body = user;
  })
  .put("/user/:id", async (context) => {
    const id = Number(context.params.id);
    const result = context.request.body({
      type: "json",
    });
    const value = await result.value;
    try {
      userService.updateUser(id, value);
      context.response.body = "update ok";
    } catch (e) {
      context.response.status = 400;
      context.response.body = e.message;
    }
  })
  .delete("/user/:id", (context) => {
    const id = Number(context.params.id);
    userService.removeUser(id);
    context.response.body = "delete ok";
  });

这样分层有什么好处呢?看起来代码只会更多,不会减少。

这是关注点分离,上层代码(main.ts)不需要知道下层(user.service.ts)的处理逻辑,二者完全解耦。封装service层业务逻辑有利于通用的业务逻辑的独立性和重复利用性。

如此一来,用户信息是怎么存储的(是在内存里,或是在文件里,还是数据库中),数据又是怎么修改的,上层都不必关注,只需要处理好参数接收、响应数据即可。同时也方便我们下一步的持久化操作。

作业

尝试下怎么持久化数据到文件中。