问题
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