Я работаю над проектом в Delphi, и я создаю установщик для приложения, состоит из трех основных частей.
- Установка / удаление PostgreSQL
- myapplication (настройка myapplication создается с использованием nsi) установка / удаление.
- Создание таблиц в Postgres через скрипт (пакетные файлы).
Все работает нормально и гладко, но если что-то не получается, я создал LogToFileger, который будет LogToFile на каждом этапе процесса,
как это
LogToFileToFile.LogToFile('[DatabaseInstallation] : [ACTION]:Postgres installation started');
Функция LogToFileToFile.LogToFile()
Это запишет содержимое в файл. Это работает хорошо, но проблема в том, что это испортило код, так как стало трудно читать код, так как один может видеть только LogToFileToFile.LogToFile()
вызов функции везде в коде
пример
if Not FileExists(SystemDrive+'\FileName.txt') then
begin
if CopyFile(PChar(FilePathBase+'FileName.txt'), PChar(SystemDrive+'\FileName.txt'), False) then
LogToFileToFile.LogToFile('[DatabaseInstallation] : copying FileName.txt to '+SystemDrive+'\ done')
else
LogToFileToFile.LogToFile('[DatabaseInstallation] : copying FileName.txt to '+SystemDrive+'\ Failed');
end;
if Not FileExists(SystemDrive+'\SecondFileName.txt') then
begin
if CopyFile(PChar(FilePathBase+'SecondFileName.txt'), PChar('c:\SecondFileName.txt'), False) then
LogToFileToFile.LogToFile('[DatabaseInstallation] : copying SecondFileName.txt to '+SystemDrive+'\ done')
else
LogToFileToFile.LogToFile('[DatabaseInstallation] : copying SecondFileName.txt to '+SystemDrive+'\ Failed');
end;
как вы можете видеть, есть много LogToFileToFile.LogToFile()
звонков,
прежде чем это было
if Not FileExists(SystemDrive+'\FileName.txt') then
CopyFile(PChar(FilePathBase+'FileName.txt'), PChar(SystemDrive+'\FileName.txt'), False)
if Not FileExists(SystemDrive+'\SecondFileName.txt') then
CopyFile(PChar(FilePathBase+'SecondFileName.txt'), PChar('c:\SecondFileName.txt'), False)
это так во всем моем коде сейчас.
его трудно читать.
Кто-нибудь может предложить мне хороший способ, чтобы убрать звонки в LogToFile?
лайк
Отступ в 'LogToFileToFile.LogToFile () `вызов ,
как этоif Not FileExists(SystemDrive+'\FileName.txt') then begin if CopyFile(PChar(FilePathBase+'FileName.txt'), PChar(SystemDrive+'\FileName.txt'), False) then {Far away--->>} LogToFileToFile.LogToFile(2,'[DatabaseInstallation] : [ACTION]:copying FileName.txt to '+SystemDrive+'\ sucessful') else {Far away--->>} LogToFileToFile.LogToFile(2,'[DatabaseInstallation] : [ACTION]:copying FileName.txt to '+SystemDrive+'\ Failed'); end;
Отдельный блок, как
LogToFileger
этот Блок будет иметь все сообщения LogToFile,switch case
как этоFunction LogToFilegingMyMessage(LogToFilegMessage : integer) begin case LogToFilegMessage of 1 : LogToFileToFile.LogToFile(2,'[DatabaseInstallation] : [ACTION]:copying FileName.txt to '+SystemDrive+'\ sucessful'); 2 : LogToFileToFile.LogToFile(2,'[DatabaseInstallation] : [ACTION]:copying FileName.txt to '+SystemDrive+'\ Failed'); 150 : LogToFileToFile.LogToFile(2,'[somthing] : [ACTION]: somthing important); end;
так что я могу просто вызвать LogToFilegingMyMessage (1), где это необходимо.
Может кто-нибудь сказать мне, что является лучшим и более чистым подходом к LogToFileging таким образом?
источник
logBook.log()
встречаются.Ответы:
Когда вы добавили запись в журнал, вы ввели две вещи:
У каждой из этих проблем есть свое, относительно простое решение:
Разбейте код на более мелкие функции. Вместо одной гигантской функции, которая содержит все ваши копии, а также регистрирует сообщения об ошибках / успехах, вы можете ввести функцию «CopyFile», которая будет копировать ровно один файл и регистрировать свой собственный результат. Таким образом, ваш основной код будет состоять из вызовов CopyFile и будет легко читаться.
Вы могли бы сделать свой регистратор умнее. Вместо того, чтобы передавать гигантскую строку, содержащую много повторяющейся информации, вы можете передать значения перечислений, которые прояснят ситуацию. Или вы можете определить более специализированные функции Log (), например, LogFileCopy, LogDbInsert ... Что бы вы ни повторяли много раз, рассмотрите возможность включения этого в свою собственную функцию.
Если вы будете следовать (1), вы можете получить код, который выглядит следующим образом:
Тогда вашему CopyFile () нужно всего несколько строк кода, чтобы выполнить действие и записать его результат, поэтому весь ваш код остается кратким и легким для чтения.
Я бы держался подальше от вашего подхода № 2, поскольку вы разделяете информацию, которая должна оставаться вместе, в разные модули. Вы просто просите, чтобы ваш основной код не синхронизировался с вашими лог-операторами. Но, глядя на LogMyMessage (5), вы никогда не узнаете этого.
ОБНОВЛЕНИЕ (ответ на комментарий): я не знаю, какой именно язык вы используете, поэтому эту часть, возможно, придется немного адаптировать. Кажется, все ваши сообщения журнала идентифицируют 3 вещи: компонент, действие, результат.
Я думаю, что это в значительной степени то, что предложил MainMa. Вместо передачи фактической строки определите константы (в C / C ++ / C # они будут частью перечислимого типа). Например, для компонентов у вас могут быть: DbInstall, AppFiles, Registry, Shortcuts ... Все, что делает код меньше, облегчит чтение.
Также было бы полезно, если бы ваш язык поддерживал передачу параметров переменных, но не уверен, что это возможно. Так, например, если действие «FileCopy», вы можете определить это действие, чтобы иметь два дополнительных пользовательских параметра: имя файла и каталог назначения.
Таким образом, строки для копирования вашего файла будут выглядеть примерно так:
* обратите внимание, также нет причин дважды копировать / вставлять строку журнала, если вы можете сохранить результат операции в отдельной локальной переменной и просто передать эту переменную в Log ().
Вы видите тему здесь, верно? Менее повторяющийся код -> более читаемый код.
источник
you could pass in enumerations values
этом?Похоже, вам нужно абстрагироваться от концепции «LoggableAction». В вашем примере я вижу шаблон, в котором все вызовы возвращают логическое значение, указывающее на успех или неудачу, и единственное отличие - это сообщение журнала.
Прошло много лет с тех пор, как я написал Delphi, так что это в значительной степени вдохновленный c # псевдокод, но я бы подумал, что вы хотите что-то вроде
Тогда ваш код вызова становится
Я не могу вспомнить синтаксис Delphi для указателей на функции, но какими бы ни были детали реализации, какая-то абстракция вокруг подпрограммы журнала может показаться вам нужной.
источник
LoggableAction()
это хорошо, я могу напрямую написать возвращаемое значение вместо проверки и записи.Одним из возможных подходов является сокращение кода с помощью констант.
станет:
который имеет лучший лог-код / другое соотношение кодов при подсчете количества символов на экране.
Это близко к тому, что вы предложили в пункте 2 вашего вопроса, за исключением того, что я бы не пошел так далеко:
Log(9257)
он явно корочеLog(2, SqlInstal, Action, CopyMapSuccess, sOSdrive)
, но также довольно сложен для чтения. Что такое 9257? Это успех? Действие? Это связано с SQL? Если вы работаете над этой кодовой базой в течение последних десяти лет, вы узнаете эти цифры наизусть (если есть логика, то есть 9xxx - это коды успеха, x2xx относятся к SQL и т. Д.), Но для начинающего разработчика, который обнаруживает кодовая база, короткие коды будут кошмаром.Вы можете пойти дальше, смешав два подхода: использовать одну константу. Лично я бы не стал этого делать. Либо ваши константы будут расти в размерах:
или константы останутся короткими, но не очень явными:
Это также имеет два недостатка. Вам придется:
Держите отдельный список, связывающий информацию журнала с их соответствующими константами. С одной константой он будет быстро расти.
Найдите способ применения единого формата в вашей команде. Например, что если вместо этого
T2SSQ
кто-то решит написатьST2SQL
?источник
log
вызова, но можете ли вы объяснить мне больше, что он не понялLog(2, SqlInstal, Action, CopyMapFailure, sOSdrive)
, вы хотите сказать,SqlInstal
будет ли моя определенная переменная какSqlInstal:=[POSTGRESQL INSTALLATION]
?SqlInstal
может быть чем угодно, например значением3
. Затем, вLog()
, это значение будет эффективно преобразовано в,[POSTGRESQL INSTALLATION]
прежде чем будет объединено с другими частями сообщения журнала.single format in your team
хороший / отличный вариантПопробуйте извлечь ряд маленьких функций, чтобы справиться со всеми беспорядочно выглядящими вещами. Существует много повторяющегося кода, который очень легко можно сделать в одном месте. Например:
Хитрость заключается в том, чтобы посмотреть на любое дублирование в вашем коде и найти способы его устранения. Используйте много пробелов и используйте начало / конец в ваших интересах (больше пробелов и легко найти / сложить блоки кода). Это действительно не должно быть слишком сложно. Эти методы могут быть частью вашего регистратора ... это зависит от вас на самом деле. Но это выглядит как хорошее место для начала.
источник
success := CopyFile()
спасибо за идею, это уменьшит некоторые ненужные строки кода в моем случаеLogIfFileDoesNotExist
копирование файлов?Я бы сказал, что идея, лежащая в основе варианта 2, является лучшей. Тем не менее, я думаю, что направление, которое вы выбрали, ухудшает ситуацию. Целое число ничего не значит. Когда вы посмотрите на код, вы увидите, что что-то регистрируется, но вы не знаете что.
Вместо этого я бы сделал что-то вроде этого:
Это сохраняет структуру сообщения, но позволяет вашему коду быть гибким. Вы можете определить постоянные строки по мере необходимости для фаз и использовать их только в качестве параметра фазы. Это позволяет вам вносить изменения в фактический текст в одном месте и влиять на все. Другое преимущество вспомогательной функции заключается в том, что важный текст связан с кодом (как это был комментарий), но текст, который важен только для файла журнала, абстрагируется.
Это не то, что вы упомянули в своем вопросе, но я заметил о вашем коде. Ваш отступ не соответствует. Первый раз, когда вы используете
begin
его, не отступ, а второй раз. Вы делаете то же самое сelse
. Я бы сказал, что это гораздо важнее, чем строки журнала. Если отступы не согласованы, это затрудняет сканирование кода и отслеживание потока. Многие повторяющиеся строки журнала легко фильтруются при сканировании.источник
Как насчет этого:
Метод NewEntry () будет строить строку текста (включая добавление [&] вокруг правильных записей) и удерживать ее в ожидании вызова методов success () или fail (), которые добавляют строку с «success» или «сбой», а затем выведите строку в журнал. Вы также можете использовать другие методы, например, info (), когда запись в журнале предназначена для чего-то другого, кроме успеха / неудачи.
источник