十二因素应用程序说:
使用声明性格式进行设置自动化,以最大限度地减少新开发人员加入项目的时间和成本
“声明性格式”是什么意思?
声明性格式是一种您声明程序的意图/最终结果的格式,而不是它应该如何到达。声明性代码通常由调用高级函数或具有清晰可读意图的抽象的语句组成。相反,命令式代码由语句组成,这些语句清楚地传达了它们对程序状态的影响,而不涉及任何高级目标。
更简洁地说,声明式代码传达了为什么,命令式传达了方式。
下面的代码是Makefile
一个假设程序的代码hellomake
。该程序使用 提供的抽象make
来定义构建过程,而不指定隐含的低级细节。只需要指定编译器Makefile
、源目录、文件依赖结构,然后make
基于这个程序结构使用抽象填充所有样板。这被认为是一种declarative
格式,因为语句传达了高级含义而没有指定低级操作。
CC=gcc
CFLAGS=-I.
DEPS = hellomake.h
# Build an object file for each of the dependencies.
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
# Build the hellomake program using the hellomake and hellofunc object files.
hellomake: hellomake.o hellofunc.o
gcc -o hellomake hellomake.o hellofunc.o -I.
以下 Python 脚本执行 中定义的相同任务Makefile
,但由于 Python 比 更通用make
,所有这些构建细节都需要显式执行。这些明确的程序动作清楚地描述了程序将如何改变构建环境,但无法描述它们如何在没有辅助解释(例如注释)的情况下对编译程序的总体目标做出贡献。这被认为是一种imperative
格式,因为低级操作已明确定义并传达给程序员。
CC = "gcc"
CFLAGS = "-I."
DEPS = ["hellomake.h"]
def make_o_file(o_file, deps):
#don't recompile if it exists & is current
c_file = "%s.c" % os.path.splitext(o_file)[0]
if (os.path.exists(o_file)
and is_newer(o_file, c_file)
and all(is_newer(o_file, dep) for dep in deps)):
return
#else actually compile it
compile_c_file(CC, code_file, o_file, CFLAGS)
if target == "hellomake":
make_o_file("hellomake.o", DEPS)
make_o_file("hellofunc.o", DEPS)
link_o_files("hellomake", ["hellomake.o", "hellofunc.o"])
命令式和声明式格式在编程中都有重要的用途。关于声明式编程的 Wikipedia可能对更多细节有用。