文章目录
- 程序的定义
-
- `程序 = 数据结构 + 控制 + 业务逻辑`
- 写出好程序的关键
- 控制control 和 业务logic 的解耦技术
-
- 例:检查用户表单信息
- 编程范式的种类
-
- 两大分支
- 分类:声明式、命名式、逻辑的、函数式、面向对象的、面向过程的。
程序的定义
很多人认同的两个观点:
-
程序 = 数据结构 + 算法
这个表达式认为,如果数据结构设计得好,算法也会变得简单,而且一个好的通用的算法应该可以用在不同的数据结构上。
-
算法 = 控制 + 业务逻辑
这个表达式则想表达的是数据结构不复杂,复杂的是算法,算法由两个逻辑组成,一个是真正的业务逻辑,另外一种是控制逻辑。也就是我们的业务逻辑是复杂的。
Robert Kowalski: 任何算法都会有两个部分, 一个是 Logic 部分,这是用来解决实际问题的。另一个是 Control 部分,这是用来决定用什么策略来解决问题。Logic 部分是真正意义上的解决问题的算法,而 Control 部分只是影响解决这个问题的效率。程序运行的效率问题和程序的逻辑其实是没有关系的。我们认为,如果将 Logic 和 Control 部分有效地分开,那么代码就会变得更容易改进和维护。
通过这两个表达式,我们可以得出:
程序 = 数据结构 + 控制 + 业务逻辑
程序 = 数据结构 + 控制 + 业务逻辑
编程范式,或是程序设计的方法。其实都是在围绕着这三件事来做的。所有的语言或编程范式都在解决这些问题, 也就是编程范式的本质:
-
是可以标准化的。比如:遍历数据、查找数据、多线程、并发、异步等,都是可以标准化的。控制
- 因为
需要处理数据,所以标准化 控制 ,需要标准化控制
,我们可以通过泛型编程来解决这个事。数据结构
- 而
还要处理用户的控制
。所以可以通过标准化接口 / 协议来实现,我们的 控制 模式可以适配于任何的 业务逻辑 。业务逻辑
写出好程序的关键
有效地分离、
业务逻辑
和
控制
是写出好程序的关键所在!
数据结构
其中,逻辑 Logic 和 控制 Control 是关键, 程序的本质复杂性 是逻辑,非本质复杂性 是控制。
这个和系统架构也有相通的地方,逻辑是你的业务逻辑过程的抽象,加上一个由术语表示的数据结构的定义,控制逻辑跟你的业务逻辑是没关系的,你控制,它执行。
业务逻辑 部分才是真正有意义的
控制 部分只是影响 业务逻辑 部分的效率
那些混乱不堪的代码,会把控制和业务逻辑放在一块。里面有些变量和流程是跟业务相关的,有些是不相关的。
业务逻辑决定了程序的复杂度,业务逻辑本身就复杂,你的代码就不可能写得简单。于是 控制 + 业务逻辑 的相互交织成为了最终的程序复杂度。
控制control 和 业务logic 的解耦技术
- 通用的解耦方案:
元语言 logic + 解释器 control
- 元语言: 描述业务逻辑
- 解释器: 元语言到目标语言的映射
- 具体技术
- State Machine
- 状态定义
- 状态变迁条件
- 状态的 action
- DSL – Domain Specific Language
- HTML,SQL,Unix Shell Script,AWK,正则表达式……
- 编程范式
- 面向对象:委托、策略、桥接、修饰、IoC/DIP、MVC……
- 函数式编程:修饰、管道、拼装
- 逻辑推导式编程:Prolog语言
- State Machine
例:检查用户表单信息
-
需求:校验 用户信息
name:字段至少3个字符
password:字段至少8个字符,
repeat_password:和password要一致,
email:要符合邮箱格式;
- 写法1:业务逻辑 与 控制 混合
function check_form_x() {
//获取name字段,校验
var name = $('#name').val();
if (null == name || name.length <= 3) {
return { status : 1, message: 'Invalid name' };
}
//获取password字段,校验
var password = $('#password').val();
if (null == password || password.length <= 8) {
return { status : 2, message: 'Invalid password' };
}
//获取repeat_password字段,校验
var repeat_password = $('#repeat_password').val();
if (repeat_password != password.length) {
return { status : 3, message: 'Password and repeat password mismatch' };
}
//获取email字段,校验
var email = $('#email').val();
if (check_email_format(email)) {
return { status : 4, message: 'Invalid email' };
}
//校验通过
return { status : 0, message: 'OK' };
}
-
写法2:业务逻辑 与 控制 分离
做一个 DSL+ 一个 DSL 的解析器
- 业务逻辑 描述成DSL
- 控制逻辑 check_form 作为 DSL 的解析器
整个逻辑顿时清晰了,细节的处理只需要在check_form中编写一次
var meta_create_user = {
form_id : 'create_user',
fields : [
{ id : 'name', type : 'text', min_length : 3 },
{ id : 'password', type : 'password', min_length : 8 },
{ id : 'repeat-password', type : 'password', min_length : 8 },
{ id : 'email', type : 'email' }
]
};
var r = check_form(meta_create_user);
编程范式的种类
编程范式基本上来说,就是两大分支
两大分支
一边是在解决 数据和算法,
一边是在解决 逻辑和控制。
分类:声明式、命名式、逻辑的、函数式、面向对象的、面向过程的。
函数式和逻辑式 偏向于你定义要什么,而不是怎么做
编程范式和面向对象编程范式,偏向于怎么做,而不是要做什么