2019独角兽企业重金招聘Python工程师标准>>>

设计软件有两种方法:一种是简单到明显没有缺陷,另外一种复杂到缺陷不那么明显。 --托尼.霍尔

5.1.1 前言

在软件工程这一学科和行业里,关于软件工程的解说有很多。有人说开发是一门艺术;有人说开发是一种技艺;也有人说开发是一门哲学。但个人认同从实用主义和理性的角度去理解。

例如一个框架,我们之所以认为它好是因为我们发现这个框架遵循了编程规范、适当地使用了设计模式、巧妙地结合了设计原则、有着稳定的依赖、代码复杂度低、并且有着很高代码覆盖率的单元测试等等。

也就是说,好的框架都是可以被解释的。既然可以被解释量化,也就可以学习、参考和借鉴。

5.1.2 共性和可变性分析

关于共性和可变性分析,在《设计模式解析》一书中有着非常到位的讲解。

CVA是一种很容易的理念,按我的理解即: 抽离共性、隔离变化 。有点类似易经里面的“变”与“不变”。

诚然,在过去的教育中(包括大学在内的),对于软件开发都着重谈论面向对象开发,即OOD,以致于很多人都对面向对象开发产生了很大的误解。而这种误解所带来的实际情况就是: 我们都在进行面向对象开发,但却是标准呆板的面向对象开发,缺少生气,缺少活力

很多人,都没有把我们开发人员作为专业人士看待,甚至连我们自己都否认我们是专业的。所以很多时候当产品提出需求时,我们提供的开发周期往往会被外界以讲价的方式削减。何以?为什么医生给出的手术时间病人没有讨价呢?因为很简单,在病人的眼里,医生是专业的。

若我们也想达到专业的层次时,何以为?学习、思考和实践,我认为至少这三者是必不可少的。

所以,当我们在对PhalApi进行设计时,我们进行了一次又一次地酝酿、尝试、思考。我们在思考:这些功能是否真的会在实际项目中被使用?开发人员是否可能很好地进行扩展?此种决策是否便于单元测试、从思路上减少代码异味?。。。

我们谨记敏捷开发,不过度设计。但我们也确实需要一种思想上的指导。正好,我们看到了 共性和可变性的分析(commonality and variability analysis, CVA)

5.1.3 CVA和三种视角、抽象类之间的关系

引用一下《设计模式解析》一书中的图表:

在这种理念的指导下,我们会更愿意将接口开发过程的共性抽离统一起来,而可变性部分的则可以由开发人员根据不同的项目情况进行快速定制实现。

5.1.4 不稳定性与抽象度分布

除了常谈及到的“低耦合、高内聚”外,在对代码进行静态分析和衡量其可维护度时,还有一个值得注意的值,即:不稳定的度量。

不稳定的度量可以根据以下公式计算获得:

I = 离心耦合 / (离心耦合 + 向心耦合)

因此从宏观上,我们的代码结构,从上层到下层,应该向着稳定的方向递增,也就是说越底层越应稳定。对应 稳定依赖原则的规则(SDP),包之间的依赖应该朝着稳定的方向:不稳定的包应该依赖于更稳定的包。

又结合不稳定性与抽象分布图,我们PhalApi框架的代码 应该大部分分布在上图中的抽象稳定区以实现框架高层的建设、少部分分布在具体不稳定区以提供一些基础的功能

5.1.5 创建和使用分离

在框架的特性中,包括:可重用、IoC Container以及SOLID五条原则的运用等。这里就部分SOLID原则的运用简单说明一下。

(1)S:单一职责原则

这是我们一直都坚持遵守的原则,因为,我们也坚持 短而美 的写法, 致力于编写优雅的代码、编写人容易理解的代码

(2)O:开放-封闭原则

我们首先希望的是在进行接口开发过程中,当需要新增一个接口时是开放的,对已有的响应调用流程是封闭的。即我们只需要实现新接口逻辑即可,不需要改动其他过程的调用。因此在OCP原则的指导下,我们通过结合工厂方法封装了对接口的初始化和调用。

(3)D:依赖倒置原则

PhalApi框架,最大的特色莫过于 它提供了一种如何快速进行接口开发的机制,但它不强制你使用不必要的功能,甚至它还鼓励你通过它来尝试研发自己的框架 。更进一步,PhalApi引入了新颖明确的概念,一如服务。我们把客户端调用的接口称之为接口服务,把服务端用到的资源称之为资源服务。对于后者,PhalApi提供了灵活的DI机制,以支持各项目定制化的开发。

5.1.6 PhalApi核心架构图

显然,到目前为止,从核心架构图所折射出PhalApi的结构和代码是如此的 简单明了、统一规范。至少我是这么认为的,也是一直这样努力的。

从上图的核心架构图可以看出,中间红色部分的DI处于汇点位置,提供各种资源服务的定位、创建、管理和提供。

而左上角的代码示例则表达本系统框架运行的主流程: 创建一个接口实例,运行响应

右上解黄色部分则为多变的接口应用开发的代码,这里特意罗列了两组接口,意在表明可以在此框架下挂靠多套接口。

最下面是接口开发过程中所用到的各种基础设施和技术,如日记、配置读取、缓存、加密、请求和响应等。同样,除各应用项目中形式多变的接口开发外,这 块的底层技术亦支撑不一而足的需求。因为,PhalApi只是作了共性的抽离,即提供一级抽象且稳定的接口或者抽象类,以约定规约视角中接口的函数签名, 不作过多的具体实现。同时以DI作为辅助,支持快速扩展。

5.1.7 PhalApi核心执行流程

和其他框架不同,除了有文档对基本使用有说明外,我们还提供了我们框架核心的设计和思想,以便大家洞明其中的原理从而进一步优化扩展。

这里,扼要说明一下PhalApi框架中接口请求背后的核心执行流程。

从上图的时序图中可以看出,在PhalApi中,一个接口的请求处理,只要分为两个环节: 接口服务初始化接口服务调用

(1)接口服务初始化

在Web Service中,往往需要对服务进行注册发布后,才能开放请求。这里免去这一层,但遵循 创建和使用分离 的原则,我们将接口服务的初始化进行了封装,以便可以统一进行初始化、异常处理和一些权限ACL的控制

,甚至接口访问的统计等操作,更为重要的是接口开发人员可以进行无绪开发,而不需要过多知道如何合法创建接口服务。

在1.2. 步骤中,UML时序图中的::generateService()表示对静态函数的调用,即对应代码:

PhalApi_ApiFactory::generateService();

随后,可以看到(假设我们这次请求的服务为:?service=Demo.DoSth),我们创建了一个指定接口的实例(此接口类须继承于PhalApi_Api基类),并以变量a返回实例。

如果请求的服务非法,则会以 400非法请求 返回给客户端。而正确创建接口服务a后,则会进行接口的初始化,其中有接口参数规则的解析和注册了过滤器服务后的检测操作。

当这一系列的操作都成功执行后,我们将会得到一个接口服务实例a返回。
因此,在接口服务的创建过程中,我们没有过多地限制,而是预留了很大的空间给到接口项目定制开发。

至此,接口服务的创建完成。

(2)接口服务调用

在完成复杂的创建工作后,客户端(备注:这里指的是服务端开发的开发客户端)只需要简单调用需要进行的操作即可。

而这一块,则需要接口项目具体开发实现,也是我们项目级的核心部分。

在获取接口服务的背后,我们建议结合领域驱动设计的理念,对项目代码进行这样的层级划分:

  • Api接口层:用于接收参数并响应接口的请求;

  • Domain领域层:用于处理复杂的领域业务逻辑,保证规则只出现一次;

  • Model数据源层:更广义上的Model层,提供数据来源,不限于DB;

最后,是我们客户端关心的返回格式。  默认情况下,我们都是以JSON格式返回的,但仍然可以轻松支持其他格式的返回,如JSONP、XML等。只需要简单地开发实现,然后重新注册即可。

至此,接口服务的调用完毕。

5.1.8 DI支持下的轻松扩展

当使用一个开源框架时,我们既喜欢其强大的一面,但矛盾的同时我们又害怕其中的复杂性,原因莫过于:学习成本高、出现问题时怕驾驭不了。

而在这里,在PhalApi这里,这一切都是这么简单,简单地又如此明了。

当需要进行资源服务的扩展时,我们可以:

实现自己需要的服务

实现指定资源服务在规约视角约定的接口,假设我们需要用文件来当作新的缓存存储。则需:

class MyCache_File implements PhalApi_Cache {public function set($key, $value, $expire = 600) {//...}public function get($key) {//...}public function delete($key) {//...}
}

在入口重新注册

当实现自己的功能后,只需要简单地在入口文件重新注册即可。如:

DI()->cache = new MyCache_File();

最后,另人兴奋的是,原来全部的调用代码都不需要改动,即可享受后期调整升级后的新功能!完全避免了曾经那种“牵一发而动全身”的痛苦。并且,定制开发出来的实现类,还可以跨越业务在其他项目中共用。

这不正是我们常常所说的代码重用吗?而如今,我们很优雅地做到了!

然而,我们在实际开发中收获到的远远不是代码重用这么简单,而是一种更好的开发实践。因为通过DI使得创建和使用分离,所以我们可以让高级的开发同 学实现服务功能的开发,然后再提供给普通的开发同学使用,新手亦然,因为对他们来说:会用就行。当然,对于高级的同学,还应该遵循开发的最佳实践,坚持单 元测试,以保证我们提供了可靠的接口(广义上的接口,非HTTP请求的接口)给我们的“客户端”使用。

若如此,我们的开发合作岂不是很更合理、更明朗、更愉快?哈哈,我想是的。

转载于:https://my.oschina.net/dogstar/blog/377987

[5.1] 架构与思想:Phal Api核心设计和思想解读相关推荐

  1. 架构必备「RESTful API」设计技巧经验总结

    转载自   架构必备「RESTful API」设计技巧经验总结 [译者注]本文是作者在自己的工作经验中总结出来的RESTful API设计技巧,虽然部分技巧仍有争议,但总体来说还是有一定的参考价值的. ...

  2. OLTP 系统和 OLAP 系统的核心设计思想

    关于 OLTP 系统和 OLAP 系统的核心设计思想 数据存储系统的关于查询的典型操作: -- 第一种需求: 根据 key(1) 找 value(name,age), 单点查询 select name ...

  3. onmounted vue3_Vue3.x 生命周期 和 Composition API 核心语法理解

    1 Vue2.x 生命周期回顾 beforeCreate,在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用. created,在实例创建完 ...

  4. BigData之Hadoop:Hadoop框架(分布式系统基础架构)的简介(两大核心【HDFS存储和MapReduce计算】)、深入理解、下载、案例应用之详细攻略

    BigData之Hadoop:Hadoop框架(分布式系统基础架构)的简介(两大核心[HDFS存储和MapReduce计算]).深入理解.下载.案例应用之详细攻略 目录 Hadoop的简介(分布式系统 ...

  5. Nacos 1.0.0 GA,架构、功能与 API 设计全面重构

    Nacos 1.0.0 GA 版本发布了,此版本在架构.功能和 API 设计上进行了全方位的重构和升级. 此版本新特性包括: 注册实例支持 ephemeral 字段 Nacos 1.0.0 版本在 i ...

  6. mysql核心数据库_从MySQL基础进军MySQL核心架构 178集MySQL数据库核心基础视频教程 MySQL基础案例教程...

    从MySQL基础进军MySQL核心架构 178集MySQL数据库核心基础视频教程 MySQL基础案例教程 课程目录 (1) 01MySQL基础_课程引入.avi (2) 02MySQL基础_为什么学习 ...

  7. 计算机设计核心思想,科学网—计算机设计的两种理念,颠覆os的计算机 - 姜咏江的博文...

    计算机设计的两种理念 姜咏江 关于图灵和冯·诺伊曼计算机,我们是否可以总结为图灵的计算机思想由冯·诺伊曼等人具体实现了?不要让计算机历史上那些说不十分清楚的问题,耽误了我们今天的行程. 在计算机体系结 ...

  8. 从零学习 InfiniBand-network架构(三) —— IB核心传输引擎Queue Pair

    从零学习 InfiniBand-network架构(三) -- IB核心传输引擎Queue Pair

  9. DDD的创新思想:开发即设计思想

    领域驱动设计(DDD)和微服务架构(MSA)近年来非常火热,尤其是在互联网公司的生产实践过程中.微服务架构为互联网公司自身业务的发展壮大提供了技术支撑,日渐显现出解决复杂业务需求的威力.更多的IT公司 ...

最新文章

  1. 设置RGBColor
  2. keil5软件仿真出现unknown signal解决方法。
  3. mysql galera cluster实现vip_2019年学MySQL,最佳的10本新书
  4. Java中多态(向上转型)机制
  5. 一名新晋程序员的自述:我的编程自学之路
  6. Flutter之Container
  7. Maven私服Nexus搭建
  8. UI设计干货素材|网页设计巧妙使用背景纹理
  9. PAYPAL 支付,sandbox测试的时候遇到异常:请求被中止: 未能创建 SSL/TLS 安全通道,以及解决方法。
  10. Hybrid端口配置理解
  11. matlab b超分类,MATLAB R2019b超详细安装教程
  12. vue中使用富文本编辑器
  13. linux消息队列优缺点,linux消息队列概念
  14. MySQL 系统自带的数据库有哪些?每个数据库的作用是什么?
  15. 思科模拟器8.1版本身份验证失败禁用网络解决
  16. mysql 创建数据列表
  17. IE浏览器低版本判断及升级提示
  18. SNA中:中心度及中心势诠释(不完整代码)
  19. 聊聊常见的服务(接口)认证授权
  20. python开发程序知道微信好友是否已读信息吗_基于Python+adb实现微信是否好友检测...

热门文章

  1. c罗python可视化分析_鸟枪换炮,利用python3对球员做大数据降维(因子分析得分),为C罗找到合格僚机...
  2. Kubernetes - CPU 单位
  3. 【无标题】CCSRP是网络与信息安全应急人员认证(现更名为CCSC)
  4. C++8/23——仿照string类,写一个my_string类
  5. 菜孔孔学python--列表
  6. 针对运行JSP文件后网页自动下载的解决办法
  7. Unity基础:文本框、图片自适应(ContentSizeFitter、VerticalLayoutGroup等组件的使用)
  8. 20220211关于TL-WDN6200(RTL8812AU)在ubuntu20.04.3下安装驱动程序的历险记
  9. 博客的开始,我的大学
  10. java将数据写入excel_java将数据写入excel