Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.08.08;
Скачать: CL | DM;

Вниз

Паттерны проектирования и Дельфи.   Найти похожие ветки 

 
Суслик ©   (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 Имхо просто так - для объема.


 
iZEN ©   (2004-07-20 20:41) [41]

/**Суслик ©   (20.07.04 17:17) [34]
Если я, конечно, не ошибаюсь, но ООП появилось имеено в сях, ну или как минимум было разработано (доработано) людьми более близкими к сям, чем к паскалю.
*/

Ха-ха.
ООП появилось намного раньше Смолтока и Си с Паскалем, а именно, в промышленной реализации Симула-67 (1967-70гг.). Эдгар Дейкстра к нему руку приложил таки.


 
Суслик ©   (2004-07-21 10:54) [42]

Позволю себе повторно поднять заданный ранее, но замятый вопрос

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

Пользуется ли кто фабриками классов в стандартном "паттерном" понимании?


 
DiamondShark ©   (2004-07-21 10:58) [43]

"Стандартное паттерное понимание" не связано с какой-то реализацией. Поэтому ответ -- да, пользуемся. И весьма радуемся, что это поддержано языком напрямую.


 
Суслик ©   (2004-07-21 11:04) [44]

Т.е.

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


 
DiamondShark ©   (2004-07-21 11:05) [45]

Именно так.


 
Суслик ©   (2004-07-21 11:08) [46]

спасибо за ответы.

буду спокоен за свои фабрики и заводы.



Страницы: 1 2 вся ветка

Текущий архив: 2004.08.08;
Скачать: CL | DM;

Наверх




Память: 0.61 MB
Время: 0.037 c
1-1090828848
46_55_41_44
2004-07-26 12:00
2004.08.08
Как сделать чтобы в ListBox.Items были разного цвета?


3-1089631143
HMT
2004-07-12 15:19
2004.08.08
Возможно глупый вопрос, как сохранить данные из blob-поля в...


3-1089635884
Satan
2004-07-12 16:38
2004.08.08
Приложение использующее BDE на машине без BDE


4-1088110925
nick_mas
2004-06-25 01:02
2004.08.08
Как скопировать строку в Edit другого приложения?


14-1090232059
Vlad Oshin
2004-07-19 14:14
2004.08.08
Русский язык, контрольная