文档章节

不用框架也能编码

Napierfyu
 Napierfyu
发布于 2017/07/12 15:57
字数 1504
阅读 9
收藏 0
点赞 0
评论 0

 

本文来自“优才网”,关注更多程序员技能提升资料,请观众“优才网”公众号。

 

没有框架你编写代码还能又快又高效吗?像这样的试验证明了:你能。但是你应该这么做吗?

 

我已经在一个令人愉快的项目上工作一段时间了,这个项目很小,小到让我感到可以为所欲为,氮素呢?它又很大,大到能够看到我的想法所产生的效用。通过这个项目我实施的一个试验是:我能不能不用任何主要的框架去做它呢?这会花去更多的时间吗?它会相当困难吗?

 

方 法

 

很显然,这里摆出的观点并不新颖而且很多人都认为这是开发软件的正确途径。因此,如果你熟悉依赖反转的概念或者使用很多小程序库(libraries)来代替一个大框架,那么这个部分就对你不会有太大的启发了。

 

正如我已经在上一段落中暗示的,我决心着重依靠依赖反转原理,不管我在这个过程中铺设了多少额外的具有“基础设施”作用的代码,那都是为了适应我的所需,而不是为了别的什么。

 

为了更明确一些,对于任何一种正常来说可能被一种框架提供的代码,我将以一个描述我的实际的、目前的需求为目的的接口(interface)开始。一旦接口设计完成了,我将在我的应用的基础设施层面来使它生效。就本质上来说,我进入了一个圈圈,我发明某种被称为梦想API的东西来解决问题,然后呢我再做可以接入API的应用。

 

package stupid.jokes;
interface Dreamable {
  Lots<Money> makeHappy(Customer customer);
}

 

因为我在这个项目上是有很确定的截止日期的,所以我把这些接口看作是防止时间表问题出现的备用计划。如果发生任何失误,我可能会尝试引入重量级的防身武器(比如Spring)以及用它使接口生效。

 

只要时间表或者我低水平的编程技巧没有什么问题,我决心继续用(相对来说)小的程序库(libraries)以及自己编写一些重要的代码块。

 

举例:REST 端点

 

我猜用于暴露REST端点的代码是一个特别好的功能的案例,这个功能一般会被诸如Spring、 Ratpack这类的框架所提供。我也觉得它会是这个post的好案例,作为定义端点的很酷的方法,当你选择一个框架的时候,这是一件重要的事情。

 

在这个事例中,我的“梦想API”十分简单。它要求基础设施层来执行两个接口以及定义两个额外的类型别名(我们在Kotlin世界中)。

 

interface Router {
    fun get(path: String, action: Handler)
    fun post(path: String, action: Handler)
    fun put(path: String, action: Handler)
    fun delete(path: String, action: Handler)
}
interface Request {
    fun body(): String
    fun <T : Any> body(clazz: KClass<T>): T
    fun pathParam(name: String): String
    fun queryParam(name: String): String
}
typealias Response = (Any) -> Unit
typealias Handler = (Request, Response) -> Unit

 

很明显,我没有立即写下全部这些。我一个特征接一个特征,一个方法接一个方法地去迭代它。如果我记得正确,我的第一个端点只是请求“post”支持和一个请求体。

 

在应用启动过程中,Router安装启用的一个实例是传递一个方法,这个方法对应用中的所有路由的初始化负责。

 

fun init(router: Router) {
    router.get("/groups/:id/members") { req, res ->
        val groupId = req.pathParam("id")
        val members = findMembers(groupId)
        res.invoke(members)
    }
    router.post("/groups/:id/members") { req, _ ->
        val groupId = req.pathParam("id")
        val studentToAdd = req.body(StudentToAdd::class)
        addMember(groupId, studentToAdd)
    }
    router.get("/groups/:id/lessons") { req, res ->
        val groupId = req.pathParam("id")
        val lessons = findLessons(groupId)
        res.invoke(lessons)
    }
    router.post("/groups/:id/lessons") { req, _ ->
        val groupId = req.pathParam("id")
        val lessonToAdd = req.body(LessonToAdd::class)
        addLesson(groupId, lessonToAdd)
    }
    // etc.
}

 

这里,你的观点可能有所不同,但是我真的认为这是一片令人愉快的API。最重要的事情是它可以做我需要的一切来服务于这个应用的特殊使用案例。

 

现在,因为一些好的理由,我并不真的想要展示这里所执行的全部,但是我愿意让你知道这其实比很多人想象的要简单得多。

 

例如,使用Servlet API来处理路径参数的一个简单机制是分裂字符串的事件和遍历URI。

 

fun parse(req: HttpServletRequest): Request {
    val uriParts = req.requestURI.split("/")
    val pathParts = path.split("/")
    val pathParams = mutableMapOf<String, String>()
    for (i in pathParts.indices) {
        if (pathParts[i].startsWith(":")) {
            val key = pathParts[i].replace(":", "")
            pathParams.put(key, uriParts[i])
        }
    }
    return ParsedRequest(req, pathParams)
}

 

另一个来自你的应用与揭露REST端点相关的例子是启动一个嵌入式web服务器。一些人也会因为像Spring Boot这样的框架有这个功能而开心,即使你亲自启动这个服务器看起来真的是小菜一碟。

 

fun main(args: Array<String>) {
    val server = Server(8080)
    server.handler = HandlerList(routerServletHandler())
    server.start()
    server.join()
}
private fun routerServletHandler(): ServletHandler {
    val servletHandler = ServletHandler()
    servletHandler.addServletWithMapping(RouterServlet::class.java, "/*")
    return servletHandler
}

结 束

很高兴我的小试验很成功而且应用没有用任何主要的框架就按时交付了。我也很高兴用这种方式写应用并没有多煎熬。相反,我一直乐在其中,而且我没有因为没使用一些流行的框架而速度慢下来。

 

除了乐趣,我不确定在这个试验中是否还有什么重要的课题。首先,我一直问自己,为什么我们这些开发者要盲从那些夸大其词的框架,尤其是当这些框架并不能多有用时。另外,有没有什么方法能够彻底改造我们开始启动的每个项目的“轮胎”呢,尤其是当我们拥有众多的微服务的时候。

© 著作权归作者所有

共有 人打赏支持
Napierfyu
粉丝 0
博文 3
码字总数 4321
作品 0
海淀
YMP v1.0 发布,轻量级 Web 开发框架

轻量级的Web应用开发框架YMP正式发布v1.0版本! 在经历了近一年时间实际公司项目环境下测试和迭代,优化和修复了若干问题,提高YMP框架代码的成熟度和稳定性。变更详情点击:http://git.oschi...

有理想的鱼
2014/10/25
4.2K
15
什么时候开发人员需要PHP框架

什么时候开发人员需要PHP框架 什么时候我需要使用PHP框架 无论您是一个经验丰富的开发人员,还是一个初级开发者都会面临这个问题,什么时候我需要使用到PHP框架? 当然缮在每当你需要它的时候...

carol_openbiz
2013/02/19
0
0
Yii框架里关于编码的问题,请知道的前辈不吝赐教

是这样的。 我的前端HTML,声明编码是UTF-8,网页运行UTF_8良好 然后我不用YII框架,进行PHP试编写的时候:网页运行UTF_8良好 然后我现在再用YII框架,莫名其妙的变成了GB-2312..... 有没有前...

崩子皆蔓
2013/12/15
302
2
开源中国春节前最后一波招聘,我们送开源内裤的

开源中国继续招聘 Java 工程师、Ruby 工程师和编辑人才: Java 工程师要求: 对学历没要求,而且不要求你会 Spring、Struts 和 Hibernate 等这些框架。热爱编码,Java 基本功扎实。 Ruby 工程...

oschina
2015/01/09
12.3K
183
RDIFramework.NET平台代码生成器V3.2版本全新发布-更新于2017-02-27(提供下载-免费使用)

  回顾V3.1版本更新内容如下:   1、增加对Oracle表创建语句的查看。   2、新增对MySql的代码生成支持。   3、全面重构对多线程的支持,改变以前会无故退出的现象。   本次在V3.1版...

80368704
06/29
0
0
为什么编码规范里要求每行代码不超过80个字符

也许在Python编码风格指导(PEP8)中最有争议的一部分要数每行代码不超过80个字符的限制。没错,实际上是79个字符,但我使用80个字符,这个大概数,它是给程序员的一个参考值。 古老的VT100终端...

oschina
2013/04/09
10K
40
COLING 2018 最佳论文解读:序列标注经典模型复现

本期推荐的论文笔记来自 PaperWeekly 社区用户 @handsome。这篇论文是 COLING 2018 的 Most reproducible Paper。作者用 PyTorch 实现了一个统一的序列标注框架,重现了 CoNLL 2003 English...

技术小能手
07/03
0
0
应用系统快速开发平台--ErpCore

ErpCore是一套强大的云计算ERP开发框架,集数据库设计、软件建模、模型自动生成、界面可视化设计、业务流可自定义、全自动生成用户所需系统于一体。在此框架上扩展出所有行业的业务系统,它让...

8088net
2011/08/15
20K
3
清华大学提出SA-VAE框架,通过单样本/少样本学习生成任意风格的汉字

近日,清华大学提出了一种风格感知变分自编码器(SA-VAE),通过引入先验知识,结合少量的样本学习,可以有效地将汉字分解成内容部分和风格部分,使我们能快速而自由地生成期望风格的汉字。 ...

uwr44uouqcnsuqb60zk2
01/02
0
0
学界 | 清华大学提出SA-VAE框架,通过单样本/少样本学习生成任意风格的汉字

  选自arXiv   作者:Danyang Sun等   机器之心编译   参与:Nurhachu Null、刘晓坤      近日,清华大学提出了一种风格感知变分自编码器(SA-VAE),通过引入先验知识,结合少量...

机器之心
01/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

联动滑动之一:NestScrollChild和NestedScrollingParent

NestScrollChild和NestedScrollingParent 吐槽一下开源中国竟然标题字数有限制 由于项目中使用了CoordinateLayout来解决联动以及实现炫酷的UI效果,那么必须就要研究一波源码了,毕竟知其然知...

JerryLin123
18分钟前
0
0
cloudera spark2.2 读写hbase

cloudera spark2.2 读写hbase 例子 host = 'bigdata-03,bigdata-05,bigdata-04'conf = { "hbase.zookeeper.quorum": host, "hbase.mapreduce.inputtable": "student1"}k......

osenlin
23分钟前
0
0
数据库规范化

转载自 一个小时学会MySQL数据库 地址:http://www.cnblogs.com/best/p/6517755.html 截取其中 1.4 部分 用于自己学习使用 感谢作者:张果 1.4、数据库规范化 经过一系列的步骤,我们现在终于...

十万猛虎下画山
23分钟前
0
0
ios逆向之工具篇

Reveal:查看任意app的UI结构 注:1.不越狱的手机,可以用Reveal来查看自己app的UI结构,不能查看其它app的结构。 2.越狱手机上可以查看任意app的UI结构。 IDA:反编译工具 从App Store下载的...

HeroHY
24分钟前
0
0
EOS区块链平台智能合约示例HelloWorld

我们将介绍一个使用EOS智能合约构建hello World的例子。 一般环境设置通过上一篇文章已经说明,这方面的问题大家可以看本博客上一篇文章,本文引用了官方EOS在Git上的示例。 运行nodeos 要通...

笔阁
26分钟前
0
0
Scrapy爬虫框架简单解析 

scrapy框架解析 Scrapy框架大致包括以下几个组件:Scrapy Engine、Spiders、Scheduler、Item Pipeline、Downloader; 组件 Scrapy Engine 这是框架的核心,负责控制数据流在整个系统的各个组...

zhujun2017
27分钟前
0
0
Vue之ref详解与实例

尽管存在 prop 和事件,有的时候你仍可能需要在 JavaScript 里直接访问一个子组件。为了达到这个目的,你可以通过 ref 特性为这个子组件赋予一个 ID 引用。ref可以加在父级组件上也可以加在子...

tianyawhl
35分钟前
0
0
Aerospike入坑导读

Aerospike是一个以分布式为核心,T级别大数据高并发的结构化数据存储解决方案,读写操作达微妙级,索引内存化数据固态化,自动感知集群状态,节点间数据强一致性,平滑扩展以及丰富的开发语言...

厉力文武
44分钟前
7
0
基于微信的libco实现php的协程扩展

php扩展cop (兼容php7) git clone https://github.com/qieangel2013/cop 基于libco简单实现的协程/usr/local/php/bin/phpize./configure --with-php-config=/usr/local/php/bin/php-c......

mickelfeng
48分钟前
0
0
Django 01

一 什么是web框架? 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演。 ...

Kefy
48分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部