koa --- > [MVC实现之三]换个角度重新开始-初始化

说明

  • 下面文章是对该系列前面2篇及项目中经验的总结,重新开始写的
  • 实现了Mar类,贯穿Router层、Controller层、Service层
  • 基本骨架的搭建

初始

  • 使用Koa创建一个简单的服务器,一般会使用如下
const koa = require('koa');
const app = new koa();
const Router = require('koa-router');
const router =new Router();
const handleIndex = async ctx => {
    ctx.body = 'Hello World';
};
const handleListen = async port => {
    console.log(`[Mar]Server is running at http://localhost:${port}`);
}
router.get('/', handleIndex);
app.use(router.routes());
app.listen(3000, handleListen(3000));

原则

借助Egg的Controller,Service的引用,有了以下灵感:

  1. 自定义一个类(Mar),在创建实例(app)的时候,会将Controller、Service方法挂载到app上
  2. 即Mar类是,集中管理各层的初始化及存放通用方法
  3. Controller层,主要用于联系路由层和Service层
  4. Service层在操作数据之后,给Controller层提供服务.

设计Mar类

根据上述的原则,我们设计Mar类的初始如下:

const koa = require('koa');

class Mar {
    constructor(conf) {
        const router = new Router();
        const controller = new Controller();
        const service = new Service();
        this.koa = new koa(conf); // 相当于app
        this.router = router.initRouter();
        this.controller = controller.initController();
        this.service = service.initService();
        // this.koa.use(router.routes());
    }

    listen(port) {
        this.koa.listen(port, async () => {
            console.log(`[mar]Server is running at http://localhost:${port}`);
        })
    }
}

class Router {
    constructor(conf) {

    }
    initRouter() {
        console.log('initRouter');
    }
}

class Controller {
    constructor(conf) {

    }
    initController() {
        console.log('initController');
    }
}
class Service {
    constructor(conf) {

    }
    initService() {
        console.log('initService');
    }
}

module.exports = Mar

说明:
1.现在都写在一个Mar里面,后期代码肯定很多,会分开写,然后将模块引入.
2.init函数仅用于测试,后期会根据需求更改
3.此时Mar类的引用如下.

// index.js
const Mar = require('./mar');
const mar = new Mar();
mar.listen(3000);

命令行运行: node index.js,结果如下
在这里插入图片描述

改进Mar类

  • 上面测试代码跑通
  • 开始逐步完善原则
    • Router层负责联系,路由和路由处理事件
    • Controller负责路由处理事件
    • Service负责处理复杂的方法,然后提供给Controller层
    • Mar贯通各个类,负责存储通用方法,并将参数传递给各个层,相当于一个粘合剂贯穿整个流程

[注: 在contructor中,使用this相当于指向实例]

  • 改进Mar类如下:
const koa = require('koa');

class Mar {
    constructor(conf) {
        this.koa = new koa(conf); // 相当于app
        this.service = new Service(this);
        this.controller = new Controller(this.service);
        this.router = new Router(this.controller);
    }

    listen(port) {
        this.koa.listen(port, async () => {
            console.log(`[mar]Server is running at http://localhost:${port}`);
        })
    }
}

class Router {
    constructor(controller) {
        console.log('Router:', controller.test());
    }
}
class Controller {
    constructor(service) {
        console.log('controller:', service.test());
    }
    test() {
        return 'Controller for Router'
    }
}
class Service {
    constructor(app) {
        console.log('Service:', app);
    }
    test() {
        return 'Service for Controller'
    }
}

module.exports = Mar

运行后输出如下:
在这里插入图片描述
说明:

  1. 可以看到在Service层,使用(暂时还未写)外面的服务
  2. 在Controller层使用Service层的服务
  3. 在Router层使用Controller层的服务

进一步改进Mar类

  • 引用分层的目的,是为了使开发更有规范,便于以后自己和他人的阅读.
  • 最终目的是提高开发效率,分为近期的和长久的
  • 一些通用的功能,就必须提取出来,放在Mar类里面
  • 上面在在传递服务给相邻层的时候,并未传入通用方法,因此改变如下
const koa = require('koa');

class Mar {
    constructor(conf) {
        this.koa = new koa(conf); // 相当于app
        this.service = new Service(this);		
        this.controller = new Controller(this);
        this.router = new Router(this);
    }

    listen(port) {
        this.koa.listen(port, async () => {
            console.log(`[mar]Server is running at http://localhost:${port}`);
        })
    }
}

class Router {
    constructor(app) {
        const { controller } = app;
        console.log('Router:', controller.test());
    }
}
class Controller {
    constructor(app) {
        const { service } = app;
        console.log('controller:', service.test());
    }
    test() {
        return 'Controller for Router'
    }
}
class Service {
    constructor(app) {
        console.log('Service:', app);
    }
    test() {
        return 'Service for Controller'
    }
}

module.exports = Mar
  • 注意: 由于引用了分层,故在Router层尽量的不要使用Service方法.

总结

  • 这一篇主要实现了一个基本骨架
  • 下一篇将会实现Router层和Controller层、Controller层和Service层的具体业务实现
发布了177 篇原创文章 · 获赞 22 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/piano9425/article/details/103416193
koa