从0开始搭建编程框架——思考

Posted breaksoftware

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从0开始搭建编程框架——思考相关的知识,希望对你有一定的参考价值。

        需求来源于问题。(转载请指明出于breaksoftware的csdn博客)

        之前有个人做前端开发的同学在群里问“C语言能做什么?能写网页么?”,然后大家就开始基于这个问题展开争辩。有的认为是“不能,从来没听说过C语言能写网页”;有的说“能,连浏览器都是C写的”。我想这是基于不同层面做出的回答。如果仅仅从语言层面来说,C的确写不出网页。但是从底层来说,C语言是可以做到的——大不了它自己设计一套描述语言来描述网页。

        但是又有几个人会尝试使用C语言去定制一个浏览器内核并绘制“网页”呢?

        所以我们不可能找到一项可以胜任所有场景的技术,于是“在一定的场景下,php是最好的语言”可能并不是一个笑话。

        我们工作也掺杂着很多的场景,这些场景包括:同事技术栈和基础知识功底,业务特征和资源消耗类型及难点等。

        举个例子。记得之前看过一篇Go语言之父Rob Pike讲述的关于golang诞生历程的文章(原文:https://commandcenter.blogspot.com/2012/06/less-is-exponentially-more.html),其中他极尽嘲讽了一下C++的编译速度,以及他认为很奇怪的一些特性。于是在他的预想的场景下,产生了设计新语言的需求。最终我们在golang中的确看到了“简单”这个特点。但是比较讽刺的是,他希望借此吸引C++程序员的愿望并没有达成,但是吸引力很多PHP或者Java语言栈的同学。

        可以见得,有的时候我们发现的问题可能比较明确,解决的方案可能也非常恰当,但是最终可能在另外一个领域或者场景下取得不错的成果。这样的例子还包括最近在人工智能领域大火的Python。

        当一个东西火起来之后,人们就开始思考它是否“放之四海而皆准”。我们在网上看到很多关于golang好不好的争论,个人觉得“只有适不适合”,而不存在“好不好”的问题。

        回到框架设计上面来说。我们需要先定义当前的场景、问题,然后找到一个恰当的方案。

        为了让此系列文章有继续写下去的意义,我假设当前的场景是:

  • 团队成员只有PHP语言基础和经验
  • 团队成员对C/C++了解仅限于大学教程,其他语言不会
  • 团队成员对多线程编程不了解,对操作系统了解很少
  • 项目需要在半个月内完成
  • 项目是CPU密集型网络服务,经调研,在当前资源下PHP不足以支撑
  • 项目的主要特征是网络数据获取并统筹计算,数据量不是很大
  • 不能使用Go语言

        除了最后一点,很多团队可能都会遇到。但是如果没有最后一条,可能这个系列也不存在写下去的意义。

        很显然,希望突击培训成员的C/C++、多线程编程和操作系统基础是不太可能的。即使这么短的时间内可以让大家写出代码,但是代码质量和维护性需要打上大大的问号,这对一个项目管理来说是非常不可控的。

        那怎么办?这个时候可能就需要我们设计一套易于使用的编程框架。它应该

  1. 把各种复杂的问题封装起来,让使用者对其无感。
  2. 可以将复杂的问题化简为团队成员经常面对的问题。

        其中第二点是非常重要的一种抽象,因为当我们人类面临未知问题时,最本能的思路是把它和已解决的问题进行对比。然后对已知方案进行修改和组合,以解决未知问题。

        确定好基本目标后,我们就会面临基础方案的选择问题。以我的经验,这是整个框架设计和开发过程中最最烦躁的过程。因为我们面临着很多种选择,比如

  • 查找各种基础的框架
  • 平行基础框架的性能对比,
  • 平行基础框架的易用性、稳定性和可维护性
  • 我们选择约束什么,约束到什么程度
  • 我们决定放开什么,放开到什么程度

        很多似是而非的问题,很可能没法做到定量分析和对比。于是框架的设计者的经验、偏好和哲学就会发挥作用。

        略掉中间过程,假设我们最终选定brpc作为网络框架(使用见《brpc介绍、编译与使用》)。现在就需要基于它来解决一些设计问题了,我们只以“多线程”这个问题为例。

        让我们的成员熟悉多线程编程?不现实,很多写了很多年的老手也经常在线程同步上栽跟头。

        编写一个线程池?不太好,虽然避开了线程管理的问题,但是还是保留了线程的概念。而且目前场景下,有足够的时间来写一个超越brpc中使用的bthread的库么?

        直接使用brpc中的bthread?不太好。因为可以参见文档(https://github.com/brpc/brpc/blob/master/docs/cn/bthread.md),其中提到一句“你不应该直接调用bthread函数,把这些留给brpc做更好”。

        那怎么解决?回顾之前提到的哲学:将未知问题转化成已知问题。我们是不是可以把每个异步过程看成一次请求呢?

        具体的做法是,服务开启一个内部端口,原来需要独立线程执行的过程变成该端口下的一个服务策略提供服务。

        这样我们就将多线程问题抽象成一个请求,将团队成员未知的问题变成了已知。

        当然,会有很多人提出异议。比如这么做是否最好?参数序列化的代价?不可否认这些都是问题,但是在之前介绍的场景下,这个方案不算差的。

以上是关于从0开始搭建编程框架——思考的主要内容,如果未能解决你的问题,请参考以下文章

从0开始搭建编程框架——插件

从0开始搭建个人博客网站

小白从零开始学编程--python安装与环境搭建

字节7年经验分享,如何从0开始搭建公司自动化测试框架?

从0开始,一起搭框架做项目搭建MVC环境 注册区域

关于技术问题解决方案与服务实际搭建的方案的成本规划问题的思考