Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 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.58 MB
Время: 0.062 c
3-1089717775
Vova
2004-07-13 15:22
2004.08.08
как програмно определить виходниє дни недели и ...


1-1090677466
V l a d i m i r
2004-07-24 17:57
2004.08.08
TEdit: разрешить ввод только чисел.


4-1088157926
AleXqwq
2004-06-25 14:05
2004.08.08
number o drives


3-1089788452
leonidus
2004-07-14 11:00
2004.08.08
Работа 2-х компов с одной БД


14-1090575127
REP
2004-07-23 13:32
2004.08.08
Пятно от шариковой ручки





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский