命令式编程和声明式编程
命令式编程也叫指令式编程。
我现在有一个需求:“假设有a、b两个值,a值为1,我需要b值是a值的两倍。”那么这个需求用算法是这样写的:
var a = 1;
var b = a * 2;
在这个算法中我写了两步命令:
- 设a值等于1
- 令b值等于a乘以2
在这样一个需求实现的过程中,我按照逻辑逐步地将需求通过代码实现,过程平平淡淡,指令一条接着一条,这就是最原始的指令式编程。
在没有声明式编程的支持下,指令式编程可以在一个文件中累积成千上万的代码来实现一个程序。这样的代码是难以理解且不可维护的。
为了让代码更容易编写和维护,声明式编程出现了。顾名思义,它就是将代码中的某一段逻辑声明出来,当做一段独立的代码块,以便随时能使用之。
现在再通过声明式编程来实现需求,于是我声明了个multiple
函数调用之:
function multiple(a) {
return a * 2;
}
var a = 1;
var b = multiple(a);
这就是声明式编程,MDN中对声明式编程的描述大体如下:
声明式编程就是将需求实现过程中的某些逻辑抽离,并声明成一段相对独立的代码,在机器去调用这个逻辑声明的时候,知道自己应该做什么。
注意关键词“逻辑抽离”和“相对独立”,它是衡量声明式编程的重要标准。像函数式编程中的函数,面向对象编程中的方法和对象,都是标准的“逻辑抽离”和“相对独立”。它们都可以称为子程序。
可是。
以“命令式编程”方式int b = a * 2;
写起来多简单啊,为什么还要写个multiple
函数呢?
虽然在简单逻辑下命令式编程具有优势,但在复杂逻辑下命令式编程就会变得十分冗余且不灵活。
举个例子来说:
我现在需要找出在自然数1-15中哪些数字是2的倍数。如果用命令式编程来写:
for(let i = 1; i <= 15; i ) {
if (i % 2 == 0) {
console.log("2 的倍数:" i);
}
}
这样写看起来不错。可现在,我的需求变了,除了原来的需求外,我还要找出在自然数51-65中哪些数字是3的倍数,于是我又写了段代码:
for(let i = 51; i <= 65; i ) {
if (i % 3 == 0) {
console.log("3 的倍数:" i);
}
}
两个需求现在有两段代码了,如果我需求反复变化,那么代码量更多。其实若是用声明式思维来思考,这两个需求高度相似,只要将相似逻辑抽离出来进行声明出来就能够复用。
首先声明个查找可整除数函数findDivisible
,我给出了一些方法参数————起始数字(begin
)和结束数字(end
)、以及被整除数(divisor
):
function findDivisible(begin, end, divisor) {
for(let i = begin; i <= end; i ) {
if (i % divisor == 0) {
console.log(divisor " 的倍数:" i);
}
}
}
findDivisible(1, 15, 2);
findDivisible(51, 65, 3);
最后调用它,两个相似需求只需要一段代码。如此看来,声明式编程能够省去我们很多代码,相对来说也能够节约时间,同时代码也便于阅读和维护。
结尾唠嗑
其实很多文章我早就写出来了,只是不敢发,怕误人子弟。但前段日子跟朋友聊天时,我朋友说:“既然写了,何不发出来,如果有人指正错误的地方,虚心学习,不也是一种成长吗”。所以今天把我之前写的文章细化一下,拆分开来,然后再发表出来。