2016-10-02 5 views
5

У меня есть несколько сценариев и модулей, которые используют глобальные переменные для нескольких вещей. Мой журнал может принимать одну из трех форм; Terse, Verbose и Validation (Verbose logging без фактических действий, просто проверка предоставленных данных). У меня также есть ряд функций, которые реагируют по-разному в зависимости от Контекста, в котором они выполняются (Пользователь или машина), и выполняемое действие (Rollout, Remove, Conform, Relocate) также влияет на вещи. Итак, до сих пор я использовал три глобальные переменные, и это сработало, но я знаю, что наилучшая практика заключается в том, чтобы избежать глобальных переменных. Тем не менее, единственный способ обращения к нему - это некоторые функции Get и Set в одном модуле и переменные уровня скрипта. Кажется, что он добавляет сложности, не обращая особого внимания, поскольку у меня все еще есть переменные, которые находятся в более высокой области действия, чем функция, использующая их. В качестве альтернативы, я мог бы передать эти три значения каждой функции, которая им нужна, но это также множество аргументов, которые мало ценят. Поэтому я начинаю удивляться, это одно место, где глобальные переменные действительно являются правильным ответом? Их существование предполагает, что должна быть какая-то ситуация, когда их следует использовать, и это начинает ощущаться именно в такой ситуации.Глобальный случай использования переменных

+0

С глобальными именами переменных становится ключевым фактором. Какие имена вы указали в трех глобальных переменных? –

ответ

5

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

Что вы должны не использовать глобальные переменные for is для транспортировки состояния, то есть изменения значений. Если вы изменяете значение глобальных переменных в разных местах вашего кода, проблемы с устранением неполадок становятся огромной болью сзади, потому что вы передаете информацию за пределами обычных «каналов» (параметры, возвращаемые значения). Если вам нужно изменить глобальную переменную где-то еще в вашем коде, это практически всегда означает, что вы должны переоценить свою архитектуру.

+0

Я думаю, что здесь все становится липким, потому что это действие обязательно изменится. Возможно, мне нужно взглянуть на обратное действие по-разному и использовать глобальную константу для остальных. Я делаю большой рефакторинг, так что теперь самое время переосмыслить, это точно. Сказано, что пара функций Set-Action & Get-Action решает проблему, или это действительно считается вариацией той же проблемы?В основном я бы установил действие для удаления, пропустил кучу задач, установил Rollout, loop, установил Conform и loop. – Gordon

2

избежать глобальных переменных в PowerShell с помощью Dynamic Scoping

PowerShell реализует Dynamic Scoping. В наши дни это редкий выбор в оформлении языков, но правильно применяемое динамическое масштабирование дает разработчику гораздо лучший контроль над конфликтами имен, чем глобальные переменные. Чтобы понять, как это может относиться к вашему делу (ы), давайте рассмотрим следующую игрушку модуль:

# File Module1.psm1 

$module = "Module1" 
$Context = "User" 

function Log-Message($message) { 
    Write-Host "$module/${action}: $message ($LogLevel-$Context)" 
} 

function CommonCode { 
    Log-Message "In CommonCode" 
} 


function Invoke-Rollout($LogLevel = "Terse", $Context=$script:Context) { 
    $action = "Rollout" 
    CommonCode 
} 

function Invoke-Remove($LogLevel = "Terse", $Context=$script:Context) { 
    $action = "Remove" 
    CommonCode 
} 

function Set-Module1($Context=$script:Context) { 
    $script:Context = $Context 
} 

Export-ModuleMember -Function Invoke-Rollout, Invoke-Remove, Set-Module1 

Что важно здесь то, что в Log-Message, переменные $module, $action, $LogLevel и $LogContext являются неглобальной переменные, а не свободные переменные, которые до сих пор не определены. Во время выполнения PowerShell будет динамически определять свою привязку, основываясь на самом последнем определении в стеке вызовов ...

Вместо того чтобы пытаться объяснить это подробно, вам может быть лучше всего поиграть с этим модулем игрушек и посмотреть каков эффект динамического охвата при регистрации. Вот некоторые эксперименты, которые я пробовал:

PS C:\temp> Import-Module -Force .\Module1.psm1 

PS C:\temp> Invoke-Rollout 
Module1/Rollout: In CommonCode (Terse-User) 

PS C:\temp> # For Sticky Change -- Set-Module1 
PS C:\temp> Set-Module1 -Context Machine 

PS C:\temp> Invoke-Rollout 
Module1/Rollout: In CommonCode (Terse-Machine) 

PS C:\temp> Invoke-Remove -LogLevel Verbose -Context XXX 
Module1/Remove: In CommonCode (Verbose-XXX) 

PS C:\temp> Invoke-Remove -Context User 
Module1/Remove: In CommonCode (Terse-User) 

PS C:\temp> $Context = "FooBar" # This should have no effet on Module1 

PS C:\temp> Invoke-Remove 
Module1/Remove: In CommonCode (Terse-Machine) 
Смежные вопросы