前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >架构师技能2:组件化思想之框架、脚手架、基础应用框架。

架构师技能2:组件化思想之框架、脚手架、基础应用框架。

作者头像
黄规速
发布2022-04-14 15:43:59
4440
发布2022-04-14 15:43:59
举报

《架构设计》https://blog.csdn.net/hguisu/category_5905793.html系列里面主要谈的是架构相关方法论,没有具体到代码层面。最近抽点时间来总结架构师如何站在巨人的肩膀上眺望远方。

代码语言:txt
复制
    管理的精髓就是“制度管人,流程管事”。而所谓流程,就是对一些日常工作环节、方式方法、次序等进行标准化、规范化。且不论精不精髓,在技术团队中,对一些通用场景,统一规范是必要的,只有步调一致,才能高效向前。

一、框架和组件

这个在《架构设计(1)-谈谈架构》 已经明确:

框架是组件实现的规范,提供一定的约束、规范、配置,具备通用业务的基础开发能力,提供一定程度的组件、工具等公共封装。例如:MVC、MVP、MVVM等,是提供基础功能的半成品,例如开源框架:Spring、spring boot、Django等,这是可以拿来直接使用或者在此基础上二次开发。框架是规范,架构是结构。

1、框架主要有两特性:

1)、框架是提供基础功能的半成品:已经对基础的代码(例如文件上传,数据库查询)进行了封装并提供相应的API,开发者在使用框架是直接调用封装好的api可以省去很多代码编写,从而提高工作效率和开发速度。

2)、框架是规范:框架规范应用的体系结构。它定义了整体结构,模块的划分、模块的主要职责,模块之间的协作。

2、使用框架的目的:

1)、提高开发效率:

代码语言:txt
复制
    使用成熟的框架,基础工作已经完成,应用开发人员只需要集中精力完成系统的业务逻辑设计。框架一般已经处理好基础功能和细节问题,比如事务处理,安全性,数据流控制等问题。还有框架一般都经过很多人使用,所以结构很好,所以扩展性也很好,而且它是不断升级的,你可以直接享受别人升级代码带来的好处。

2)、提高团队人员协同效率。

通过框架规范,规定大层次的约束与规范,较小层次的设计在这些约束与规范下进行的话,能最大限度地满足某些方面的特性,如可读性、可靠性、可扩展性、安全性。同时有使得代码更为清晰及更易维护。最终目的是提高团队协作效率,降低工程维护成本。

3、组件化

组件化就是基于可重用的目的,将一个大的软件系统按照分离关注点的形式,拆分成多个独立的组件,已较少耦合。把重复的代码提取出来合并成为一个个组件,组件最重要的就是重用(复用),位于框架最底层,其他功能都依赖于组件,可供不同功能使用,独立性强。

大部分来说,组件主要分三层:业务组件,基础业务组件以及基础组件,组件之间只能通过接口耦合,也就是依赖倒置原则,每个组件都提供对外的接口文档以描述该组件提供的功能。

组件化的好处:解耦,平台化,职责单一,复用性,编译集成。

  1. 解耦:每个组件都是一个单一的工程(项目),对外只提供接口。组件之间的依赖只能通过接口,通过工程或者项目的方式,可以很大程度避免代码之间的耦合。
  2. 职责单一:每个组件只提供单一的功能,每个组件都可以单独去维护扩展,只要接口不变。
  3. 复用性强:基于职责单一,那么新项目中就可以依赖需要的组件。如果有其他项目需要该组件可以直接引入使用,而不是拷贝代码。
  4. 平台化:这个其实是最有价值的,如果你作为一个平台产品,其他业务或者兄弟部门的开发同学想集成到你的产品中,那么他在开发测试的时候就很方便的依赖必须的组件,方便调试。这样,在多部门,多team去联合调试的时候,会节省很多的时间,但是这个要求文档必须要够完善,以便于其他人能够很方便的去接入。类似于:支付宝,美团等等平台级的产品。
  5. 编译集成:单个组件化组合成一个产品,可单独开发,测试,发布一个组件。对于编译来说可以很快速的定位问题以及快速编译,打包。
  6. 组件单独测试方便:测试完成后进行集中测试。

二、组件化之基础应用框架/脚手架


组件化到组件的粒度到底多大,如何区分业务组件以及基础业务组件?这个需要根据具体项目具体分析。

脚手架:基于开源框架或者组件的整合,只是一个空架子,把项目的基础环境配置和maven相关依赖都搭建好,封装程度较低,偏向于一套技术最佳实践。做前端node的都知道,经常去npm install 一个脚手架或者vue-cli脚手架搭建工具,然后用脚手架命令去创建一个空架子的项目。

基础应用框架:除了整合应用使用的开源框架,同时还封装项目应用到的基本工具和基础功能:日志,接口协议、异常处理、安全处理、单元测试、参数校验等。即在脚手架的基础。

注明:以上仅个人理解脚手架和项目基础技术框架。

在微服务里面或者生命周期比较长的项目,一般是需要对使用不同原始框架拼装项目的基础框架,目的是封装提供项目使用的基础功能和规范项目技术体系,不要重复造轮子,提高团队的协同效率,降低维护成本。

例如:

1、封装基础组件:如spring boot的版本统一规范和依赖规范。

2、日志组件统一规范。

3、restFull接口规范:比如rest接口返回格式。

4、异常处理统一规范

5、参数校验

6、安全处理机制。

7、api文档

8、基础应用配置。

9、模型统一规范格式。

10、一些基础工具类:比如项目使用获取ip,邮箱、手机号等校验。

11、单元测试规范。

下面是一一具体描述。

三、基础应用框架说明

1、基础组件和依赖统一规范管理:

主要spring boot的版本统一规范和依赖规范。主要的措施:

1)、通过maven的parent工程统一管理项目所有的jar的版本。

2)管理jar包依赖,在parent工程中配置依赖通用性jar包,然后引用该parent的项目就会自动继承。

3)parent工程通过<dependencyManagement>管理了可选的jar依赖,具体项目是按需继承。

如:<dependencyManagement>

<dependencies>

代码语言:txt
复制
 <dependency>
代码语言:txt
复制
   <groupId>junit</groupId>
代码语言:txt
复制
   <artifactId>junit</artifactId>
代码语言:txt
复制
   <version>3.8.1</version>
代码语言:txt
复制
   <scope>test</scope>
代码语言:txt
复制
 </dependency>

</dependencies>

</dependencyManagement>

具体项目只要按需去依赖自己所需的jar包,并且version 和 scope 都继承pom。

<dependency>

代码语言:txt
复制
   <groupId>junit</groupId>
代码语言:txt
复制
   <artifactId>junit</artifactId>

</dependency>

2、日志组件统一规范:

Java应用项目经常遇到的一个棘手的问题就是:依赖的包使用了不同的日志组件,常用的有log4j, log4j2, logback, common-logging, JUL等,导致日志输出异常混乱。因此日志的输出有必要进行统一配置,而不是针对不同的日志组件分别配置。

因此需要做统一规范:

  • 使用SLF4J作为日志API框架:通过适配各种日志实现的桥接包,接收所有的日志请求。
  • 使用logback作为最终的唯一日志实现,处理SLF4J收集的所有日志

因此为了统一规范日志的记录,及方便日后扩展,通过抽象接口对日志记录进行了封装。

然后在具体项目统一使用:

代码语言:javascript
复制
import com.xxx.framework.logs.Logger;
import com.xxx.framework.logs.LoggerFactory;

private static final Logger logger = LoggerFactory.getLogger(xxController.class);

3、restFull接口规范:

采用的微服务框架,前后端分离,前端和后端进行交互,前端按照约定请求URL路径,并传入相关参数,后端服务器接收请求,进行业务处理,返回数据给前端。

为了提高团队间接口对接的效率,需要做前后端交互的格式规范。一般统一的规范如下:

1、请求格式规范:建议使用json body格式,传入参数包含公共请求头的要求(如:app_version,api_version,device等)。

2、返回格式规范:

JSON体方式,定义如下:

代码语言:javascript
复制
{
   code:integer,#返回状态码	
   message:string,#返回信息描述,直接展示友好用户提示信息
   error:string,#错误描述信息,方便开发直接定位
   data:object #返回值
}

code状态码:我们可以参考http状态设计:

代码语言:javascript
复制
HTTP状态码:
200 - 请求成功
301 - 资源(网页等)被永久转移到其它URL
404 - 请求的资源(网页等)不存在
500 - 内部服务器错误

分类的好处就把错误类型归类到某个区间内,如果区间不够,可以设计成4位数。

代码语言:javascript
复制
#900~999   区间表示系统异常错误
#1000~1999 区间表示用户模块1错误
#2000~2999 区间表示用户模块2错误

这样前端开发人员在得到返回值后,根据状态码就可以知道,大概什么错误,再根据message相关的信息描述,可以快速定位。

简单实现,这里我是为兼容旧项目,不得使用status代替code,这个无关紧要,只要规范统一旧可以。

代码语言:javascript
复制
@Data
public class RestVO<T> {

    private int status = 0;
    private String msg = "success";
    //前端不展示,方便开发检查。
    private String error;
    private T data;

    public RestVO() {
    }

    public RestVO(T data) {
        this.data = data;
    }

    public RestVO(int code, String msg) {
        this.status = code;
        this.msg = msg;
    }

    public RestVO(int code, String msg, T data) {
        this.status = code;
        this.msg = msg;
        this.data = data;
    }

    public RestVO(RestCode restCode) {
        this.status = restCode.getCode();
        this.msg = restCode.getMsg();
    }

    public RestVO(RestCode restCode, String error) {
        this.status = restCode.getCode();
        this.msg = restCode.getMsg();
        this.error = error;
    }
}

4、异常处理统一规范:

统一异常处理需要依赖rest接口格式规范。

基础框架组件需要对异常进行统一处理,规范异常处理的行为。这样各个具体项目基于这个框架组建开,减少重复造轮子。

具体实现:

Spring学习笔记(9)一springMVC全局异常处理_黄规速博客:学如逆水行舟,不进则退-CSDN博客_springmvc全局异常处理

5、参数校验

参数校验主要是定义一些注解实现请求参数校验和格式化

1、示例1:@RegionFormat(地区格式化):

被@RegionFormat注解的属性,会接受一个地区id转换为地区对象。

代码语言:javascript
复制
@RegionFormat
private Region region;

上述注解假设如下请求:

xxx?region=3

则会将id为1的地区及其父的信息读取并形成Region对象

例如region=3的地区为长安街,父辈为为东城区-->北京,刚形成的Region对象数据如下:

代码语言:javascript
复制
{
    "cityId": 2,
    "townId": 0,
    "countyId": 3,
    "provinceId": 1,
    "province": "长安街",
    "county": "东城区",
    "city": "北京市",
    "town": ""
}

2、@Mobile (手机格式校验)

使用@Mobile注解可以校验手机号码的正确性。

使用:在声明的对象手机号码属性上面加@Mobile

代码语言:javascript
复制
 @Mobile
 private String mobile;

如果校验失败会抛出如下异常:

代码语言:javascript
复制
{
  "code": "004",
  "message": "手机号码格式不正确"
}

6、安全处理机制

代码语言:javascript
复制
主要是防xss攻击的一些措施。例如防xss攻击过滤。

7、api文档

代码语言:javascript
复制
使用Swagger2做api文档,同时封装Swagger配置基类:
代码语言:javascript
复制
public abstract class AbstractSwagger2 {

    /**
     * 构建认证token参数
     *
     * @return token参数
     */
    protected List<Parameter> buildParameter() {

        ParameterBuilder tokenPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<Parameter>();
//       tokenPar.name("sign").description("sign").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
//       pars.add(tokenPar.build());
        return pars;
    }

}

待续... ...

8、基础应用配置。

9、模型统一规范格式。

10、一些基础工具类:比如项目使用获取ip,邮箱、手机号等校验。

11、单元测试规范。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、框架和组件
    • 1、框架主要有两特性:
      • 2、使用框架的目的:
        • 3、组件化
        • 二、组件化之基础应用框架/脚手架
        • 三、基础应用框架说明
          • 1、基础组件和依赖统一规范管理:
            • 2、日志组件统一规范:
              • 3、restFull接口规范:
                • 4、异常处理统一规范:
                  • 5、参数校验
                    • 6、安全处理机制
                      • 7、api文档
                      相关产品与服务
                      Prowork 团队协同
                      ProWork 团队协同(以下简称 ProWork )是便捷高效的协同平台,为团队中的不同角色提供支持。团队成员可以通过日历、清单来规划每⽇的工作,同时管理者也可以通过统计报表随时掌握团队状况。ProWork 摒弃了僵化的流程,通过灵活轻量的任务管理体系,满足不同团队的实际情况,目前 ProWork 所有功能均可免费使用。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档