Script working in two modes (preview and update)

对着背影说爱祢 提交于 2019-12-25 12:43:27

问题


I'm writing a script which works in two modes: 'preview' and 'update'.
When it runs in 'preview' mode, the script generates a preview of the changes that will be made (something like a diff output).
When it runs in 'update' mode, it applies those changes.



The preview output could be generalized in this way:

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. 

As you already can imagine, the 'action' mode for this preview will do something like

- Create item 231234 with his information
- Update description for item 211012
- Update description and name for item 218998
- Remove item 212099



Until now, I've been building the script following this logic:
(note: this pseudo code has just the self-explaining lines needed for this question, and is obviously really different from actual code)

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

 ....


This script will usually takes care of lists of circa 300 to 3000 elements, testing about 80-120 conditions.
The script is expected to take his somewhat long time to execute (for example, is ok that script running in 'preview' mode takes 3mins for larger lists).


But now I'm wondering if it wouldn't be "better" (*) to build the script under the following logic:

[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

Which version should be preferred, under which circumstances and why?



EDIT: Just for being clearer, this is the resume of the two options

a. "single script, runs twice":
I have a single script which runs twice.
It checks a lot of conditions, and for each of those, depending on which mode it is running, it will add some string to the preview output, or it will execute a command.
(code is written only once, but the ton of conditions is executed twice; the script is first called in 'preview' mode and then in 'update' mode.)

b. "two different scripts":
all the conditions of the previous script will be checked only in the 'preview' script.
For each condition, it will add some string to the preview output, and a command to a command_list.
The 'update' script will simply execute every command in that command_list, nothing more.
(the testing code of previous 'a' script is written only once, and it will always generate preview and command_list)



__
(*) better for performance, duration, etc ...


回答1:


Perhaps the most important consideration is that you don't want to maintain two separate scripts that must be kept in sync.

Is it possible to change each command (or write a shell around each command) so it can operate in either "preview" or "execute" mode? Then you can run a single script, and pass a parameter to each command, telling it which mode to run in.

As an example, in bash, you can sometimes set a variable to either "echo" or nothing, depending on the mode. Then you can write commands like

$ECHO command args

which will either echo the command (if $ECHO is "echo") or execute it (if $ECHO is empty). Of course this is very simplistic, but you may be able to apply a similar technique.




回答2:


This question is tagged as langauge-agnostic but some responses may use syntactic tricks possible in some languages and not in others. Personally, I would recommend a system in which you define actions on your items depending on the mode, and the "script proper" calls these actions and does not depend on mode at all. For example:

[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)

This way you do not duplicate your command flow and the code is easier to work with. Most languages will implement this mechanism with virtual function overriding, the cost of which is negligible for the call counts you quote.




回答3:


Perhaps a combination of your proposal and @michal's idea. Do one pass through the logic, with a dummy output destination if you are not going to do a preview.

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


来源:https://stackoverflow.com/questions/9473771/script-working-in-two-modes-preview-and-update

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!