Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Флейм (http://www.flasher.ru/forum/forumdisplay.php?f=53)
-   -   глобальные переменные зло? (http://www.flasher.ru/forum/showthread.php?t=164069)

filepark 13.08.2011 17:07

глобальные переменные зло?
 
Вопрос теоретический, есть программа претендующая на некоторую универсальность. Имхо, удобно создать класс исключительно для хранения настроек - статических переменных, констант и функций. Они доступны везде и всегда. Но, я слышал мнение, что это зло и все чайники через это проходят.
Почему это плохо?
Какова альтернатива?
Использовать xml для хранения настроек, имхо, неудобно, его могут изменить/удалить, нужно время чтобы его загрузить.

goodguy 13.08.2011 17:14

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

mikhailk 13.08.2011 17:33

Цитата:

Но, я слышал мнение, что это зло и все чайники через это проходят.
Все очень просто.

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

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

А, вообще-то, эта тема - злостный баян. Надо в поиск сходить.

Wolsh 13.08.2011 19:29

Это такой способ мышления, вариант "организации" порядка.. Типа на вопрос "а где у нас..." ответ готов заранее - в шкафу.
Я лично этой логики никогда не мог понять - почему, с какой стати настройки для, например, кнопки, должны храниться в общественном месте и быть доступны всем - текстовым полям, битмапам и прочим левым сущностям? В самой идее "доступно всем и отовсюду" содержится дьявольское зерно Хаоса и полная бессмыслица. Дело не в том, что кто-то злобно поменяет чего-нибудь в чужих настройках. Дело в том, что контроля просто НЕТ. А это значит, что никакой гарантии отсутствия ошибок нет. Это значит, что программист оставил зияющую дыру в структуре ради того, чтобы не напрячь случайно свой мозг обеспечением иерархии и контроля – тем, что и делает из кучи строчек кода Программу.
Я не знаю ни одного случая, когда "зачастую это лучший вариант".

goodguy 13.08.2011 19:58

Wolsh, мысли шире. Допустим есть игра на бокс2д (чисто для примера), в ней тебе постоянно надо переводить пиксели в метры, радианы в градусы и наоборот. Не лучший ли вариант хранить формулы для перевода этих величин в глобальных константах? Вот тебе и один случай

saikspaik 13.08.2011 19:58

filepark
Среди программистов тоже встречаются суеверные, вот они и боятся использовать глобальные переменные :D
Я считаю так - если тебе удобно использовать глобальные переменные - используй, чего огород городить? Не удобно, или дядька начальник запрещает - не используй.
А если говорить о традициях, то таки да - глобальные переменные - зло!!!

expl 13.08.2011 20:18

Цитата:

Имхо, удобно создать класс исключительно для хранения настроек - статических переменных, констант и функций. Они доступны везде и всегда. Но, я слышал мнение, что это зло и все чайники через это проходят.
Почему это плохо?
Какова альтернатива?
Использовать xml для хранения настроек, имхо, неудобно, его могут изменить/удалить, нужно время чтобы его загрузить.
Я бы сказал не "Почему это плохо" (ведь Вы используете и проблем не возникает), а "на что можно напороться".
- например появится 2-я часть системы, которую надо настроить по другому - а конфиг один (не важно xml или статический класс)
- замучаетесь менять эти глобальные переменные до теста и после автоматического теста возвращать "как было", хотя, вроде делают так и не жужжат.
- если речь идет не просто о постоянных данных конфигурации, а о некоторых параметрах состояния хранящихся глобально - то тут еще возникает путаница "... да ёлы палы, какая сволочь эту переменную меняет, я же выставляю false, а здесь она опять true"

Как бороться?
- протаскивать параметры
- протаскивать объекты с параметрами
- протаскивать фабрики, которые правильно параметризуют создаваемые ими объекты
- протаскивать фабрики фабрик
- использовать IoC-контейнеры
- ...
но на самом деле, будет только хуже.

mikhailk 13.08.2011 20:25

Цитата:

Я не знаю ни одного случая, когда "зачастую это лучший вариант".
Например, есть типовой клиент, который запускается в разных сетях, причем в продакшн- и тест-модах. Разумно (на мой взгляд) все настройки для всех сетей свести в один статический класс. При этом, после запуска клиента в нем же запомнить текущий вариант запуска. Далее, в ходе показа интерфейса пользователю мы должны подгонять функционал под особенности текущей социальной сети. Мне кажется простым и удобным решением иметь всегда под рукой (глобально доступными) ApplicationConfig.appMode и ApplicationConfig.socialNetwork. В противном случае мне потребуется передавать эти параметры сквозным образом и я не вижу, что я от этого выиграю. Плюс, может оказаться, что портировании в очередную сеть мне потребуется иметь настраиваемый интерфейс на пятом-седьмом уровне иерархии - придется модифицировать все классы, чтобы дотянуть туда appMode и socialNetwork. В чем выигрыш по сравнению с глобальными параметрами?

На мой взгляд, тут как всегда, главная часть любого инструмента - голова его владельца.

Wolsh 13.08.2011 21:21

goodguy, в моем тексте нет ни слова о константах. Как и в названии темы.
expl, то, что Вы называете "протаскивать", обрисовывает ситуацию, когда архитектура заточена под глобальные переменные, и вдруг Вы решили эти глобальные переменные отменить. А проект уже написан, и Вы начинаете "протаскивать", не спорю. Но когда архитекрура строится изначально иерархически, вложенными модулями, этот процесс естественен и называется настройкой при инициализации. Когда каждому более глубоковложенному модулю передаются все те параметры, которые ему необходимы, чтобы настроить себя и свои составляющие, точно так же при вызове метода (передаче команды этому модулю) ему отдаются необходимые параметры. Это аналог положения метода в классе - Вы можете хранить всё и вся в приватных полях класса, доступных всем методам, и вызывать методы с пустым приемником: foo(); а можете хранить только то, что действительно нужно (например для хендлеров и геттеров/сеттеров), а методы вызывать, передавая им локальные данные: foo(w, h, index); Оба варианта работают, это просто вопрос логики – глупо создавать поле класса лишь для того, чтобы передать данные из одного метода класса в другой, и при этом не быть уверенным, что это значение в поле класса не будет переписано из другого метода до того, как попадет "по назначению". Представьте, что этот класс потребовалось расширить новой функциональностью – где гарантия, что, добавляя новые методы, Вы учтете все связи, что были раньше построены на хранении промежуточных значений в поле класса? И это те же самые архитектуры, на уровне класса показывающие то же, что творится в проекте. ООП предлагает использовать заведомо безопасное решение, чтобы исключить возможность ошибки еще на стадии планирования. Аргументы типа "но я же помню че кого" и "да кому надо там чето менять" выглядят, простите, как детский лепет. Нет смысла задумываться о верной архитектуре, если вы делаете банер. Но если от вашей лени будет зависеть безопасность игроков или денег пользователей, стоит прислушаться к тому, что советуют профессионалы. ООП выглядит смешно и монструозно на проектах "одеть куколку" (привет Сандерсу / Кумаранатунгу). Но когда вы планируете что-то динамическое и развивающееся, от него не скрыться.
Цитата:

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

mikhailk 13.08.2011 21:41

Цитата:

Что разумного иметь настройки всех сетей в приложении, выложенном на Facebook? Я начинаю бояться за свой рассудок.
Это открытая информация, ее можно получить без декомпиляции клиента. Адреса API-серверов соцсетей, адреса собственных серверов, appID приложений. Клиент при загрузке проверяет переданный ему сетью appID и настраивается на сервера, соответствующие этому appID. Не вижу дополнительных проблем (клиенты все равно декомпилят, в сервера все равно долбят и без этого).


Цитата:

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

И все равно я не понял, что я выигрываю от того, что протаскиваю по всему приложению ApplicationConfig.appMode и ApplicationConfig.socialNetwork, вместо того, чтобы работать с ними как с глобальными данными.


Часовой пояс GMT +4, время: 00:45.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.