使用 OOP 封装方式写 Bash 脚本

OOP(面向对象的程序设计),我在开源项目:MobileMate 里尝试一些 OOP 思路使写 Bash 脚本更容易,易于理解、修改和扩展功能。有三个基本的面向对象特性:封装、多态和继承。这里只借用其封装思想。最后,作为一个写程序的非专业人士,在我写代码时,有了更多的层次,更多的类,小的类,小的函数,简单的代码,更多的测试。

概览
我用 MobileMate V0.1a42.1 代码中转换这部分作为阐述使用 OOP 封装方式的例子。

脚本之间的关系如下:
调用者: bin/guiconvert.sh
被调用:
生成转换脚本:
如果转换一个文件夹里的所有文件: share/folderconvertor
如果转换一个单独的文件:
如果用 MENCODER 解码: share/convertor
如果用 LIBAV 解码: share/lconvertor
执行转换脚本进行实际的转换:
share/taskmanager

调用者: share/folderconvertor
被调用:
如果用 MENCODER 解码: share/convertor
如果用 LIBAV 解码: share/lconvertor

调用者: share/lconvertor
Be Called:
if convert to video: share/lv2vconvertor
if convert to audio: share/lx2aconvertor

另外,这些脚本调用一些辅助“类”,比如, "share/configurator" 用于处理配置文件, "share/filedetector" 用于检测文件信息,"share/helper" 是一些工具函数。

一个“类”
作为一个例子,这里我用 "share/lconvertor" 来描述怎样构建一个 bash 脚本类。

"类", "share/lconvertor", 作用是用 Libav 作为解码工具转换文件到视频或音频文件。

在 "lconvertor" 里有3个数据成员: lconvertor_input, lconvertor_output, lconvertor_option。

lconvertor_input: 源文件。
lconvertor_output: 目的文件夹。
lconvertor_option: 转换选项。

"lconvertor"里有方法(函数)成员:lconvertor_init(), lconvertor_destroy(), lconvertor_set(), lconvertor_get(), lconvertor_is2video(), lconvertor_getvf(), lconvertor_getaf(), lconvertor_doconverts()。

lconvertor_init(): 在开始时初始化数据成员并且可能有其它的一些初始化操作。
lconvertor_destroy(): 在结束时清理数据成员并且可能有其它的一些清理操作。
lconvertor_set(): 设置数据成员。
lconvertor_get(): 取得数据成员的值。
lconvertor_is2video(): 检查输入文件是否是一个视频或音频。
lconvertor_getvf(): 根据 lconvertor_option,组成视频滤镜链字符串。
lconvertor_getaf(): 根据 lconvertor_option,组成音频滤镜链字符串。
lconvertor_doconverts(): 根据 lconvertor_input, lconvertor_output, lconvertor_option, lconvertor_getvf(), lconvertor_getaf(), 组成下一层次被调用类的新选项,如果是转换到视频调用 lv2vconvertor,转换到音频调用 lx2aconvertor。

好,你可以看到数据或方法成员有个 "lconvertor_" 前缀, 它是“类”名。因为在 Bash 脚本里,数据和方法成员是可公共访问的,所以需要一个避免冲突的机制。尽管,在引入类“. .../share/lconvertor”或调用lconvertor_init() and lconvertor_destroy()时数据成员会被设置为一个初始值。这是避免变量和函数名称冲突的双保险。

实际上,有一些完整的 shell OOP 实现,如: https://www.usenix.org/legacy/publications/library/proceedings/bos94/full_papers/haemer.ps , A New Object-Oriented Programming Language: sh Jeffrey Haemer, Canary Software, Inc.。

Shell 脚本是一个有用的工具,怎样恰当的使用来完成工作,个人的喜好很重要。因为有限的 shell 脚本技能,喜欢代码更人性化,我选择了 OOP 封装来写 shell,并在编码中选择了更多的层次,更多的类,小的类,小的函数,简单的代码,更多的测试。

发表评论

电子邮件地址不会被公开。 必填项已用*标注