Форум: "Потрепаться";
Текущий архив: 2004.08.08;
Скачать: [xml.tar.bz2];
ВнизПаттерны проектирования и Дельфи. Найти похожие ветки
← →
Суслик © (2004-07-19 18:56) [0]Это что-то типа обсуждения.
Читаю книгу "Паттерны проектирования" авторы Гамма и товарищи.
Настолько я понимаю, данная книга считается классической в разделе паттернов.
Знает ли кто-нибудь статьи о преломлении паттернов в дельфи?
Очень интересно было бы почитать мнение серьезных людей на эту тему. Т.е. не о том, как реализовать (думаю проблем быть не должно), а о роли паттернов в рамках дельфи.
Вопрос вызван тем, что указанная книга написана отталкиваясь от ООП в си++. Думаю, что со мной можно согласится в том, что ООП в СИ и в Дельфи реализованы несколько по разному. В частности в СИ нет виртуальных статических методов. В дельфи есть. Некоторые паттерны могли бы быть реализованы проще или иначе. А некоторые паттерны просто отсутствовать. Вот об анализе этого преломления паттернов в зеркале Дельфи и хотелось бы почитать.
← →
Суслик © (2004-07-19 18:59) [1]Если таких статей нет, то можно и просто пообсуждать (если, конечно, кому-то есть что сказать по этому поводу)
← →
Sergey Masloff (2004-07-19 20:54) [2]Посмотрев код VCL найдешь немало следов паттернов. Но, с другой стороны, не надо их идеализировать. Некоторые паттерны я использовал много лет прежде чем узнал что это паттерны ;-) Кстати советую прочитать еще книгу "Антипаттерны" пржде чем начинать фанатеть от оных ;-)
← →
Суслик © (2004-07-20 10:45) [3]
> Некоторые паттерны я использовал много лет прежде чем узнал
> что это паттерны ;-)
Аналогично :))
> фанатеть от оных
Это делать и не собраюсь (пока). Интересно мнение людей...
Что за книга "Антипаттерны"? Название, автор?
=============================================================
Предлагаю пообсуждать конкретно паттерн singleton.
Реализовывал ли его кто и как?
← →
Суслик © (2004-07-20 11:03) [4]В действительности меня интересует несклько моментов:
1. Как выполняется инициализация. Ясно, что можно делать через NewInstance c использованием переменной под implementation - если уже не первый вызов конструктора, то возвращаем значение указанной переменной и ставим флажок пропуска тела конструктора
2. Как с удалением. Очевидно, что нужно также перекрывать и FreeIntance. Я пока сделал также поведение этого метода в зависимости от флажка - т.е. внешним образом устанавливаешь флажок, тогда метод уничтожает объект, если не установишь флажок - FreeInstance не вызывает inhereited.
← →
Mike_Goblin © (2004-07-20 11:46) [5]Creating a real singleton class in Delphi 5 http://community.borland.com/article/0,1410,22576,00.html
В Delphi 8 и 7.1 появилась возможность реализовать синлетон проще, так как появились статические переменные класса
Неплохая страничка по паттернам
http://delphi.about.com/library/weekly/aa010201a.htm
← →
Суслик © (2004-07-20 11:48) [6]
> В Delphi 8 и 7.1 появилась возможность реализовать синлетон
> проще, так как появились статические переменные класса
ух ты! Здорово - сильно не хватало.
← →
Суслик © (2004-07-20 12:52) [7]У меня сообственно вопрос про singleton возник по следующим причинам.
Думаю со мной можно согласится, что дельфи имеет следующие отклонения от ООП в си (могу ошибаться, т.к. си знаю плохо):
1. Есть метаклассы
2. Классы по сути есть сущности мета классов.
Т.е. в дельфи как бы есть мета классы, классы это экземплятры метаклассов, а объекты - экземпляры классов.
В сях же, насколько я понимаю проще - есть классы, есть экземпляры классов - объекты. Все. Именно поэтому там нет виртуальных статических функций, а также виртуальных конструкторов - это там надо реализовывать через фабрики классов.
В дельфи я фактически часто пользуюсь singleton - через классовые методы с хранением данных ПОД implementation в модуле, где реализован класс.
Ну типаtype
TSettins = class
public class function SomeOption1: Boolean;
public class function SomeOption2: Boolean;
public class function SomeOption3: Boolean;
public class procedure Init;
end;
implementation
var
fuSomeOption1: Boolean;
...
class function TSettings.SomeOption1: Boolean;
begin
Result := fuSomeOption1;
end;
...
class procedure Init();
begin
инициализация fuSomeOption1
...
end;
end.
Использовать соответственно такTSettings.SomeOption1
Я никогда не испытывал страха перед такой конструкцией (через стат. переменные). В сях ожно делать также - но тогда в следствие отсутствия виртуальных статических методов там закрыта возможность полифомизма. В дельфи мне ничего не срашно - метаклассы и вирт. методы класса со всем справятся :)))
Хотелось бы узнать, что кто думает про такую конструкцию и почему надо/не надо использовать singleton вместо этого?
← →
Mike_Goblin © (2004-07-20 15:21) [8]Синглетон - это класс, экземпляр которого можно создать один и только один раз
Где это применяется и зачем нужно уже другой вопрос.
С точки зрения приведенного определения Ваше решение не является синглетоном. Ничто не мешает мне создать кучу экземпляров TSettings.
>Хотелось бы узнать, что кто думает про такую конструкцию и
Конструкция будет работать :)
>почему надо/не надо использовать singleton вместо этого?
Огласите, пожалуйста, конечную цель применения этой конструкции, другими словами сформулируйте решаемую задачу. Тогда можно говорить о путях решения задачи, их недостатках и достоинствах.
Пока виден один недостаток - необходимость явного вызова метода Init перед использованием класса, но он устраним.
← →
Sandman25 © (2004-07-20 15:38) [9][8] Mike_Goblin © (20.07.04 15:21)
Если бы методы были виртуальными, можно было бы заподозрить использование class of TSettings, а в таком виде, как сейчас, класс является бесполезным хранилищем отдельных процедур.
← →
Sandman25 © (2004-07-20 15:41) [10]Кстати, в текущем виде вообще нужно запретить создание экземпляров указанного класса.
← →
Суслик © (2004-07-20 15:50) [11]
> как сейчас, класс является бесполезным хранилищем отдельных
> процедур.
я попросил бы! :)))
--------------
Конечная цель имхо ясна из названия - хранение настроек. Не суть важно каких.
> Ничто не мешает мне создать кучу экземпляров TSettings.
Конечно ничего - но операции у них от этого все равно будут работать одинаково.
---------------------------
вообще говоря в реализации через NewInstance тоже ничего не мешает переопределить в потомке NewInstance и убарть фактически сингтонность.
>
> Если бы методы были виртуальными, можно было бы заподозрить
> использование class of TSettings
так я тоже иногда делаю.
> Кстати, в текущем виде вообще нужно запретить создание экземпляров
> указанного класса.
да можно было бы.
-------------------
эх блин - почему в дельфи конструктор public :((( Нет бы как в сях - сделал protected и никто извне не сможет создать объект через конструктор.
← →
Суслик © (2004-07-20 15:53) [12]
> Пока виден один недостаток - необходимость явного вызова
> метода Init перед использованием класса, но он устраним.
Ну это понятно можно сделать в initialization.
← →
Sandman25 © (2004-07-20 16:02) [13]Можно новый конструктор объявить private (+reintroduce), тогда конструктор будет недоступен.
← →
Суслик © (2004-07-20 16:06) [14]
> Sandman25 © (20.07.04 16:02) [13]
вроде не поможет.
Из описания reintroduce.
The reintroduce directive suppresses compiler warnings about hiding previously declared virtual methods. For example,
← →
Суслик © (2004-07-20 16:10) [15]> Sandman25 © (20.07.04 16:02) [13]
да и вообще - скрытие методов предка противоречи ООП - потомок должен поддерживать интерфейс предка...
← →
Sandman25 © (2004-07-20 16:20) [16]А так?
interface
type
TSingle = class
private
constructor Create(var Single: TSingle); overload;
public
class function GetMe: TSingle;
constructor Create; overload;
end;
implementation
uses
SysUtils;
{ TSingle }
var
Single: TSingle;
constructor TSingle.Create;
begin
raise Exception.Create("Do not call create!");
end;
constructor TSingle.Create(var Single: TSingle);
begin
Single := Self;
end;
class function TSingle.GetMe: TSingle;
begin
if not Assigned(Single) then
TSingle.Create(Single);
Result := Single;
end;
← →
Суслик © (2004-07-20 16:24) [17]
> Sandman25 © (20.07.04 16:20) [16]
> А так?
все равно можно обойти :)))
создать через метакласс
var
c: tclass;
begin
c := tsingle;
o := c.create();
// создаться именно класс tstingle, а консттруктор выполнится из предка.
end;
← →
Sandman25 © (2004-07-20 16:32) [18][17] Суслик © (20.07.04 16:24)
Ну и что? Я же не запрещаю создавать TObject :-)
То, что будет создано, не будет являться TSingle, потому что конструктор не виртуальный.
А вот если
type
TM = class of TSingle;
procedure TForm1.bt2Click(Sender: TObject);
var
M: TM;
begin
M := TSingle;
M.Create;
end;
то получим ругань.
← →
Sandman25 © (2004-07-20 16:34) [19]Забавно, что M: TClass и M.Create.ClassName возвращает "TSingle", хотя TSingle.Create не был вызван. Я бы назвал это глюком реализации метаклассов
← →
Суслик © (2004-07-20 16:36) [20]
> Ну и что? Я же не запрещаю создавать TObject :-)
Погодите, погодите.
Мое утверждение, что ваш код TSingle не гарантурет от создания второй копии. Пример я привел. В моем примере будет создан объект класса TSingle, но не будет выполнен конструктор. Т.е. ваш код не запрещает вызов конструктора.
← →
Суслик © (2004-07-20 16:37) [21]
> Sandman25 © (20.07.04 16:34) [19]
> Забавно, что M: TClass и M.Create.ClassName возвращает "TSingle",
> хотя TSingle.Create не был вызван. Я бы назвал это глюком
> реализации метаклассов
Вот и я об этом. Ничего удивительного нет.
Create это просто метод с припиской contstructor. Эта и только эта приписка говорит о том, что нужно сделать посдедовательность вызовов, которая приводит к созданияю объекта. Create не отвечает за создание - это метод...
← →
DiamondShark © (2004-07-20 16:39) [22]
> Предлагаю пообсуждать конкретно паттерн singleton.
>
> Реализовывал ли его кто и как?
Паскальный модуль и есть самый натуральный синглетон.
И ничего тут изобретать не надо.
← →
Суслик © (2004-07-20 16:41) [23]
> DiamondShark © (20.07.04 16:39) [22]
>
> > Предлагаю пообсуждать конкретно паттерн singleton.
> >
> > Реализовывал ли его кто и как?
>
> Паскальный модуль и есть самый натуральный синглетон.
> И ничего тут изобретать не надо.
Во! Хорошая мысль. Мне она тоже приходила. Хотелось бы от кого нить услышать.
Понимаете, основаная мысль, почему я завел эту ветку это понять на фига мне, программисту на дельфи, нужно использовать паттерны, если сам язык уже их предоставляет. И второе - может быть сдедовать все-таки надо, т.к. не далек момент, когда придется сваливать с дельфи на что-то сиподобное и тогда будет легче переводить?
← →
Sandman25 © (2004-07-20 16:49) [24]interface
type
TSingle = class
public
class function GetMe: TSingle;
class function NewInstance: TObject; override;
end;
implementation
uses
SysUtils;
{ TSingle }
var
Single: TSingle;
IsCreationAllowed: Boolean;
class function TSingle.GetMe: TSingle;
begin
if not Assigned(Single) then
begin
IsCreationAllowed := True;
try
Single := TSingle.Create;
finally
IsCreationAllowed := False;
end;
end;
Result := Single;
end;
class function TSingle.NewInstance: TObject;
begin
if not IsCreationAllowed then
raise Exception.Create("Do not call create!");
Result := inherited NewInstance;
end;
← →
Sandman25 © (2004-07-20 16:51) [25]Только не надо говорить, что можно будет сделать объект в другом потоке, а то ведь я могу и объект синхронизации при доступе к IsCreationAllowed использовать :)
← →
Суслик © (2004-07-20 16:56) [26]1. Про потоки не буду.
2. Ну это понятно. Но прикиньке как было бы здорово, если бы на стадии компиляции сам компилятор говорил о недоступности констрктора, т.к. он private, ну как в сях. Согласитесь, так красивее.
3. Я так или почти так обычно и делаю. Т.е. на уровке NewInstance запрещаю создавать вторую копию, контроль делаю через классовы метод. Ну в общем как у вас.
Но в сях как-то красивее. :((
← →
Sandman25 © (2004-07-20 16:58) [27][26] Суслик © (20.07.04 16:56)
Согласен. Метаклассы в Delphi могут быть не только полезными, но и вредными :(
← →
DiamondShark © (2004-07-20 16:58) [28]
> Суслик © (20.07.04 16:41) [23]
> Понимаете, основаная мысль, почему я завел эту ветку это
> понять на фига мне, программисту на дельфи, нужно использовать
> паттерны, если сам язык уже их предоставляет.
Надо пользоваться родными средствами языка, а не притягивать за уши чужеродные конструкции.
> И второе -
> может быть сдедовать все-таки надо, т.к. не далек момент,
> когда придется сваливать с дельфи на что-то сиподобное и
> тогда будет легче переводить?
Совершенно смехотворный аргумент. А со всем кодом что тогда делать?
← →
Суслик © (2004-07-20 17:00) [29]Резюмируя обсуждение хотел бы в очередной раз уточнить тему: какую роль играют паттерны, разработанные в основном для сей, в дельфи. Приветствуются ссылки, мнения. Приведенную ссылку по реализации singleton очень интересно было почитать. Но к сожалению ничего нового - это и так ясно. Real singleton не сделаешь без Newinstance (imho).
А вот например фабрики классов? Вот спрашивается зачем мне, программеру на дельфи, нужно создавать экземпляр объекта, если я могу опять же обойтись метаклассами и виртуальными методами классов? Т.е. реализовать полиформизм не на уровне объектов (как в это предлагается делатьс в сях), а на уровне классов.
← →
Суслик © (2004-07-20 17:02) [30]
> Совершенно смехотворный аргумент. А со всем кодом что тогда
> делать?
Это провокация в стиле сами знаете кого :))))
Ну типа так легче мнение получить от кого-то.
Я в общем также считаю - родные средства должны быть использованы.
Если придется переползать куда-то, то все равно все заново писать придется :((
← →
DiamondShark © (2004-07-20 17:03) [31]Если в языке есть -- незачем городить огород.
← →
Суслик © (2004-07-20 17:03) [32]
> Sandman25 © (20.07.04 16:58) [27]
> [26] Суслик © (20.07.04 16:56)
>
> Согласен. Метаклассы в Delphi могут быть не только полезными,
> но и вредными :(
Очень интересное мнение. Мне в голову приходила мысть - может быть в сях не спроста не сделано метаклассов? Может в этом есть глубокая мысль (пока мне недоступная)?
← →
DiamondShark © (2004-07-20 17:08) [33]
> Мне в голову приходила мысть - может быть в сях не спроста
> не сделано метаклассов? Может в этом есть глубокая мысль
> (пока мне недоступная)?
Мало ли чего нет. У меня вот нет зелёного "Запорожца".
Есть ли в этом глубокий смысл?
;)
← →
Суслик © (2004-07-20 17:17) [34]
> Мало ли чего нет. У меня вот нет зелёного "Запорожца".
> Есть ли в этом глубокий смысл?
Если я, конечно, не ошибаюсь, но ООП появилось имеено в сях, ну или как минимум было разработано (доработано) людьми более близкими к сям, чем к паскалю. Явно они не дураки были. Может стоит подумать почему они не сделали то-то и то-то.
Может, оказаться, и совсем все иначе - дельфовы ООП это прогрессивно, а в сях - уже старело :))
← →
DiamondShark © (2004-07-20 17:38) [35]
> Если я, конечно, не ошибаюсь, но ООП появилось имеено в сях
Вы, конечно, ошибаетесь.
> Может стоит подумать почему они не сделали то-то и то-то.
Они ещё много чего не сделали. Например, нормальной модульности.
Что за манечка такая, всё с сями сравнивать? Весь мир медленно и болезненно пытается избавиться от тяжкого наследия сей.
← →
Суслик © (2004-07-20 17:55) [36]
> DiamondShark © (20.07.04 17:38) [35]
Конечно, жаль, что не прав.
Ну да ладно.
Я их не знаю, особливо и не стремлюсь.
Посмотрим, что мы все будем делать без тяжкого наследния, когда борланд загнется :))
← →
DiamondShark © (2004-07-20 18:23) [37]А при чём тут борланд? Даже без учёта того, что загибание борланда вовсе не означает мнгновенный исход и покаяние всех дельфистов.
Что, кроме сей и дельфей больше нет ничего?
← →
Mystic © (2004-07-20 18:38) [38]Если я, конечно, не ошибаюсь, но ООП появилось имеено в сях
http://www.computer-museum.ru/histsoft/oophist.htm
Smalltalk появился на 10 леть раньше С++. Кстати, можно вспомнить слова Алана Кея, который говорил, что когда он придумывал термин объктно-ориентированое программирование, то он не имел в виду С++.
← →
Суслик © (2004-07-20 18:42) [39]
> Mystic © (20.07.04 18:38) [38]
битая ссылка.
спасибо поищу.
> то он не имел в виду С++.
врет наверное?
← →
Суслик © (2004-07-20 19:08) [40]Но он то может и не имел в виду, сейчас это не важно. Важно то, что авсолютно все книги, которые я читаю или начал читать в последнее время по проектированию используют именно с++.
В паттернах есть немного про smalltalk Имхо просто так - для объема.
Страницы: 1 2 вся ветка
Форум: "Потрепаться";
Текущий архив: 2004.08.08;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.036 c