欢迎来到现实世界
00-1010如果你是一个开发过的客户端程序员,或者是一个前端程序员,你一定听说过MVC MVVM redux vue react的一个或者几个开发模式或者框架.这些模式或者框架总是需要你花很多时间去学习,因为它们制定了很多规则,各种名词,各种限制。这种费用总会在你入门的时候支付。
为什么人们总是做很多框架,然后新框架的新版本不断出来?很多老人都说‘我真的学不会’。尤其是当你换平台或者为多个平台开发的时候,你总是会重新做一个新的框架。这些事情不断重复。你应该想想为什么?这是为什么?为什么用户看不到不同的东西?为什么他们需要几套不同的东西来做?它们不应该有相同的东西吗?
我真的学不会!
00-1010这些框架有什么共同点?他们应该表达同样的东西。应该有一个共同的逻辑,或者目的就在于此。开发游戏、网页、windows客户端、安卓后.等等,作者发现了一个令人震惊的秘密!他们有共同的逻辑!
一个令人惊讶的大秘密
这是所有框架作者都在做的事情。内部逻辑是:‘把UI部分和逻辑部分分开’。只有这样的规则,你才能摆脱所有的框架约束。即使使用新的平台和新的语言,也能写出非常优雅的客户端程序。即使使用其他框架,也会突然明白其中的逻辑,知道如何灵活运用。
无数的框架,让开发人员疲于学习.
https://github.com/fengshihao/XFrame,别担心,最后看看这个项目,继续读下去。为了解释这个常见的逻辑,我们必须回到客户端程序的开头。在计算机时代,当图形界面不存在的时候,计算机程序都是命令行的形式。用户一个字母一个字母地打出相应的命令,告诉程序他想做什么。因此,我们可以得出结论,客户端程序可以独立运行,无需UI。
客户端程序一开始没有UI。
告诉你个惊天秘密,这些框架都有一个内在逻辑!
即使在今天,无论程序有多复杂,都可以设计成无需UI即可运行。例如,git或无头浏览器(一种用于分析动态网页的浏览器,服务器端没有UI)。
命令行下的Git显示提交信息。
没有界面,用户仍然可以只用命令行完成所有的工作,但是比较麻烦。因此,当图形界面操作系统诞生时,它迅速占领了市场。结果,客户端程序的复杂性增加了。尤其是现在的开发者开始学习UI。这就导致了一种错误的直觉,认为UI从一开始就是App的基础,程序刚设计的时候就掺杂了太多的UI代码,使得后续的开发特别。
00-1010如上所述,在程序设计之初,程序的设计没有UI,也没有命令行。事实上,当我们编写程序时,命令行只比API调用短一点点。因此,我们在开始时简单地将程序设计成一堆API。复杂程序是几组API。每个API都有不同的参数。
举个简单的例子。比如用户在没有UI的情况下登录,API调用是这样的。
92e60-6d4c-4f9e-86ba-d7b83f8124d9?from=pc">用户在命令行使用这个app的时候就是 输入类似这样的命令行
login xxx yyy
然后程序会打印登录进程, 然后最终显示成功,或者失败, 然后才可以进行之后的操作. 程序执行的过程中都是阻塞的,用户不能做其他操作.
很显然的一个问题, 当有UI的时候,我们不能让ui阻塞, 得让UI不断地更新程序的运行状态. 这里我们采用观察者模式. 让UI实现一个接口, 这个接口是程序逻辑发生响应事件时回调给UI的. 接口看起来是这样的
有人说这个例子很简单,为啥不用Rx编程. 或者加一个回调函数就解决的问题. 为啥还要定义两个接口这么麻烦. 因为复杂的情况下rx 或者回调函数不能满足需求.
1 有的时候一个API调用会引起多个回调 ,比如下载,会有进度的回调, 成功回调, 失败的回调.
2 接收同一个回调事件的UI元素是多个, 比如一个页面同一个资源,上有两个下载入口(这种情况很常见), 点击一个开始下载后,下载入口就要disable ,然后开始显示下载进度, 然后成功后再把两个入口改为"已下载".
一些UI和逻辑分离的细节
记住最重要的原则: UI 和逻辑分离. 然后考虑每一部分代码是否违反这个原则. 下边的细则都可以推导出来. 关键这些东西都不依赖平台,不依赖语言, 非常容易在各个平台实现. 不需要多少代码. 可以做到无框架客户端开发了.
UI的部分包括: view的显示,隐藏, 布局, 动画, 字体...逻辑部分包括: 所有的IO请求, 网络请求, 数据库访问, 逻辑计算, 状态记录...逻辑实现给用户调用的API 接口, 这些接口都要在UI线程调用.UI实现逻辑层的事件回调, 这些回调接口都在UI线程调用.UI依赖逻辑层代码, 但是逻辑层代码不依赖UI层代码. 这些可以通过自动检测做到. 把他们放到不同的文件夹下,所有UI代码放入ui文件夹, 所有的非UI代码放到logic文件夹下. 两层都会有些纯数据的model, 比如有个User的Model类, 里边有用户名, 头像.... 通常很多开发把逻辑的Model直接给UI使用, 这样是不对的. 不要复用逻辑的Model. 应为两边不是一样的目的, 比如有选中态,这个数据,只在UI这层有用, UI和逻辑需要靠Id来建立两个model的映射. 这点很重要.因为UI和逻辑都是接口的实现, 所以会带来自然而然的好处.
两边都可以很好的被测试, 因为都是接口很容易mock假数据,假case来测试很容实现面向切面编程, 比如在 逻辑API外加一层统计执行时间的代码, 如果超过16ms就报警告,这样很容易发现执行慢的API回调接口包一层做线程检测, 保证所有的UI操作都在UI线程执行,一个以此为指导的框架实现XFrame
XFrame 是为了详细说明上述内容该如何实现做的一个开源项目 https://github.com/fengshihao/XFrame
初衷是传播一种客户端编程的理念. XFrame是这个这种理念的Android上的实现.
为什么不给开发一个框架, 而是强调一个理念. 是因为框架是死的, 细节繁琐不适合人类记忆. 人类大脑适合思考,总结,抽象.
XFrame的代码就是用来表达这个理念的, 希望开发能从中能抽象出 UI代码和Logic代码分开 这么个思想. 如果只是口头介绍或者举例说明这个理念,仍然不够详细,让人不知道如何理解.