Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

ООП. Как сделать правильнее ???


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-й намекает на то, что текст сам по себе, без печати, как бы не имеет смысла


Наверх

Титульная страница Поиск, карта сайта Написать письмо