![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ООП. Как сделать правильнее ???
Leon-Z © (2011-04-03 12:38:00)Есть два класса: TMyText и TMyPrinter.
1-ый содержить текст, 2-й умеет печатать разные тексты.
Когда создается TMyText возможно через параметр конструктора передать ссылку на TMyPrinter. Естественно, что экземпляр TMyPrinter объявляется и создается заранее. В TMyText нужно хранить ссылку на TMyPrinter и по мере надобности обращаться к этому экземпляру.
constructor TMyText.Create(aPrn: TMyPrinter);
Есть другой вариант: В конструкторе не передавать ссылку на TMyPrinter, а использовать непосредственно в методе TMyText, т.е
так: procedure TMyText.Print(Prn: TMyPrinter);
Экземпляр TMyPrinter также должен быть объявлен и создан заранее.
Какой вариант предпочтительнее с Вашей точки зрения ?
Ega23 (2011-04-05 20:51:00) [1]
IMyPrinter = interface
[GUID]
procedure Print(const SomeText: string);
end;
TMyText = class (...)
procedure Print(Printer: IMyPrinter);
end;
TMyPrinter = class (TInterfacedObject, IMyPrinter)
procedure Print(const SomeText: string);
end;
procedure TMyText.Print(Printer: IMyPrinter);
begin
Printer.Print('Bla-Bla-Bla');
end;
И не важно, что из себя представляет класс принтера и вообще какого он класса.
Ы?
_Юрий (2011-04-04 18:32:00) [2]Не кажется ли уважаемым Мастерам, что хардкорно связывать текст с принтером(или принтер с текстом) - это путь к так называемому "спагетти-коду"?
Ioc нынче не в почете?
clickmaker (2011-04-04 11:07:00) [3]procedure TMyText.Print(Prn: TMyPrinter);
begin
Prn.Print(Self);
end;
Или наоборот. Где реализовать - надо смотреть по структуре классов, как удобней
Leon-Z (2011-04-03 19:20:00) [4]
> Юрий Зотов © (03.04.11 15:13) [8]
Значит правильнее выбрать 1-й вариант ???
> Юрий Зотов © (03.04.11 15:37) [9]
> > Leon-Z © (03.04.11 14:40) [6] Кстати, стоит подумать
> - если текст будет печатать сам себя, то нужен ли вообще
> класс принтера? Что тогда остается на его долю?
Класс принтера нужен. Он содержит ф-ии выбора шрифта, цвета, печати строки и рисунка и т.п. (Это некий виртуальный принтер).
Jeer (2011-04-03 17:34:00) [5]
> то нужен ли вообще класс принтера? Что тогда остается на
> его долю?
Точно. Я бы включил методы работы с текстом в класс Текст.
Юрий Зотов (2011-04-03 15:37:00) [6]> Leon-Z © (03.04.11 14:40) [6]
Кстати, стоит подумать - если текст будет печатать сам себя, то нужен ли вообще класс принтера? Что тогда остается на его долю?
Юрий Зотов (2011-04-03 15:13:00) [7]> Leon-Z © (03.04.11 14:40) [6]
> TMyText.Print(Prn: TMyPrinter);
Это согласуется с принципами ООП - каждый объект знает, как ему самого себя обрабатывать. Ведь может быть несколько потомков TMyText и у каждого свои особенности и свой собственный метод Print.
> TMyPrinter.Print(Txt: TMyText);
А это согласуется с нормальной человеческой логикой - ведь мы привыкли, что печатает все же принтер, а не текст.
clickmaker (2011-04-03 14:54:00) [8]ну как в магазине прям... если не знаешь, что выбрать, покупай оба
Leon-Z (2011-04-03 14:40:00) [9]А согласно каким критериям определить вид отношения.
Можно так:
TMyText.Print(Prn: TMyPrinter);
А ведь можно и так:
TMyPrinter.Print(Txt: TMyText);
Какой вариант выбрать ???
Leon-Z (2011-04-03 14:31:00) [10]
> Юрий Зотов © (03.04.11 14:08) [2]
Мастер-класс !!!
Leon-Z (2011-04-03 14:30:00) [11]
> Юрий Зотов © (03.04.11 14:08) [2]
Мастер-класс !!!
Palladin (2011-04-03 14:20:00) [12]
> Юрий Зотов © (03.04.11 14:08) [2]
Но с другой стороны Принтер не есть какая то виртуальная программная сущность, а вполне себе конкретное устройство, по-этому лучше завести глобальный список принтеров или создать синглтон, нежели постоянно создавать объекты класса. Ведь в конструкторах класса принтера могут содержатся некий, инициализирующий устройство код и как-то не кошерно принтер опрашивать/инициализировать на каждый чих )
Юрий Зотов (2011-04-03 14:08:00) [13]Особой разницы нет, но если TMyPrinter может обзавестись потомками, то я бы сделал примерно так:
type
TMyPrinter = class(...)
...
public
constructor Create(...); virtual;
end;
TMyPrinterClass = class of TMyPrinter ;
TMyText = class(...)
private
FPrinterClass: TMyPrinterClass;
...
public
constructor Create(PrinterClass: TMyPrinterClass; ...);
procedure Print(...);
end;
...
constructor TMyText.Create(PrinterClass: TMyPrinterClass; ...);
begin
inherited Create(...);
FPrinterClass := PrinterClass;
...
end;
procedure TMyText.Print(...);
var
Prn: TMyPrinter;
begin
Prn := FPrinterClass.Create(...);
try
... // Печать
finally
Prn.Free;
end;
end;
Удобно еще и тем, что не надо заботиться о создании и уничтожении экземпляра принтера - все делается автоматически. Ну и плюс небольшая экономия памяти, поскольку экземпляр принтера не висит в ней постоянно, а создается и уничтожается "на ходу". Конечно, это приводит к небольшому замедлению в методе Print, но есть основания полагать, что по сравнению с самой печатью такое замедление будет пренебрежимо мало.
clickmaker (2011-04-03 12:43:00) [14]принципиальной разницы нет. Просто 1-й намекает на то, что текст сам по себе, без печати, как бы не имеет смысла