• 编程漫谈(十八):编程三境界


    编程三境界: 编码、设计、模型。


    引子

    写一段程序很容易,3 岁小孩都能学会。可是,写一段优雅、简洁、可靠的程序,却不是 3 岁小孩能够搞定的事情。

    编程即是表达逻辑。编程有三个境界:编码、设计、模型。 它们层层递进,难度越来越大,亦标志着编程技艺的三次飞跃性的突破。

    编码

    编码是最基本的逻辑表达活动。不必多加思考,一个普通人花一下午学习编程的基本知识,也能写出一段程序来,只要他能理解“加减乘除”、“如果-那么”,“一直做某件事-直到某个条件不能满足”。

    在真实的软件开发活动中,常见的编码模式是:组装 API 参数、调用 API、获取数据、做一点业务处理、组装 API 参数、调用 API 、获取数据、……

    while (programming career is not over) {
        buildParam;
        callAPI;
        fetchData;
        doBizLogic;
    }
    

    嗯,很多人很长一段时间都做的是这样的工作。然而,做一万小时重复性的事情,只能原地踏步,并不会带来编程技艺上的提升。不进则退。要如何真正的提升技艺呢 ?

    重构是提升编程技艺的一个重要途径。重构意味着重新审视代码,用一种新的方式去理解代码逻辑的实现,追求更简洁更可靠的实现。比如,“精练代码:一次Java函数式编程的重构之旅”,即是用函数式编程的视角,让代码更加简洁,更加可复用。重构得越多,代码越简洁,编程技艺的提升就越快。这是每天写相似的业务代码无法比拟的。因此,重新去审视日常中的每一行代码:

    • 对于冗长的飞流直下三千尺的代码流程,能不能切分成可以正交组合的多个函数,让主流程清晰可见 ?
    • 对于拗口的山路十八弯的判断逻辑,能不能用更清晰的控制结构进行表达 ?
    • 代码读起来和理解起来是否足够流畅 ? 如果不流畅,如何实现更加清晰自然 ?
    • 代码在大量数据下是否有性能问题 ? 如果慢,是否可以通过数据结构和算法进行优化 ?
    • 代码是否可以复用 ?如果难以复用,能否抽离出容易复用的部分,让实现类似需求更加轻松 ?
    • 代码是否可以扩展应对不同需求 ? 如果难以扩展,是否可以将通用和差异分离开,更容易定制化 ?

    重构,最终的目标其实就是让以后的编程工作更加轻松,花更少的时间,拿一样的收入。

    设计

    当持续重构的时候,也在持续地思考和设计。

    代码即设计。设计,即是对现实问题进行抽象,提炼出基本的问题,用简洁的概念去描述和定义,揭示概念之间的关联,发展方法去处理,从而获得简洁优雅的设计
    比如,“从JSON中自动生成对应的对象模型” 即是一例。不是立即着手去编程,而是首先分析对应的数据模型和数据结构,提炼出要素,用设计模式分离不同的关注点,将表示与构建分离。后续要修改时,只要修改相应的一小块即可。

    设计常常通过组件编程来实现。组件是具有一定接口和行为规范的实现。组件可以相互组合,构建更大的组件和子系统。组件有一个通俗的说法:积木。每种不同类型的积木都有特定的嵌口(接口),具有不同的形状(行为规范),可以与其它积木组装,构造更大的形状。

    一切逻辑皆可组件化。用组件的视角去审视业务逻辑,将系统中的业务逻辑抽象成各种组件,应用层只需要针对特定需求进行组件编排。比如,“基于接口编程:使用收集器模式使数据获取流程更加清晰可配置” 将获取组装订单详情的普通流程变成了一个组件化的可编排的流程。业务逻辑即组件,业务即配置。

    我接手的一个订单同步的系统,是一个组件化做得很好的系统。这个系统里基本只有各种各样的组件,相当于一个较为完备的工具箱。业务逻辑,也是作为业务组件来看待的。这样,订单同步任务所需要做的,只是将各种组件组合起来,构建一个完整的业务流程。

    区分新手和高级工程师的一个区别,就是看他能不能从设计的角度来思考、分析和解决问题,从组件的角度来构建和优化系统。

    模型

    模型,是设计的深化。模型,是有序组织的数据模型和数据结构,以及基于其上的编排良好的应用控制结构。模型是软件系统的基石。数据模型三要素—— 一致性、完整性和完备性,基于其上的数据质量的可靠性,是软件系统的稳定性与持久发展的根基。

    • 一致性:模型中的冗余数据是一致的,只存在单一的事实。冗余数据通常存于从库、副本、缓存、消息等。要实现多个冗余存储的一致性,难度和挑战性还是很大的。
    • 完整性:模型中的数据及关联始终满足指定的约束关系;不会因为动态变化而破坏约束关系。完整性通常在构建数据模型之初就明确指定,并固化到模型的定义中。在变更数据时,必须满足模型的完整性的约束。
    • 完备性:所构建的模型可以从理论上支撑各种通用需求和定制化需求,不会因为缺失某种数据而无法支撑需求。比如说,因为导出记录模型里缺乏一个总店ID,无法支撑连锁商家的订单导出需求,就可以说这个导出记录模型是不完备的。模型的完备性可以通过场景走查来完善和补缺。

    鉴于我在这方面也在持续学习中,可以在后文中多多探讨和分享。一个值得学习和实践的设计理念是领域驱动模型设计(DDD)。从领域角度不断思考、审查和精炼系统的领域数据模型。

    为什么说模型也是一种编程呢 ? 因为编程是表达逻辑,而逻辑实质是一种严谨的结构化的思维。模型正是结构化思维的集中体现。对模型的思考和精炼,往往需要追溯更深层的原理,需要全局的视角。

    刻意练习

    从刻意练习的角度来说,每日有所编程,并不能提升编程技艺。每日有所进步(哪怕只有微小的进步),才能促进编程技艺的提升。这种进步,或者来自于简单的代码重构,或者来自于大胆的全局结构重构,或者来自于有挑战性的编程课题,或者来自于设计先导的构思,或者来自于对模型完善性的推敲。

    结语

    要持续提升编程技艺,不能仅仅只是做重复性的编码工作。通过重构可以精炼逻辑的表达,通过设计可以提炼可复用的问题和方案,通过模型的审查和优化可以将系统的基石打磨得更加稳定。

    编程,远不止于编码。模型之美,逻辑之美,表达之美,才是编程的最高目标,亦即编程的“道”。


  • 相关阅读:
    SQLite的总结与在C#的使用
    Linq中比较字符串类型的日期
    C#中委托,匿名函数,lamda表达式复习
    MYSQL中SUM (IF())
    C#在属性中用Lambda语法
    Mysql绿色版安装和遇到的问题
    FormsAuthentication权限管理
    存储过程中高性能安全式SQL拼接
    JavaScript实现搜索联想功能
    JavaScript组成
  • 原文地址:https://www.cnblogs.com/lovesqcc/p/13257580.html
Copyright © 2020-2023  润新知