启动器函数编写

抛开系统架构不说,基础的代码架构是一定要掌握的,好的代码架构是程序可维护的基础。

有可能你上一个月写的代码这个月就看不懂,不知道当时怎么写的,因此我记录一下最近学习的代码架构。

关于boot函数的编写。

先来看分层架构。

参考 《软件体系结构与设计模式》 第 159 页 图 7-3

优点:

1、分层结构将应用系统正交地划分为若干层,每一层只解决问题的一部分,通过各层的协作提供整体解决方案。大的问题被分解为一系列相对独立的子问题,局部化在每一层中,这样就有效的降低了单个问题的规模和复杂度,实现了复杂系统的第一步也是最为关键的一步分解。

2、分层结构具有良好的可扩展性,为应用系统的演化增长提供了一个灵活的框架,具有良好的可扩展性。增加新的功能时,无须对现有的代码做修改,业务逻辑可以得到最大限度的重用。同时,层与层之间可以方便地插入新的层来扩展应用。

3、分层架构易于维护。在对系统进行分解后,不同的功能被封装在不同的层中,层与层之间的耦合显著降低。因此在修改某个层的代码时,只要不涉及层与层之间的接口,就不会对其他层造成严重影响。

缺点:

1、不容易划分层次。

2、找不到合适的、正确的层次抽象方法。

 比起缺点优点属实有点多。

下面是一个分层的实例:

逻辑架构

用户接口层 apis

  • http server
  • PRC 框架

应用层 service 接口

  • 定义软件要完成的所有任务
  • 业务流程控制逻辑
  • 各种领域模型相互协作
  • 事务日志安全
  • 通常指service

领域层

  • 表达业务概念,状态信息,规则
  • 业务核心层
  • 主要包含,实体,值对象 ,领域对象

基础设施层

  • 提供统一的技术能力
  • 应用层提供消息,领域层提供持久化机制,用户界面提供组件
  • 统一算法
  • 各层之间的通信
  • 和其他服务器交互

物理架构

  • PO 持续化对象 
  • DAO 操作数据库
  • VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。
  • DTO(Data Transfer Object):数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对象。
  • DO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或无形的业务实体。
  • PO(Persistent Object):持久化对象,它跟持久层(通常是关系型数据库)的数据结构形成一一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应PO的一个(或若干个)属性。

现在基本了解了什么是代码架构。下面说一下boot函数的编程思想。我用伪代码实例一下

1、需要一个boot类

class   bootApplication {

      属性;
      //...

    构造函数()
    
    pubilc Start(){
        //1.初始化starter
        init()
	//2.安装starter
        setup()
	//3.启动starter
        start()
    //... //等待其余线程结束 Wait() } private init(){} private setup() private start()
private Wait()
}

2、需要一个基础starter接口,这也是每个子系统的生命周期。

//资源启动器,每个应用少不了依赖其他资源,比如数据库,缓存,消息中间件等等服务
//启动器实现类,不需要实现所有方法,只需要实现对应的阶段方法即可,可以嵌入@BaseStarter
//通过实现资源启动器接口和资源启动注册器,友好的管理这些资源的初始化、安装、启动和停止。
//Starter对象注册器,所有需要在系统启动时需要实例化和运行的逻辑,都可以实现此接口
//注意只有Start方法才能被阻塞,如果是阻塞Start(),同时StartBlocking()要返回true




type Starter interface { //资源初始化和,通常把一些准备资源放在这里运行 Init(StarterContext) //资源的安装,所有启动需要的具备条件,使得资源达到可以启动的就备状态 Setup(StarterContext) //启动资源,达到可以使用的状态 Start(StarterContext) //说明该资源启动器开始启动服务时,是否会阻塞 //如果存在多个阻塞启动器时,只有最后一个阻塞,之前的会通过goroutine来异步启动 //所以,需要规划好启动器注册顺序 StartBlocking() bool //资源停止: // 通常在启动时遇到异常时或者启用远程管理时,用于释放资源和终止资源的使用, // 通常要优雅的释放,等待正在进行的任务继续,但不再接受新的任务 Stop(StarterContext) PriorityGroup() PriorityGroup Priority() int }

3、一个注册器函数和一个容器

  // 接口类型

    starterRegister   [] starter  

  // 把接口添加到列表数组里

    Register( intrerface  starter ){

  append(starterRegister  , starter)

4、需要实现接口的类。然后调用注册函数,添加到starterRegister  。

然后问哦们回到 boot函数的编写

例如initi()函数。

遍历  starterRegister  执行每一个实现结构的类的init函数。

 func init(){

    for starterRegister {
       
         starterRegister[i].init()
        
    
              }
  }

剩下的 start().... 都一样了。

然后这是我写的Golang代码。其实吧啥都不重要,好看最重要。这就是整个项目,按着 Ctrl 点就能找到每个结构体的在哪。也好修改。

 

、找不到合适的、正确的层次抽象方法。
[, Zhǎo bù dào héshì de, zhèngquè de céngcì chōuxiàng fāngfǎ.]
, Find the right, the right level of abstraction method.

猜你喜欢

转载自www.cnblogs.com/Addoil/p/11645755.html
今日推荐