express 項目分層實踐

前言 上次咱們搭建了一個基本的 express 後臺,可是這樣的項目結構的可擴展性,維護性和代碼複用性都不是很好,參照以前學習 JavaWeb 時候的四層架構設計,用分層的思想來對 express 進行一點小優化,進一步提升代碼的可拓展性。本文的源代碼在 Github 上,建議看着代碼來看這篇文章。javascript

1 四(五)層結構概念

這個就簡單說一下,所謂四層架構就是 Model實體層,Dao層(數據訪問層也就是從數據庫中查數據),Service層(業務邏輯層,也就是處理好數據),Controller層(視圖控制層,在先後端分離的狀況下就是寫接口響應前端請求)和前端的 view(視圖層),爲啥要搞分層咧,說到底就是要解耦合,提升拓展性和維護性,寫代碼的時候,思路清晰一點,後面改代碼的時候也知道要改哪邊。css

可是咱們此次只是涉及後臺的,視圖層咱們就不用管了,只需看前面的就好了。前端

2 分層

首先看一下項目結構哈java

│  app.js
│  package.json
│  README.md
│
├─.idea
│  │  express-project.iml
│  │  misc.xml
│  │  modules.xml
│  │  vcs.xml
│  │  watcherTasks.xml
│  │  workspace.xml
│  │
│  └─inspectionProfiles
├─bin
│      www
│
├─config
│      db.json
│
├─dao
│      BaseDao.js
│      UserDao.js
│
├─models
│      user.js
│
├─public
│  ├─images
│  ├─javascripts
│  └─stylesheets
│          style.css
│
├─routes
│      index.js
│      users.js
│
├─services
│      UserService.js
│
├─utils
│      db-util.js
│
└─views
        error.jade
        index.jade
        layout.jade

按照分層思想,咱們新建幾個文件夾哈,首先是 Model層的 models 文件夾,dao 層的 dao 文件夾,service 層的 services 文件夾,controller 層的話就用原來的 routes 文件夾就能夠了,爲了方便,我加了一個全局配置的 config 文件夾和工具函數 utils 文件夾。具體項目以下,咱們從最底層開始來一個一個來分析git

2.1 config

這個就放着各類配置文件,例如個人 db.json 裏面就放了mongodb 的端口號,數據庫名那些,反正就是各類配置啦github

2.2 utils

這個就是有一些建立型的方法或者其餘公共方法,像建立數據庫鏈接池的方法我就放在這邊的 db-util 裏面了。mongodb

2.3 models

實體層,針對 mongodb 來講,一個集合對應一個 model,而後都是這樣的形式啦。數據庫

const mongoose = require('mongoose');
const { mongoClient } = require('../utils/db-util');

// 建立 user Schema
const user = new mongoose.Schema({
  name: String,
  id: String,
},{versionKey: false});

/*model 的參數1 導出的模塊名,
參數2 建立的 Schema,
參數2 指定數據庫中的集合的名字,若不加的,則抹默認取‘第一個參數s’的集合*/
let User = mongoClient.model('User', user, 'user');

module.exports = User;

2.4 dao

建立完實體層,接下來就是 dao 層了,這邊我封裝了一個 BaseDao,基本的數據庫操做都有了,後面咱們建立其餘 dao 的時候就很舒服啦,直接繼承一下 BaseDao 就行了。例以下面的這個 UserDao:express

let BaseDao = require('./BaseDao');
// 導入對應的實體
let User = require('../models/user');

class UserDao extends BaseDao{
  constructor() {
    super(User);
  }
  //若是有啥特殊需求的話,本身再重寫方法咯
}

module.exports = UserDao;

這樣就寫好了一個基本的 dao 了,增刪改查這些他都從 BaseDao 中繼承了,json

2.5 services

service 層是業務邏輯層,這麼寫就看你項目的業務啦。我下面就簡單些一個查詢全部 user 數據的方法啦。

const UserDao = require('../dao/UserDao');

let userDao = new UserDao();

class UserService {
  async getUserList() {
    try {
      // 調用 dao 層查詢數據
      let userList = await userDao.findAll();
      return userList;
    } catch (err) {
      console.log(`getUserList error--> ${error}`);
      return error;
    }
  }
}
module.exports = UserService;

2.6 routes

controller 層,寫接口用,這個寫起來簡單,就拿一下 service 層的數據返回就能夠啦。

var express = require('express');
var router = express.Router();
const UserService = require('../services/UserService');
let userService = new UserService();

/* GET users listing. */
router.get('/', function(req, res, next) {
  userService.getUserList().then((data)=>{
    res.json({
      code:0,
      msg:'OK',
      data:data
    })
  });
  // res.send('respond with a resource');
});

router.get('/login',(req,res,next)=>{
  res.json({
    code:0,
    msg:'OK',
    data:{result:true}
  })
});
module.exports = router;

而後這邊的話,我有一個想法,就是想着每次多一個路由實例(controller)的時候,就要往 app.js 裏面導入並引入,以爲這樣 controller 多了的時候,app.js 裏面代碼會不少,因此就想着把模塊導入的代碼移到 routes 文件夾裏面的 index.js 裏面來,app.js 就引入個 index 就好啦。因此就有了下面 index.js 的代碼。

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});
// user 路由模塊
// 當我在 user 文件裏面寫一個 '/login' 的時候,前端訪問就要訪問 '/user/login'
router.use('/user', require('./users'));
module.exports = router;

至此,全文就結束啦,對於 express 框架的分層實踐若是有更好的建議或者我這樣分層有啥問題的話,歡迎在在下方留言哈,你們一塊兒學習一下。

相關文章
相關標籤/搜索