Скрипт работает в двух режимах (предварительный просмотр и обновление) - PullRequest
0 голосов
/ 28 февраля 2012

Я пишу скрипт, который работает в двух режимах: '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

Какая версия предпочтительнее, при каких обстоятельствах и почему?



РЕДАКТИРОВАТЬ: Просто для ясности, это резюме двух вариантов

а. «один скрипт, запускается дважды»:
У меня есть один скрипт, который запускается дважды.
Он проверяет много условий, и для каждого из них, в зависимости от того, в каком режиме он работает, он добавит некоторую строку в вывод предварительного просмотра или выполнит команду.
(код пишется только один раз, но тонна условий выполняется дважды; скрипт сначала вызывается в режиме «предварительного просмотра», а затем в режиме «обновления».)

б. «два разных сценария»:
все условия предыдущего сценария будут проверены только в сценарии предварительного просмотра.
Для каждого условия он добавляет некоторую строку в вывод предварительного просмотра и команду в список_команд.
Сценарий «update» просто выполнит каждую команду в этом списке команд, ничего более.
(тестовый код предыдущего скрипта 'a' пишется только один раз, и он всегда генерирует предварительный просмотр и список команд)



__
(*) лучше по производительности, продолжительности и т. д. *

Ответы [ 3 ]

0 голосов
/ 28 февраля 2012

Этот вопрос помечен как независимый от языка, но некоторые ответы могут использовать синтаксические приемы, которые возможны в некоторых языках, а не в других.Лично я бы порекомендовал систему, в которой вы определяете действия над своими элементами в зависимости от режима, а «собственно скрипт» вызывает эти действия и не зависит от режима вообще.Например:

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

Таким образом, вы не дублируете поток команд и с ним легче работать.Большинство языков реализуют этот механизм с переопределением виртуальных функций, стоимость которых незначительна для количества вызовов, которое вы цитируете.

0 голосов
/ 28 февраля 2012

Возможно сочетание вашего предложения и идеи @ 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
0 голосов
/ 28 февраля 2012

Возможно, наиболее важным соображением является то, что вы не хотите поддерживать два отдельных сценария, которые должны быть синхронизированы.

Можно ли изменить каждую команду (или написать оболочку вокруг каждой команды), чтобы она могла работать в режиме «предварительного просмотра» или «выполнения»? Затем вы можете запустить один скрипт и передать параметр каждой команде, сообщая, в каком режиме работать.

Например, в bash вы можете иногда устанавливать для переменной значение «echo» или ничего, в зависимости от режима. Тогда вы можете написать команды, как

$ECHO command args

, который либо выдает команду (если $ECHO "echo"), либо выполняет ее (если $ECHO пусто). Конечно, это очень упрощенно, но вы можете применить аналогичную технику.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...