我正在编写一个以两种模式运行的脚本:'preview'
和'update'
。
当它以'preview'
模式运行时,脚本会生成将要进行的更改的预览(类似于diff输出)。
当它以'update'
模式运行时,它会应用这些更改。
预览输出可以通过以下方式进行推广:
Item 231234 is new to the db. It will be added to the db with the following data:
Name:
Description:
etc...
Item 211012 already exists in the database, but some changes have been made:
Different description:
Old description: "Blah blah blah"
New description: "Improved blah blah blah"
Item 218998 already exists in the database, but some changes have been made:
Different name:
Old name: "I am 218998"
New name: "John"
Different description:
Old description: "Blah blah blah"
New description: "Improved blah blah blah"
Item 212099 doesn't exists anymore, it will be removed from the database.
正如您已经可以想象的那样,此预览的'action'
模式将执行类似
- Create item 231234 with his information
- Update description for item 211012
- Update description and name for item 218998
- Remove item 212099
到现在为止,我一直在按照这个逻辑构建脚本:
(注意:这个伪代码只有这个问题所需的自解释行,显然与实际代码完全不同)
if condition 1:
if mode is 'preview': add message1 to preview
if mode is 'update': execute command1
for element in list1:
if mode is 'preview': add something about element to preview
if mode is 'update': execute some command involving element
for element in list2:
if condition 2:
if mode is 'preview': add message2 about this element to preview
if mode is 'update': execute command2 involving element
if condition 3:
if mode is 'preview': add message3 about this element to preview
if mode is 'update': execute command3 involving element
....
此脚本通常会处理circa 300 to 3000
元素列表,测试80-120
条件
该脚本需要花费很长时间才能执行(例如,在'preview'
模式下运行的脚本需要3分钟才能执行更大的列表)。
但现在我想知道在以下逻辑下构建脚本是不是“更好”(*):
[preview_script]
if condition 1:
add message1 to preview
add command1 to command_list
for element in list1:
add something about element to preview
add some command involving element to command_list
[update_script]
for command in command_list:
execute command
应该首选哪个版本,在哪种情况下以及为什么?
编辑:为了更清楚,这是两个选项的简历
一个。 “单脚本,运行两次”:
我有一个运行两次的脚本
它检查很多条件,对于每个条件,
根据它运行的模式,它会在预览输出中添加一些字符串,或者执行命令
(代码只写一次,但大量条件执行两次;
该脚本首先在“预览”模式下调用,然后在“更新”模式下调用。)
湾“两个不同的剧本”:
只会在“预览”脚本中检查上一个脚本的所有条件
对于每个条件,它将向预览输出添加一些字符串,并向command_list添加命令
'update'脚本将只执行该command_list中的每个命令,仅此而已
(以前的'a'脚本的测试代码只写一次,它将始终生成预览和command_list)
__
(*)更好的表现,持续时间等...
答案 0 :(得分:0)
也许最重要的考虑因素是不想要维护两个必须保持同步的独立脚本。
是否可以更改每个命令(或围绕每个命令编写一个shell),以便它可以在“预览”或“执行”模式下运行?然后,您可以运行单个脚本,并将参数传递给每个命令,告诉它运行哪个模式。
例如,在bash中,您有时可以将变量设置为“echo”或“null”,具体取决于模式。然后你可以编写像
这样的命令$ECHO command args
将回显命令(如果$ECHO
是“echo”)或执行它(如果$ECHO
为空)。当然,这非常简单,但您可以应用类似的技术。
答案 1 :(得分:0)
这个问题被标记为语言不可知,但有些回答可能会在某些语言中使用语法技巧,而在其他语言中则不然。就个人而言,我建议使用一个系统,根据模式定义对项目的操作,“适当的脚本”调用这些操作,完全不依赖于模式。例如:
[preview script]
define function handleMessage(args) to print "handle message:"+args
define function handleCommand(args) to print "handle command: "+args
[update script]
define function handleMessage(args) to actually handle the message (send it somewhere etc.)
define function handleCommand(args) to actually handle the command (execute it etc.)
[common part]
handleMessage(message1)
for command in command_list:
handleCOmmand(command)
这样您就不会复制命令流,代码也更容易使用。大多数语言都会使用虚函数覆盖来实现此机制,其成本对于您引用的调用计数可以忽略不计。
答案 2 :(得分:0)
也许是你的提案和@ michal的想法的结合。如果您不打算进行预览,请使用虚拟输出目标来传递逻辑。
if (isPreview)
dest = ValidMessageSink
else
dest = \dev\null
[always]
if condition 1:
add message1 to dest
add command1 to command_list
for element in list1:
add something about element to dest
add some command involving element to command_list
[update_script]
if (isUpdate)
for command in command_list:
execute command