Почему глобальное государство так злобно?

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

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

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

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

Я знаю, что это плохо для злоупотребления , но это глобальное пространство действительно THAT зло? И если это так, какие хорошие альтернативы существуют?

291 голос | спросил Madara Uchiha 10 Maypm12 2012, 23:35:42

17 ответов


255

Вкратце, это делает состояние программы непредсказуемым.

Чтобы разработать, представьте, что у вас есть пара объектов, которые используют одну и ту же глобальную переменную. Предполагая, что вы не используете источник случайности нигде внутри любого из модулей, тогда выход определенного метода может быть предсказан (и поэтому проверен), если состояние системы известно до того, как вы выполните этот метод.

Однако, если метод в одном из объектов вызывает побочный эффект, который изменяет значение общего глобального состояния, вы уже не знаете, что такое начальное состояние при выполнении метода в другом объекте. Теперь вы уже не можете предсказать, какой результат вы получите при выполнении метода, и поэтому вы не сможете его протестировать.

На академическом уровне это может показаться не столь серьезным, но возможность модульного тестового кода является важным шагом в процессе проверки его правильности (или, по крайней мере, пригодности для цели).

В реальном мире это может иметь некоторые очень серьезные последствия. Предположим, у вас есть один класс, который заполняет глобальную структуру данных, и другой класс, который потребляет данные в этой структуре данных, меняет свое состояние или уничтожает его в процессе. Если класс процессора выполняет метод до того, как класс populator будет завершен, результатом будет то, что процессорный класс, вероятно, будет иметь неполные данные для обработки, а структура данных, над которыми работал класс популяций, может быть повреждена или уничтожена. Поведение программы в этих условиях становится совершенно непредсказуемым и, вероятно, приведет к эпическому потере.

Кроме того, глобальное состояние вредит читабельности вашего кода. Если ваш код имеет внешнюю зависимость, которая явно не вводится в код, то кто бы ни занимался поддержкой вашего кода, придется искать его, чтобы выяснить, откуда он взялся.

Что касается альтернатив, то вообще невозможно вообще не иметь глобального состояния, но на практике обычно можно ограничить глобальное состояние единственным объектом, который обертывает все остальные, и на который никогда нельзя ссылаться, полагаясь на правила определения области использования языка. Если конкретный объект нуждается в определенном состоянии, он должен явно запросить его, передав его в качестве аргумента его конструктору или методу setter. Это называется инъекцией зависимостей.

Может показаться глупым пройти в части состояния, к которой вы уже можете получить доступ из-за правил определения того или иного языка, который вы используете, но преимущества огромны. Теперь, если кто-то смотрит на код изолированно, ясно, какое состояние ему нужно и откуда оно. Он также имеет огромные преимущества в отношении гибкости вашего модуля кода и, следовательно, возможности повторного использования его в разных контекстах. Если состояние передано и изменения в состоянии являются локальными для блока кода, то вы можете передать любое состояние, которое вам нравится (если это правильный тип данных), и обработать его код. Код, написанный в этом стиле, имеет тенденцию к появлению коллекции слабо ассоциированных компонентов, которые могут быть легко заменены. Код модуля не должен заботиться о том, откуда приходит государство, только как его обрабатывать. Если вы передадите состояние в блок кода, тогда этот кодовый блок может существовать изолированно, это не так, если вы полагаетесь на глобальное состояние.

Существует множество других причин, по которым передача состояния намного превосходит глобальное состояние. Этот ответ отнюдь не является всеобъемлющим. Вероятно, вы могли бы написать целую книгу о том, почему глобальное состояние плохое.

ответил GordonM 10 Maypm12 2012, 23:37:23
120

Изменяемое глобальное состояние является злым по многим причинам:

  • Ошибки из изменчивого глобального состояния - множество сложных ошибок вызвано изменчивостью. Ошибки, которые могут быть вызваны мутацией из любой точки программы, даже сложны, так как часто трудно найти точную причину.
  • Плохая тестируемость . Если у вас есть изменяемое глобальное состояние, вам необходимо настроить его для любых тестов, которые вы пишете. Это делает тестирование сложнее (и люди, которые люди, поэтому имеют меньше шансов сделать это!). например в случае учетных данных базы данных приложения, что, если один тест должен получить доступ к конкретной тестовой базе данных, отличной от всего остального?
  • Негибкость . Что, если одна часть кода требует одного значения в глобальном состоянии, но для другой части требуется другое значение (например, временное значение во время транзакции)? У вас внезапно есть неприятный кусочек рефакторинга на руках.
  • Функциональная примесь - «чистые» функции (т. е. те, в которых результат зависит только от входных параметров и не имеют побочных эффектов) гораздо проще рассуждать и компоновать для создания более крупных программ. Функции, которые читают или управляют изменчивым глобальным состоянием, по своей сути нечисты.
  • Кодовое понимание - поведение кода, которое зависит от множества изменяемых глобальных переменных, гораздо сложнее понять - вам нужно понять диапазон возможных взаимодействий с глобальной переменной, прежде чем вы сможете рассуждать о поведении кода , В некоторых ситуациях эта проблема может стать неразрешимой.
  • Проблемы с параллелизмом - изменяемое глобальное состояние обычно требует некоторой блокировки при использовании в параллельной ситуации. Это очень сложно сделать правильно (это причина ошибок) и значительно усложняет ваш код (жесткий /дорогой в обслуживании).
  • Производительность . Несколько потоков, постоянно избивающих одно и то же глобальное состояние, приводят к конфликту с кешем и замедляют работу вашей системы в целом.

Альтернативы изменчивому глобальному состоянию:

  • Функциональные параметры - часто упускаются из виду, но лучше всего оптимизировать ваши функции - это лучший способ избежать глобального состояния. Это заставляет вас решить важный концептуальный вопрос: какую информацию выполняет эта функция для выполнения своей работы? Иногда имеет смысл иметь структуру данных под названием «Контекст», которая может передаваться по цепочке функций, которая завершает всю соответствующую информацию.
  • Инъекционная инъекция - такая же, как и для параметров функции, только что сделанная бит раньше (при построении объекта, а не в вызове функции). Будьте осторожны, если ваши зависимости являются изменяемыми объектами, хотя это может быстро вызвать те же проблемы, что и изменчивое глобальное состояние .....
  • Неизменное глобальное состояние в основном безвредно - оно эффективно является постоянным. Но убедитесь, что он действительно является константой, и что вы не собираетесь испытывать соблазн превратить его в изменяемое глобальное состояние в более поздней точке!
  • Неизменяемые синглтоны - в значительной степени такие же, как и неизменяемое глобальное состояние, за исключением того, что вы можете отложить создание экземпляра до тех пор, пока они не понадобятся. Полезно для, например, большие фиксированные структуры данных, которые нуждаются в дорогостоящем одноразовом предварительном расчете. Разумные синглтоны, конечно, эквивалентны изменяемому глобальному состоянию и поэтому злы: -)
  • Динамическое связывание - доступно только в некоторых langauges, таких как Common Lisp /Clojure, но это эффективно позволяет привязывать значение в пределах контролируемой области (обычно на основе потока), которая не влияет на другие потоки. В какой-то степени это «безопасный» способ получить тот же эффект, что и глобальная переменная, поскольку вы знаете, что будет затронут только текущий поток выполнения. Это особенно полезно в случае, когда у вас есть несколько потоков, каждый из которых обрабатывает независимые транзакции, например.
ответил mikera 11 Mayam12 2012, 05:18:59
57
  1. Поскольку все ваше чертово приложение может использовать его, всегда невероятно сложно их развить вернуться снова. Если вы когда-либо изменяете что-либо, связанное с вашим глобальным, весь ваш код нуждается в изменении. Это головная боль обслуживания - это больше, чем просто возможность grep для имени типа, чтобы узнать, какие функции его используют.
  2. Они плохи, потому что они представляют скрытые зависимости, которые прерывают многопоточность, что становится все более важным для все большего числа приложений.
  3. Состояние глобальной переменной всегда полностью ненадежное, потому что весь ваш код может что-то делать с ним.
  4. Их действительно сложно проверить.
  5. Они делают вызов API сложным. «Вы должны помнить, что вы вызываете SET_MAGIC_VARIABLE () перед вызовом API« просто begging , если кто-то забудет позвонить ему. Это делает использование ошибки API ошибкой, вызывая труднодоступные ошибки. Используя его как обычный параметр, вы вынуждаете вызывающего пользователя правильно предоставлять значение.

Просто передайте ссылку на нужные ей функции. Это не так сложно.

ответил DeadMG 10 Maypm12 2012, 23:42:06
30

Если вы говорите «состояние», это обычно принято понимать как «изменяемое состояние». И глобальное изменяемое состояние - это полностью зло, потому что это означает, что любая часть программы может влиять на любую другую часть (путем изменения глобального состояния).

Представьте, что вы отлаживаете неизвестную программу: вы обнаружите, что функция A ведет себя определенным образом для определенных входных параметров, но иногда она работает по-разному для тех же параметров. Вы обнаружите, что он использует глобальную переменную x .

Вы ищете места, которые изменяют x , и обнаруживают, что есть пять мест, которые его модифицируют. Теперь удачи, узнав, в каких случаях функция A делает то, что ...

ответил sleske 10 Maypm12 2012, 23:42:34
9

Ты вроде как ответил на свой вопрос. Их трудно справиться, когда они «злоупотребляют», но могут быть полезны и [несколько] предсказуемы при правильном использовании тем, кто знает, как их содержать. Обслуживание и изменения в /на глобальном уровне - это, как правило, кошмар, который ухудшается по мере увеличения размера приложения.

Опытные программисты, которые могут сказать, что разница между глобальными значениями является единственной опцией, а у них легкое исправление, can имеют минимальные проблемы с их использованием. Но бесконечные возможные проблемы, которые могут возникнуть при их использовании, требуют совета против их использования.

edit: Чтобы уточнить, что я имею в виду, глобальные переменные непредсказуемы по своей природе. Как и ничего непредсказуемого, вы можете предпринять шаги, чтобы сдержать непредсказуемость, но всегда есть ограничения на то, что можно сделать. Добавьте к этому проблему новых разработчиков, присоединяющихся к проекту, имея дело с относительно неизвестными переменными, рекомендации против использования глобальных переменных должны быть понятными.

ответил orourkek 10 Maypm12 2012, 23:47:06
8

Прежде всего, чтобы инъекция зависимости была «stateful», вам нужно было бы использовать синглтоны, поэтому люди, говорящие это, как-то альтернатива ошибаются. Люди постоянно используют глобальные объекты контекста ... Даже состояние сеанса, например, по сути является глобальной переменной. Прохождение всего вокруг, будь то инъекция зависимости или нет, не всегда является лучшим решением. В настоящее время я работаю над очень большим приложением, которое использует множество объектов глобального контекста (одиночные пакеты, вводимые через контейнер IoC), и никогда не было проблемой для отладки. В частности, с архитектурой, управляемой событиями, может быть предпочтительнее использовать глобальные объекты контекста и пропускать все измененные. Зависит от того, кого вы спрашиваете.

Все, что можно злоупотреблять, а также зависит от типа приложения. Использование статических переменных, например, в веб-приложении, полностью отличается от настольного приложения. Если вы можете избежать глобальных переменных, сделайте это, но иногда они будут использовать их. По крайней мере, убедитесь, что ваши глобальные данные находятся в понятном контекстуальном объекте. Что касается отладки, ни один столбец вызовов и некоторые точки останова не могут решить.

Я хочу подчеркнуть, что слепое использование глобальных переменных - плохая идея. Функции должны быть повторно использованы и не должны заботиться о том, откуда поступают данные. Обращение к глобальным переменным связывает функцию с конкретным вводом данных. Вот почему он должен быть передан и почему инъекция зависимостей может быть полезна, хотя вы все еще имеете дело с централизованным хранилищем контекстов (через синглтоны).

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

ответил KingOfHypocrites 11 Maypm12 2012, 16:48:14
7

Есть много проблем с Singletons - вот две самые большие проблемы в моем сознании.

  • Это делает модульное тестирование проблематичным. Глобальное состояние может быть заражено от одного теста до следующего

  • Он применяет жесткое правило «Единственное единственное», которое, даже если оно не может измениться, внезапно делает. Затем необходимо изменить целую кучу кода полезности, который использовал глобально доступный объект.

Сказав, что в большинстве систем есть потребность в больших глобальных объектах. Это большие и дорогие предметы (например, диспетчеры подключения к базам данных) или хранят информацию о распространенном состоянии (например, информацию о блокировке).

Альтернативой Singleton является создание этих больших глобальных объектов при запуске и передача в качестве параметров всем классам или методам, которым необходим доступ к этому объекту.

Проблема в том, что в итоге вы получаете большую игру «pass-the-parcel». У вас есть график компонентов и их зависимостей, а некоторые классы создают другие классы, и каждый из них должен содержать кучу компонентов зависимостей только потому, что им нужны их порожденные компоненты (или компоненты компонентов, которые были созданы).

Вы столкнулись с новыми проблемами обслуживания. Пример: Неожиданно ваш компонент «WidgetFactory», находящийся в глубине графика, требует объекта таймера, который вы хотите издеваться. Тем не менее, «WidgetFactory» создается «WidgetBuilder», который является частью «WidgetCreationManager», и вам нужно иметь три класса, зная об этом объекте таймера, хотя только один его использует. Вы обнаруживаете, что хотите отказаться и вернуться обратно в Singletons и просто сделать этот объект таймера доступным по всему миру.

К счастью, это именно та проблема, которая решается с помощью платформы Injection Dependency. Вы можете просто указать инфраструктуре, какие классы ей нужно создать, и она использует отражение, чтобы определить граф зависимостей для вас, и автоматически создает каждый объект, когда они необходимы.

Итак, в целом, синглтоны плохие, и альтернативой является использование инфраструктуры Injection Dependency.

Я использую Castle Windsor, но вы избалованы выбором. См. эту страницу за 2008 год для получения списка доступных фреймворков.

ответил Andrew Shepherd 11 Mayam12 2012, 10:45:04
3

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

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

(Это не случайный пример ... это произошло с нашей системой конфигурации в проекте, в котором я сейчас.)

Учитывая, что стоимость создания чего-то неглобального обычно тривиальна, глупо это делать. Вы просто создаете будущие проблемы.

ответил Steven Burnap 11 Mayam12 2012, 00:02:06
3

Другая проблема с любопытством заключается в том, что они делают приложение сложным для масштабирования, потому что они недостаточно «глобальны». Область глобальной переменной - это процесс.

Если вы хотите масштабировать приложение, используя несколько процессов или работая на нескольких серверах, вы не можете. По крайней мере, пока вы не отбросите все глобальные переменные и не замените их каким-либо другим механизмом.

ответил James Anderson 11 Mayam12 2012, 05:45:08
3

Языки, предназначенные для обеспечения безопасности & надежный дизайн систем часто избавляется от глобального состояния mutable . (Возможно, это означает, что не существует глобальных переменных, поскольку неизменяемые объекты в некотором смысле не являются действительно сдержанными, поскольку они никогда не имеют перехода состояния.)

Joe-E - один из примеров, и Дэвид Вагнер объясняет это решение таким образом:

  

Анализ того, кто имеет доступ к объекту и принцип   наименьших привилегий являются одновременно искаженными, когда возможности   хранятся в глобальных переменных и, следовательно, потенциально читаемы   любой частью программы. Когда объект доступен в глобальном масштабе, уже невозможно ограничить область анализа:   доступ к объекту - это привилегия, которую нельзя удержать   от любого кода в программе. Джо-Э избегает этих проблем   путем проверки того, что глобальная область не содержит никаких возможностей,   только неизменяемые данные.

Итак, один из способов подумать об этом -

  1. Программирование - это проблема распределенного рассуждения. Программисты по крупным проектам должны разделить программу на части, которые могут быть обоснованы отдельными лицами.
  2. Чем меньше объем, тем легче рассуждать. Это верно как для физических лиц, так и для инструментов статического анализа, которые пытаются доказать свойства системы и тестов, требующих проверки свойств системы.
  3. Значительные источники полномочий, доступные во всем мире, затрудняют определение свойств системы.

Следовательно, глобально изменяемое состояние затрудняет

  1. разработка надежных систем,
  2. сложнее доказать свойства системы, а
  3. сложнее убедиться, что ваши тесты тестируются в области, сходной с вашей производственной средой.

Глобальное изменяемое состояние похоже на аддон DLL . Со временем различные части большой системы потребуют тонко различного поведения от общих частей изменчивого состояния. Решение DLL-ада и общие изменчивые несогласованные состояния требуют крупномасштабной координации между разрозненными командами. Эти проблемы не возникли бы, если бы глобальное состояние было должным образом занято.

ответил Mike Samuel 17 Maypm12 2012, 23:21:10
2
  

Почему глобальное государство настолько злое?

Mutable глобальное состояние является злым, потому что мозгу очень сложно принимать во внимание более чем несколько параметров за раз и выяснить, как они сочетаются как с точки зрения перспективы, так и с точки зрения стоимости что-то влияют.

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

ответил guillaume31 11 Maypm12 2012, 20:11:14
2

Состояние неизбежно в любом реальном приложении. Вы можете его обернуть любым способом, но таблица должна содержать данные в ячейках. Вы можете создавать объекты ячейки только с функциями в качестве интерфейса, но это не ограничивает количество мест, которые могут вызвать метод в ячейке и изменить данные. Вы строите целые иерархии объектов, чтобы попытаться скрыть интерфейсы, чтобы другие части кода не могли изменять данные по умолчанию. Это не препятствует произвольной передаче ссылки на содержащий объект объект. Ни одна из этих проблем сама по себе не устраняет проблемы параллелизма. Это затрудняет распространение доступа к данным, но фактически не устраняет воспринимаемые проблемы с глобальными. Если кто-то хочет изменить часть состояния, они собираются сделать это в погоде, это глобально или через сложный API (позднее будет только препятствовать, а не предотвращать).

Истинная причина не использовать глобальное хранилище - избежать конфликтов имен. Если вы загружаете несколько модулей, которые объявляют одно и то же глобальное имя, у вас либо есть неопределенное поведение (очень сложно отлаживать, потому что проходят модульные тесты), либо ошибка компоновщика (я думаю, C - предупреждает ли ваш компоновщик или не работает по этому поводу?).

Если вы хотите повторно использовать код, вы должны иметь возможность захватить модуль из другого места и не иметь его случайно наступать на ваш глобальный, потому что они использовали одно с тем же именем. Или, если вам повезло и вы получите ошибку, вы не хотите, чтобы все ссылки ссылались в одном разделе кода, чтобы предотвратить столкновение.

ответил phkahler 11 Maypm12 2012, 21:11:43
1

Глобалы не так уж плохи. Как указано в нескольких других ответах, реальная проблема с ними заключается в том, что сегодня ваш глобальный путь к папке может быть одним из нескольких или даже сотен. Если вы пишете быструю одноразовую программу, используйте ее, если это проще. Как правило, хотя, учитывая множественность, даже если вы считаете, что вам нужно, это путь. Не нравится реструктурировать большую сложную программу, которая внезапно нуждается в обсуждении с двумя базами данных.

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

Если вы собираетесь писать в файл и путь к папке изменяется, изменение и запись необходимо синхронизировать. (Как одна из тысячи вещей, которые могут пойти не так, скажем, вы берете путь, затем этот каталог удаляется, затем путь к папке изменяется на хороший каталог, затем вы пытаетесь и записываете в удаленный каталог.) Проблема заключается в том, путь к папке является глобальным или является одним из тысяч используемых в настоящее время программ.

Существует реальная проблема с полями, к которым могут обращаться различные события в очереди, разные уровни рекурсии или разные потоки. Сделать его простым (и упрощенным): локальные переменные хороши, а поля плохие. Но прежние глобальные поля по-прежнему будут полями, поэтому эта (как бы критически важная) проблема не применима к не к состоянию Good или Evil глобальных полей.

Дополнение: Проблемы многопоточности:

(Обратите внимание, что у вас могут быть подобные проблемы с очередью событий или рекурсивными вызовами, но многопоточность, безусловно, хуже всего.) Рассмотрим следующий код:

if (filePath != null)  text = filePath.getName();

Если filePath является локальной переменной или какой-то константой, ваша программа not перестает работать, потому что filePath имеет значение null. Проверка всегда работает. Ни одна другая нить не может изменить ее значение. В противном случае гарантий нет. Когда я начал писать многопоточные программы на Java, я постоянно получал NullPointerExceptions в таких строках. Любой другой поток может изменить значение в любое время, и они часто это делают. Как видно из нескольких других ответов, это создает серьезные проблемы для тестирования. Вышеупомянутое заявление может работать в миллиард раз, получая его через обширное и всестороннее тестирование, а затем взорвать один раз в производстве. Пользователи не смогут воспроизвести проблему, и это не повторится, пока они не убедят себя, что они видят вещи и забывают об этом.

У Globals определенно есть эта проблема, и если вы можете полностью их устранить или заменить на константы или локальные переменные, это очень хорошо. Если на веб-сервере установлен код без состояния, вы, вероятно, сможете. Как правило, все ваши проблемы многопоточности могут быть приняты в базе данных.

Но если ваша программа должна помнить вещи от одного действия пользователя к другому, у вас будут поля, доступные для любых запущенных потоков. Переключение глобального на такое неглобальное поле не поможет надежности.

ответил RalphChapin 11 Mayam12 2012, 01:55:59
1

Так как некоторые другие ответы здесь дают различие между глобальным состоянием mutable и неизменяемым , я хотел бы предположить, что даже неизменяемый глобальные переменные /настройки часто раздражают .

Рассмотрим вопрос:

  

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

Правильно, для небольшой программы это, вероятно, не проблема, но как только вы сделаете это с компонентами в более крупной системе слегка , автоматическое автоматическое тестирование становится сложнее, потому что все тесты ( ~ работает в одном и том же процессе) должен работать с тем же глобальным значением конфигурации.

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

ответил Martin Ba 30 J0000006Europe/Moscow 2017, 15:02:55
0

Когда легко видеть и получать доступ ко всему глобальному состоянию, программисты неизменно делают это. То, что вы получаете, невысказано и трудно отслеживать зависимости (int blahblah означает, что массив foo действительно в любом случае). По существу, практически невозможно поддерживать программные инварианты, поскольку все можно разделить независимо. someInt имеет отношения между otherInt, это трудно управлять и сложнее доказать, можете ли вы напрямую изменить либо в любое время.

Тем не менее, это может быть сделано (путь назад, когда это был единственный способ в некоторых системах), но эти навыки теряются. Они вращаются в основном вокруг правил кодирования и именования - поле перешло по уважительной причине. Ваш компилятор и компоновщик лучше выполняют проверку инвариантов в защищенных /частных данных классов /модулей, чем полагаться на людей, чтобы следовать генеральному плану и источнику чтения.

ответил anon 11 Mayam12 2012, 06:50:31
0

С глобальным состоянием следует учитывать несколько факторов:

  1. Объем памяти программиста
  2. Неизменяемые глобальные переменные /запись раз globals.
  3. Mutable globals
  4. Зависимость от глобальных переменных.

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

Непрерывность /запись один раз, как правило, в порядке, но следите за ошибками последовательности инициализации.

Переменные глобальные переменные часто ошибочно принимают за неизменные глобальные значения â € |

Функция, которая эффективно использует глобальные переменные, имеет дополнительные «скрытые» параметры, что делает реорганизацию более сложной.

Глобальное государство не является злом, но оно приходит к определенной стоимости - используйте его, когда преимущество перевешивает стоимость.

ответил jmoreno 11 Maypm12 2012, 16:19:38
0

Я не собираюсь говорить, хороши или плохи глобальные переменные, но то, что я собираюсь добавить к обсуждению, - это сказать, что если вы не используете глобальное состояние, то вы, вероятно, много тратите впустую памяти, особенно если вы используете classess для хранения своих зависимостей в полях.

Для глобального состояния такой проблемы нет, все глобально.

Например: представьте себе следующий сценарий: у вас есть сетка 10x10, которая выполнена из классовой «платы» и «плитки».

Если вы хотите сделать это способом ООП, вы, вероятно, передадите объект «Совет» каждому «Плитке». Предположим теперь, что «Плитка» имеет 2-байтовые поля типа, хранящие ее координату. Общая память, которую потребуется на 32-битной машине для одной плитки, будет равна (1 + 1 + 4 = 6) байтам: 1 для x-координаты, 1 для координаты y и 4 для указателя на плату. Это дает в общей сложности 600 байт для настройки 10x10 плиток

Теперь для случая, когда Совет находится в глобальной области действия, для каждого объекта, доступного из каждого фрагмента, вам нужно будет получить только 2 байта памяти на каждый фрагмент, то есть байты координат x и y. Это даст всего 200 байт.

Итак, в этом случае вы получаете 1/3 объема использования памяти, если используете только глобальное состояние.

Это, помимо других вещей, я думаю, это причина, по которой глобальный охват по-прежнему остается в (относительно) языках низкого уровня, таких как C ++

ответил spectre 22 MarpmSat, 22 Mar 2014 16:51:00 +04002014-03-22T16:51:00+04:0004 2014, 16:51:00

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132