Форум: "Прочее";
Текущий архив: 2013.10.06;
Скачать: [xml.tar.bz2];
ВнизНужен третейский судья :) Найти похожие ветки
← →
Rouse_ © (2013-04-22 20:55) [0]Итак спор:
есть отдельный не связанный с базовым проектом юнит, который может использоваться в множестве проектов.
В юните реализован некий класс TFoo
оппонент предлагает решение в виде:{$IFDEF SELF_INITIALIZE}
var
Foo: TFoo = nil;
{$ENDIF}
...
initialization
{$IFDEF SELF_INITIALIZE}
Foo := TFoo.Create;
{$ENDIF}
finalization
FreeAndNil(Foo);
мной предлагается более простое решение на базе синглтона:function Foo: TFoo;
implementation
var
_Foo: TFoo = nil;
function Foo: TFoo;
begin
if _Foo = nil then
_Foo := TFoo.Create;
Result := _Foo;
end;
...
initialization
finalization
FreeAndNil(Foo);
Объясняю оппоненту - в данном случае не нужно заморачиваться с перекомпиляцией, тем более в случае использования юнита в рамках нескольких проектов.
Оппонент отвечает тем, что в случае реализации расширенного класса TFoo2 = class(TFoo) в модуле Foo2, ему достаточно не объявлять директиву SELF_INITIALIZE и тогда он может объявить очередную глобальную переменную видаvar
Foo: TFoo2 = nil;
и с этим будет более удобно работать.
Я отвечаю что это не верная идеология разработки, ибо глобальная Foo в данный момент уже зарезервированна в конкретном модуле, как и сам класс TFoo, который тоже нельзя переобъявить в новом юните, ибо он уже обьявлен.
Оппонент отвечает что моя идеология не верна, ибо нельзя объявлять синглтон на требуемую переменную :)
В итоге уперлись :)
Рассудите, плз, ибо толь я уже не умею объяснять как правильно, или я соовсем отстал :)
← →
___ (2013-04-22 21:05) [1]Удалено модератором
← →
DevilDevil © (2013-04-22 21:10) [2]Розыч, не стоит отталкиваться от мнения "если это принято, значит это правильно"
В данном случае подойдёт сравнение плюсов и минусов
Плюс "синглетона":
- доступно из коробки
Минусы "синглетона":
- возможный конфликт имён
- функция вместо переменной
Плюс дифайна:
- доступно из коробки + опциональность (может кому-то не нужен глобальный объект Foo)
Минус дифайна:
- нужно задать дифайн SELF_INITIALIZE в опциях проекта
По моему в данном случае дифайн победитель
← →
картман © (2013-04-22 21:12) [3]только монетка
← →
имя (2013-04-22 21:15) [4]Удалено модератором
← →
Rouse_ © (2013-04-22 21:18) [5]
> Минусы "синглетона":
> - возможный конфликт имён
> - функция вместо переменной
Это не минусы, но плюсы, да и как можно на конфликт то выйти?
> По моему в данном случае дифайн победитель
Имхо наоборот.
А из плюсов - использование модуля в 10 проектах к примеру, под каждый рекомпил делать, чтоб директива скушалась?
← →
Ega23 © (2013-04-22 21:20) [6]Удалено модератором
← →
Rouse_ © (2013-04-22 21:21) [7]
> Ega23 © (22.04.13 21:20) [6]
Там у тебя проблема была с тем что класс настроек был синглтоном, это никак с этим не связано, тем более что под тебя спецом все переделали.
← →
Rouse_ © (2013-04-22 21:23) [8]
> DevilDevil © (22.04.13 21:10) [2]
Зы, Дим, ты кстати аська выйди-то, раз на мыло не реагируешь, а то ты мне еще лично персонально нужен :)
← →
Ega23 © (2013-04-22 21:26) [9]
> Там у тебя проблема была с тем что класс настроек был синглтоном
Не только, там ещё с лицензированием что-то было.
А, впрочем, фиг с ним.
По-сабжу:
есть третье решение:
unit FooUnit;
type
TFoo = class
.....
end;
end.
unit SingletonFooUnit;
function Foo: TFoo;
....
end.
← →
картман © (2013-04-22 21:31) [10]
> тем более что под тебя спецом все переделали.
Free вызывал постоянно?))
← →
DVM © (2013-04-22 21:36) [11]Я за второй вариант
← →
Ega23 © (2013-04-22 21:37) [12]
> Free вызывал постоянно?))
Не, там просто дофига всего тянулось ненужного
← →
oxffff © (2013-04-22 21:42) [13]А постановку задачи можно? Может все проще можно сделать.
P.S. Представьте себе структуру на Java(а поскольку в java нет структур, то это класс), смысл в которой это набор данных. Я объявил как набор public полей.
Мой код увидел разработчик на Java и обернул это все сеттерами и геттерами (напрямую работающие с каждым полем) и свел поля в private. Я его спросил, а зачем? Мне ответили бо инкапсуляция.
← →
oxffff © (2013-04-22 21:46) [14]По сабжу мне не нравится ни тот ни другой вариант.
Переменную состояние нужно как минимум внести в класс как статическую(class var), чтобы не захламлять namespace
← →
oxffff © (2013-04-22 21:53) [15]
> есть отдельный не связанный с базовым проектом юнит, который
> может использоваться в множестве проектов.
> В юните реализован некий класс TFoo
1. А зачем для этих целей вообще создавать объект?
2. Быть может все можно решить статическими методами класса?
← →
oxffff © (2013-04-22 22:04) [16]
> Переменную состояние нужно как минимум внести в класс как
> статическую(class var), чтобы не захламлять namespace
в смысле class function TFoo.getInstance();static;
Но все же [15].
← →
vuk © (2013-04-22 22:12) [17]Как вариант - методы класса + переменная типа class of TFoo и работать через эту переменную. Тогда можно будет подменить реализацию, буде оно понадобится.
← →
картман © (2013-04-22 22:15) [18]ну, тогда кубик
← →
Rouse_ © (2013-04-22 22:21) [19]
> oxffff © (22.04.13 21:53) [15]
> 1. А зачем для этих целей вообще создавать объект?
Допустим это класс, работающий с файлом в блокирующем режиме, в статике хэндл хранить негде будет (ну если не переоткрывать его каждый раз или не использовать глобалку, но тогда зачем вообще синглтон?).
← →
oxffff © (2013-04-22 22:26) [20]
> Допустим это класс, работающий с файлом в блокирующем режиме,
> в статике хэндл хранить негде будет
Привет, Саша.
Так есть статические переменные класса. Зачем выделять память в куче, если по сути это класс утилит, который подсоединяется по запросу с использованием uses. То есть насколько я понял использование класса, как namespace, для группировки методов.
Но!!!
Все же давай с постановки задачи, а то так можно далеко уйти.
← →
oxffff © (2013-04-22 22:32) [21]
> но тогда зачем вообще синглтон
Я то мат. часть читал, да вот из паттернов использую "Посетитель".
И то уже не считаю паттерны как панацею.
А больше стал склоняться к функциональному программированию.
← →
Дмитрий С © (2013-04-22 22:39) [22]Я думаю задача - побольше кофе попить, да покурить :)
С директивами вариант сложнее для понимания. К тому же поддерживать класс который может быть синглетоном самоинициализирющимся, а может быть и нет - тоже себе задачка.
> var
> _Foo: TFoo = nil;
Подчеркивание перед именем - бррр. Это этот класс синглетон, я бы его переменную сделал бы классовой (или статической, не знаю как правильно называется).
Кстати, а есть смысл инлайнить функцию Foo?
← →
DVM © (2013-04-22 22:55) [23]Директивы условной компиляции без крайней необходимости - это вообще зло. С ними зачастую очень сложно понять что происходит а коде, потому как тут читаем тут не читаем, а вон в тот кусочек в отдельном инклюде рыбу заворачивали. Здесь они не нужны.
Сам я чаще практиковал второй вариант, но в последнее время стал избегать глобальных переменных и обычных (не классовых и не методов) функций, стараясь все вносить внутрь классов.
← →
DevilDevil © (2013-04-22 23:07) [24]> Rouse_ © (22.04.13 20:55)
Поймал себя на мысли, что если бы я проектировал библиотеку, в которой должен быть один глобальный объект - я бы просто объявил глобальную переменную как Application: TApplication и создавал/удалял бы в initialization/finalization
Практика применения функций-синглетонов у меня небольшая. Но возможно это где-то оправдано
Если я правильно представляю себе библиотеку, о которой ты говоришь :), то использование дифайна там обусловлено опциональным использованием глобального объекта (специфика проекта). Я уверен, если бы не было требования опциональности, автор просто бы сделал глобальную переменную без всяких синглетонов
← →
Rouse_ © (2013-04-22 23:36) [25]
> oxffff © (22.04.13 22:26) [20]
Пфф, в аську стучись - а то всю интригу раскрою :)
← →
Rouse_ © (2013-04-22 23:37) [26]
> DVM © (22.04.13 22:55) [23]
> Директивы условной компиляции без крайней необходимости
> - это вообще зло
О!!! Об чем и речь...
← →
Rouse_ © (2013-04-22 23:41) [27]
> DevilDevil © (22.04.13 23:07) [24]
Нет, немного не верно, основная концепция зиждется на том что модуль может использоваться в разных проектах, где есесно дефайны различны, что вводит некое неудобство с рекомпиляцией. А если модули распространяются еще и в виде DCU по фрилансерам - то там вообще потеряешься кому чего давать.
← →
DevilDevil © (2013-04-23 00:12) [28]> Rouse_ © (22.04.13 23:41) [27]
ну... я как-то не выдаю dcu фрилансерам :)
по поводу рекомпиляции - есть отличный пункт меню "Build"
очень помогает :)
← →
Германн © (2013-04-23 02:13) [29]
> по поводу рекомпиляции - есть отличный пункт меню "Build"
Так о нем и шла речь. Перекомпилировать модуль при изменении только Conditional Defins иначе никак не возможно. Но эта невозможность однозначно приводит к тому, что билдить нужно заново весь проект. Что создаёт некие неудобства.
← →
Макс Черных (2013-04-23 02:18) [30]
> Оппонент отвечает что моя идеология не верна, ибо нельзя
> объявлять синглтон на требуемую переменную :)
Саня, во-первых, можно. И кучей способов. Например с помощью дженериков. А во-вторых, когда тип глобальной переменной зависит от директив - это даже не зло, а ад адский. Уже же много говорилось о том, что директивы компилера надо использовать по минимуму и только тогда, когда нет других вариантов. А то кто-то будет опять громко ругаться :)
← →
DevilDevil © (2013-04-23 02:35) [31]> Германн © (23.04.13 02:13) [29]
как часто ты перекомпилируешь разные проекты ?
лично у меня правило когда открываю проект - перебилдить его. Чтобы не использовать кешированые dcu, которые были созданы с неизвестными опциями компилятора и дифанами. Потом при работе над проектом просто его компилируешь
я не знаю что вы бучу подняли
для меня обращение к экземпляру каждый раз по функции страшнее
← →
Германн © (2013-04-23 02:35) [32]
> Rouse_ © (22.04.13 20:55)
Саш, а ведь первый пример из топика просто не скомпилирутся, если в дополнительных условиях не будет "SELF_INITIALIZE".
← →
Германн © (2013-04-23 02:43) [33]
> DevilDevil © (23.04.13 02:35) [31]
>
> > Германн © (23.04.13 02:13) [29]
>
> как часто ты перекомпилируешь разные проекты ?
Пересобираю проекты (вроде именно так принято переводить на русский Build Projects) постоянно. Сейчас уже не часто, ибо те проекты сейчас уже редко изменяются. Но если изменяются, то тогда пересобираю все шесть. :)
← →
Германн © (2013-04-23 02:56) [34]
> Rouse_ © (22.04.13 23:36) [25]
>
>
> > oxffff © (22.04.13 22:26) [20]
>
> Пфф, в аську стучись - а то всю интригу раскрою :)
А нафига тогда было нужно задавать вопрос тут?
← →
Юрий Зотов © (2013-04-23 05:02) [35]Я бы использовал синглтон, только не в такой редакции. В такой редакции это не синглтон, поскольку никто не мешает вызвать конструктор напрямую и насоздавать кучу экземпляров. Чтобы этого не было, надо перекрыть NewInstance и FreeInstance. И создавать экземпляр синглтона нужно при первом обращении к нему, а не в initialization.
← →
Ega23 © (2013-04-23 08:14) [36]
> как часто ты перекомпилируешь разные проекты ?
Раз в сутки это билд-сервер делает. Как минимум.
← →
Kilkennycat © (2013-04-23 08:19) [37]Я за более простое решение Розыча, ибо исчо Оккам запрещал плодить сущности без необходимости.
← →
sniknik © (2013-04-23 08:45) [38]делал так, с условной компиляцией для общего модуля для клиента и сервера.... глупо пытался "минимизировать объем программы", чтобы в сервере не создавалось визуальных объектов которые все одно там не используются.
в итоге уже через неделю сам путался где, что и какая версия скомпилированного лежит (когда пишешь клиент сервер открыты оба проекта), + возникали непонятные глюки, приходилось билдить чуть ли не каждый раз.
в начале второй плюнул и разнес проверку на нил и создание объектов по функциям, т.е. "а ля второе решение" только не в инициализации. смысл - в сервисе функция не вызывается лишнего обьекта не создается, не вызываемые функции оптимизатор выкидывает сам... путаницы нет.
резюме - если твой оппонент будет сам пользоваться юнитом минимум в паре проектов одновременно с разными "настройками", то через некоторое время поймет "проблему", если же чисто теоретизирования, или использует в 1м то не испытав неудобств (один раз сбилдить не проблема) то останется при своем мнению что бы ты не говорил (и мы).
← →
sniknik © (2013-04-23 08:50) [39]> что в случае реализации расширенного класса TFoo2 = class(TFoo) в модуле Foo2
а он не ставит себе перед сном стакан воды рядом? ну, в случае если ночью проснется и захочет пить.
(© идея из какого то анекдота)
← →
Dimka Maslov © (2013-04-23 09:07) [40]Я всегда пользуюсь вторым вариантом, и только исходя из принципа "объект должен создаваться в тот момент, когда он впервые понадобился". Это значительно ускоряет начальную загрузку приложения, особенно в случаях, когда таких глобальных объектов множество и они потребляют значительные ресурсы. Что же касается соображения "функция вместо переменной", тот тут могут возникнуть некоторые сложности при отладке, не более того.
Страницы: 1 2 3 4 5 6 7 вся ветка
Форум: "Прочее";
Текущий архив: 2013.10.06;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.006 c