-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
高阶的编程模型 #172
Comments
嗯嗯,写的代码越多,发现要重复的地方越多,例如 “我们的工作,其实就是运用调配这些框架代码、编程结构,从原始的输入数据处,产生正确的输出。” -- 通过对代码逻辑的归类和总结,得到的这个结论倒是没有想到过,棒棒的 |
@jkvim 哎,你说我怎么就忘了 这个插件可以生成 React 相关的 template 代码:https://github.com/Minwe/jetbrains-react 。我去搜搜有没有 redux 的。。。 |
哈哈 感觉更高层次的工作,是以代码为数据生成代码,如模板引擎,编译器,解释器等 |
补一个:还有项目本身相关的编程结构,比如数据库存取、API 请求发送、以及特定技术栈在项目上的定制等。需要了解项目时留意。大坑。 |
SICP 只看过两章的人都觉得,受益匪浅 |
@JimmyLv |
@kenpusney 毕业论文想研究 Java 反射。结果发现它里面有一章元编程,并且我根本看不懂 |
@kenpusney 原谅我本科没学过,😂 |
通过一系列「优雅的 Mac」的讨论,我提到这些快捷的本质是为你更快地处理尽可能多的「背景事务」,以使你能够专注在「更重要的事情」上。更重要的事情是什么呢?产出价值。产出代码。这里,我们暂且假定
代码=价值
,那么有两个推论:更遑论,产出的代码本身不一定就100%达到了你要的价值。在业务代码的上下文下,你产出了代码,解决了问题,就是为公司产出了价值。在自己做产品时,写的代码有没有价值,就难说了。因此,更快的产出,才能支持更快的验证、反馈,甚至抛弃,才能作为整个敏捷体系的支撑。代码产出越慢,价值反馈越慢,你能试错的机会越少,机会成本越高。
骨架代码
这个 issue 要谈的是「产出代码」这个事情本身。我发现,即便是在产出代码,你在写的很大一部分代码也不一定是产生了直接价值的代码,比如框架代码,比如基本的控制结构。我把你要写的代码想像成一篇文章,这篇文章应该是有它更高层次的结构的。并且,这个结构与你所写文章的类型——理解为你所用的框架——有直接的关系。打个地方:
render
方法,可能有若干生命周期方法。这些是它的结构、骨架,有了骨架,你再往里填东西就是了class MyClass { ... }
。里面可能有若干方法。这些是它的结构、骨架,有了骨架,再往方法里填东西就是了describe('', () => { it('', () => {}) })
这样 的骨架,一个测试里,一定有given
(准备数据)、when
(调用方法)、then
(验证返回)三个部分。有了骨架,你再往方法里填东西就是了可以看到,这些代码,都不一定是有价值的代码。你所写真正的代码,应该是那些骨架里的函数、方法里的那些代码。骨架代码,生成就行了。这是我要提的第一个点,骨架代码生成。说白了,就是这样一个 API:
基本控制结构
好,我们真正要写的就是那些骨架里的函数方法代码。但是莫急!这些函数里面,依然不需要你去写的所有的代码,我们还有更为基本的组件。那,就是我们经典的三大编程结构:
statement
、if-else
、while
。顺序结构、条件结构、循环结构。各种结构有变体,不妨碍使用,而且为了减少记忆负担,尽量只用一种可应对万能情况的结构。细细拆分下来,顺序结构里面,一般是 变量计算、API 调用 与 赋值 等,本质都是通过计算和请求获得可供下步计算或返回的 数据;循环结构,其实在 JS 这种特定语言里,又可以使用函数式编程来代替。所以,我们在实现函数或代码的时候,可用的编程结构分列如下:
statement
$.ajax()
、fetch()
不同的 API 语法不同,你用 HTTP 请求与用 FTP 请求需要的协议参数又可能不同),但它又有共通的接口,如都需要你传入url
、settings(optional)
、回调等。其实又有一个编程结构的 API:generateAPICode(...techStack, url, settings, params, successCallback, errorCallback)
if-else
switch
。generateConditionComponent(condition, ...opeartions)
。这个 Intellij 里也已有if
这样的 live templatewhile
。generateLoopComponent(startCondition, stopCondition, accumulateCondition, operations)
。对于数组来说,这样的循环则可进一步简化为高阶函数式编程,现已有完美支持:array.map()
、array.filter()
、array.reduce()
、array.find()
、array.any()
等理解了这些,其实编程产生的直接价值,真正需要你的东西,除了把代码写好让人容易理解到极致之外,就只是输入数据了。我们的工作,其实就是运用调配这些框架代码、编程结构,从原始的输入数据处,产生正确的输出。如是而已。中间调配过程,能越快完成越好。
实践落地
说了那么多,怎么落地呢!?
Mindset
思维转换。比如要 TDD,就要先把思维切换到 任务分解、快速反馈验证 这样的工作论上来;这种编程模型,本质是把代码做从上至下的组件划分,从框架性的最高层组件,到下面的结构组件,通过分离组件模板代码和真正需要我们编写的代码,尽量剔除无用的工作。新的思维模型会出来,正是因为以往直白的直觉思维,已经无法高效应对更复杂的问题。因此,尝试、辩证、质询看待一种新的思维方式,才是成长式的思维嘛。
真的要落地了
自己撸一个。核心代码尽量做成可复用的 API,这样不同的编辑器插件只需依照不同的模板集成就行了。就像 JUnit 5 分离出一个 jupital-core 的核心包出来一样,以后即可适应 gradle runner, maven runner, Intellij plugin, Eclipse plugin 等等不同的三方插件了。
API
举个非常简单的🌰:
这个16行的 React 类里,其实真正需要我们写的,只有打了星号的部分,仅3行 + 2个变量名,也就是 类名、传入参数、组件
render
方法真正要做的事,其他的什么class xxx extends React.Component
、render()
等都是 ES6+React这个技术栈本身所需要的骨架结构,完全可以一键生成;map
是实现过程中使用到的循环结构;html 这些,甚至可以用 emmet 这样的工具插件来完成。emmet 这个工具其实也是一样的思想,HTML 的标签都是模板,尽量生成就好,手撸个啥,HTML 页面真正需要你写的,就是把传入的数据展示出来,如是而已。按
实际产出 / (实际产出 + 框架代码 + 基本编程结构)
这个公式来看,写一个16行的类,不产生直接价值、可通过模板生成的代码有75%。好在,在 React 上,现在真的有 Intellij 插件完成这个事情了。剩下我们自己真正做的,真的就只有对输入的处理逻辑,这是我们最应该专注的地方。
The text was updated successfully, but these errors were encountered: