Форум: "Основная";
Текущий архив: 2004.12.05;
Скачать: [xml.tar.bz2];
ВнизSingleton Найти похожие ветки
← →
Fktrc © (2004-11-23 05:10) [0]Можно ли в Delphi создать единственный экземпляр класса на все приложение? Т.е. чтобы при попытках создать второй выдавалась либо ошибка компиляции, либо рантайм ошибка. По-моему, такие объекты называют singleton, хотя могу и ошибаться.
Пока приходит в голову только создание какого-л именованного объекта ядра в конструкторе объекта. Но нет ли другого способа, изящнее?
← →
MBo © (2004-11-23 07:19) [1]Один из путей реализован в модуле ClipBrd для ClipBoard
← →
Bel © (2004-11-23 09:45) [2]Можно.
Можно еще вместо ошибки при попытке создания второго экземпляра подменить его уже созданным первым экземпляром. Надо перекрыть методы NewInstance и FreeInstance. Ну, и счетчик ссылок на объект.
← →
Fktrc © (2004-11-23 09:53) [3]2Bel
Примерчик перекрытия методов NewInstance и FreeInstance или ссылку на таковой можете дать? А я пока по гуглю и яндексу побегаю...
← →
Bel © (2004-11-23 10:23) [4]Держи, разбирайся. Когда-то сам копался с этим.
unit uSingleton;
interface
type
TSingleton = class (TObject)
private
FCount: Integer;
public
class function NewInstance: TObject; override;
procedure FreeInstance; override;
function Test1(SomeText: String): Integer;
function Test2(SomeText: String): Integer;
end;
implementation
uses Dialogs, SysUtils;
var
gSingle: TSingleton;
class function TSingleton.NewInstance: TObject;
begin
if gSingle <> nil then begin
Result := gSingle;
Inc(gSingle.FCount);
end else begin
Result := inherited NewInstance;
gSingle := TSingleton(Result);
gSingle.FCount := 1;
end;
end;
procedure TSingleton.FreeInstance;
begin
if FCount = 0 then begin
inherited;
gSingle := nil;
end else
Dec(FCount);
end;
function TSingleton.Test1(SomeText: String): Integer;
begin
ShowMessage(SomeText + ": Test1 adr: " + IntToStr(Integer(Self)) + " counter: " + IntToStr(FCount));
Result := 1;
end;
function TSingleton.Test2(SomeText: String): Integer;
begin
ShowMessage(SomeText + ": Test2 adr: " + IntToStr(Integer(Self)) + " counter: " + IntToStr(FCount));
Result := 2;
end;
end.
← →
Bel © (2004-11-23 10:30) [5]:) Только сейчас увидел, что в FreeInstance косяк со счетчиком. Ну да ладно, сам разберешься.
← →
Amoeba © (2004-11-23 10:33) [6]На сайте "Королевство дельфи" http://www.delphikingdom.com найдешь статью, специально посвященную этому вопросу.
← →
Reindeer Moss Eater © (2004-11-23 10:37) [7]Пока приходит в голову только создание какого-л именованного объекта ядра в конструкторе объекта. Но нет ли другого способа, изящнее?
Есть один класс и один его конструктор и один паскалевский модуль в котором все это реализовано. И глобальные переменные модуля на весь процесс.
Какие ядра? Какие пушки?
Есть способ не изящнее, а проще.
← →
Fktrc © (2004-11-23 10:47) [8]Принято к сведению.
Всем спасибо.
← →
KSergey © (2004-11-23 11:07) [9]Вообще, как как-то сказал Reindeer Moss Eater ©, "модуль в паскале - и есть уже синглетон! Зачем изобретать что-то еще??"
И я с ним согласен ;)
← →
Суслик © (2004-11-23 11:49) [10]Мне всегда хватало
tsingleton = class
class function SomeFunction: Integer;
class procedure SomeProcedure();
...
end;
Значения можно хранить под implementation.
Использовать TsingleTon.SomeProcedure.
Отличие от singleton в том, что мой tsingleton всегда есть ровно онид по определению и его убить нельзя.
← →
Palladin © (2004-11-23 11:52) [11]Он не прав. Singletone это во-первых, контроль самого программиста. Модуль не есть Singletone. Класс объявлен, в interface, можно создать сколько угодно объектов этого класса. Другое дело когда при вызове конструктора возвращается один и тот же объект. Это и есть Singletone.
Clipboard, это не Singletone. Так же как и Application. Что бы модуль превратить в Singletone в Interface нужно объявить только функции работы. Но это уже не Singletone в понятии OOD&P.
← →
Суслик © (2004-11-23 12:02) [12]Может ли мне кто-нибудь объяснить смысл делать в дельфи singleton?
← →
Palladin © (2004-11-23 12:05) [13]при чем тут делфи, это вопрос проектирования... воспользуйся поисковиком и найди описание singletone... там будет объяснение...
← →
Суслик © (2004-11-23 12:14) [14]
> [13] Palladin © (23.11.04 12:05)
Вопрос проектирования говоришь...
Ну-ну.
Вот только изначальный вопрос тут не на концептуальном уровне, а на уровне реализации. Причем, реализации на конкретном языке. Вот и вопрос, зачем нужно в дельфи иметь singleton.
Songleton в теории обычно идут в связке с другими типовыми решениями. Например, abstract factory. Вопрос, зачем нужно в рамках дельфи делать singleton да и фабрику ту же, когда есть виртуальные классовые методы.
Заметь, я не говорю про проектирование. Я говорю, про реализацию, зачем в конкретном языке городить огород, когда можно, например, в случае фабрики и singleton сделать так:type
TMyFactory = class
public class function CreateFirstObject: TObject; virtual; abstract;
public class function CreateSecondObject: TObject; virtual; abstract;
end;
TFirstFactory = class (TMyFactory)
public class function CreateFirstObject: TObject; override;
public class function CreateSecondObject: TObject; override;
end;
implementation
class function TFirstFactory.CreateFirstObject: TObject; override;
begin
Result := TFistObject.Create;
end;
class function TFirstFactory.CreateSecondObject: TObject; override;
begin
Result := TSecondObject.Create;
end;
end.
В качестве фабрики можешь описывать TMyFactory, а передавать TFirstFactory. Чем не фабрика? Концептуально именно она. ЧЕм не singleton? Концептуально именно он. Спустившись на уровень реализации задай себе вопрос, зачем тебе нужна именно такая реалзиация singleton через NewInstance и FreeInstance?
← →
KSergey © (2004-11-23 12:16) [15]> [11] Palladin © (23.11.04 11:52)
Да, модуль - это безусловно не класс-синглетон. Речь шла об идейной замене, а не буквальной.
Т.е. модуль есть един, и он - есть без нашего участия. Так есть ли смысл изобретать что-то?
> Что бы модуль превратить в Singletone в Interface нужно
> объявить только функции работы.
Да, конечно.
> Но это уже не Singletone в понятии OOD&P.
Буквально - нет. По сути - от чего же?
← →
Reindeer Moss Eater © (2004-11-23 12:17) [16]Автору вопроса нужен был единственный экземпляр класса.
И автор робко предположил, что то что он хочет называется singleton.
Как этого достичь, ему сказали.
При чем здесь то, что это не singlrton?
← →
Суслик © (2004-11-23 12:19) [17]
> [15] KSergey © (23.11.04 12:16)
Насколько я понимаю, что все-таки модуль нельзя использовать как singleton именно потому, что мудули не могут использоваться в рамках полиморфизма.
Мое же видение singleton через классовые сслыки вполне укладываться в рамки полиформизма.
← →
Суслик © (2004-11-23 12:20) [18]
> [16] Reindeer Moss Eater © (23.11.04 12:17)
не вижу проблемы в том, что приводится другое видение данного вопроса...
← →
Reindeer Moss Eater © (2004-11-23 12:21) [19]Вопрос бы в единственном экземпляре на процесс.
← →
Palladin © (2004-11-23 12:32) [20]Фабрика фабрикой. Это конкретная реализация. Это конкретный пример. Можно обойтись и без singletone.
А я разработал свой шаблон в котором Singletone нужен и без него не обойтись. Или у меня в программе создан механизм при котором без Singletone тоже не обойтись... Простейший пример: класс для работы с ресурсом, доступ к котрому должен производится только из одного экземпляра класса, другие экземпляры недопустимы. Это Singletone.
← →
Palladin © (2004-11-23 12:35) [21]
> [15] KSergey © (23.11.04 12:16)
В таком случае заголовочные файлы c тоже Singletone.
← →
Суслик © (2004-11-23 12:36) [22]
> Это Singletone.
пиши через классовые методы (class procedure и пр.), обращаясь к ним через класс:TRecource.Write(...)
..
TRecource.Read(...)
тоже singleton..
← →
Palladin © (2004-11-23 12:37) [23]Если речь идет об идейной замене, а не буквальной. :)
← →
Суслик © (2004-11-23 12:40) [24]
> [23] Palladin © (23.11.04 12:37)
что такое "буквальной"?
С языках, на основе которой пишет Гамма свою знаменитую книга, если не ошибаюсь, нет виртуальных статических методов!
Т.е. методовclass function F: Integer; virtual;
Поэтому в тех языках нужно делать именно так, как написано в книге.
В дельфи есть штатных механизм фабрик и singleton. Да, он не очень похож на примеры из книги. НО делает ровно тоже самое.
← →
Palladin © (2004-11-23 12:41) [25]
> [22] Суслик © (23.11.04 12:36)
Да это и ежу понятно. Вот только, в делфи есть классовые методы, но нет классовых полей.
Что то на подобие Singletone можно получить, запихав конструктор в private или protected (вместе с деструктором) написать толпу классовых методов и описать в implementation "поля" класса... в таком случае идейная замена выйдет неплохая.
← →
Palladin © (2004-11-23 12:42) [26]
> что такое "буквальной"?
Это вопрос к KSergey, а не ко мне...
← →
Суслик © (2004-11-23 12:47) [27]
> [25] Palladin © (23.11.04 12:41)
> запихав конструктор в private
а ты попробуй :)))
Create, идущий от TObject не запихаешь никуда - все равно, собака, виден :))
Отдестроить объект любому клиенту в дельфи помешать нельзя :)))
Хоть обзасовывайся деструктор куда угодно.
С сях можно, в java можно - в дельфи нет.
> но нет классовых полей.
А знаешь почему? Потому, как в отличие от си++ и java статические (классовые методы) в дельфи могут быть виртуальны. Отседова ограничение на статические переменные.
← →
Palladin © (2004-11-23 13:02) [28]
> а ты попробуй :)))
Unit Singletone;
Interface
Type
TSingletone=Class
Protected
Constructor Create;
Destructor Destroy;
Public
Class Function New:TSingletone;
Class Procedure Free;
End;
Implementation
Var
SingleObject:TSingletone;
Class Function TSingletone.New;
Begin
If SingleObject=Nil Then SingleObject:=TSingletone.Create;
Result:=SingleObject;
End;
Constructor TSingletone.Create;
Begin
End;
Class Procedure TSingletone.Free;
Begin
End;
Initialization
SingleObject:=Nil;
End.
Ну вот, попробовал... в этом модуле будет видно, в других нет...
хоть заудаляйся...
> А знаешь почему?
Спасибо за разьяснения... даже и в голову не приходило... года три назад...
← →
Суслик © (2004-11-23 13:06) [29]
> [28] Palladin © (23.11.04 13:02)
> Ну вот, попробовал... в этом модуле будет видно, в других
> нет...
> хоть заудаляйся...
ты сам проверял, что написал?
Кто не будет виден в другом модуле?
Все видно :)
← →
Суслик © (2004-11-23 13:09) [30]
> [28] Palladin © (23.11.04 13:02)
у тебя create виден, только не tsingletone, а tobject.
Спасти свой класс от инстанцирования тебе не удасться :)
Кроме как переопределить в PUBLIC конструктор Create, в нем возбуждать исключение, а пользоваться другим private конструктором.
← →
Palladin © (2004-11-23 13:10) [31]Я пробовал что написал. Не видно. D6
← →
Palladin © (2004-11-23 13:11) [32]
> Кто не будет виден в другом модуле?
Конструктор от TObject.
← →
Суслик © (2004-11-23 13:12) [33]
> [31] Palladin © (23.11.04 13:10)
> Я пробовал что написал. Не видно. D6
ну бог в помощь :)
Для справки: в дельфи не документированно понижение видимости. В д3 оно было, но работало не так, как в д5. Если не ошибаюсь и в д6 нет документации на понижение видимости. Если найдешь оное, буду благодарен за информацию.
← →
Суслик © (2004-11-23 13:15) [34]
> [32] Palladin © (23.11.04 13:11)
> Конструктор от TObject.
гонишь :)))
Как раз он то и будет виден. Твой новый конструктор виден не будет.
← →
Palladin © (2004-11-23 13:21) [35]Хем, ну что ж... ты понизил абстрагирование обсуждения Singletone до Делфи, я в свою очередь понизил до Делфи6... :)
← →
Суслик © (2004-11-23 13:23) [36]
> [35] Palladin © (23.11.04 13:21)
> Хем, ну что ж... ты понизил абстрагирование обсуждения Singletone
> до Делфи, я в свою очередь понизил до Делфи6... :)
Точное замечание:)
← →
GuAV © (2004-11-23 13:25) [37]Palladin © (23.11.04 13:02) [28]
Ха! FreeAdnNil его сделает! :)
← →
Palladin © (2004-11-23 13:35) [38]Не сделает, не волнуйся.
← →
Palladin © (2004-11-23 13:37) [39]Сорри, а ведь точно сделает...
← →
jack128 © (2004-11-23 13:41) [40]Palladin © (23.11.04 13:37) [39]
и создать твой объект можно. Через классовую ссылку ;-)
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2004.12.05;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.042 c