> -- comm1x писал(а):
> Не, не забили. Я совершенно не понимаю о чем вы ведете диалог.
Есть разные варианты, в зависимости от задач. Тот что я показал - из разряда "наскоряк пойдёт для одного раза".

Если каждая отрисовка имеет свои параметры (различные для разных объектов), то делать можно так:

Основной модуль:
## Код:
```
MODULE PrivViews;

IMPORT
   Views;
   
TYPE
   Drawer* = POINTER TO ABSTRACT RECORD
      v- : View; (* при отрисовке мы должны использовать данные объекта *)
   END;

   View* = POINTER TO RECORD(Views.View)
      d : Drawer (*у каждого объекта в каждый момент времени - один рисователь*)
   END;

   DefDrawer = POINTER TO RECORD (Drawer) (* изначально объект рисоваться не умеет - это заглушка *)
   END;

PROCEDURE (d : Drawer) Draw- (f : Views.Frame; l, t, r, b : INTEGER), NEW, ABSTRACT;

PROCEDURE (d : DefDrawer) Draw- (f : Views.Frame; l, t, r, b : INTEGER);
BEGIN
END Draw;

PROCEDURE (v : View) Restore* (f : Views.Frame; l, t, r, b : INTEGER);
BEGIN
   (* если бы не ввели DefDrawer, то здесь пришлось бы проверять на v.d # NIL *)
   v.d.Draw(f, l, t, r, b)
END Restore;

(* меняем рисователь  для объекта *)
PROCEDURE SetDrawer* (v : View; d : Drawer);
BEGIN
   ASSERT (v # NIL, 20);
   ASSERT (d # NIL, 21);
   v.d := d; d.v := v
END SetDrawer;

(* создаём объект с пустым рисователем. Никто не мешает нам создать его и простым NEW, но тогда он не будет правильно инициализирован. Можно и это предусмотреть, но для примера - сойдёт *)
PROCEDURE New* () : View;
VAR res : View; d : DefDrawer;
BEGIN
   NEW(res); NEW(d); SetDrawer(res, d); RETURN res
END New;

PROCEDURE Deposit*;
BEGIN
   Views.Deposit(New())
END Deposit;

END PrivViews.
```


Модуль реализации рисователей:
## Код:
```
MODULE PrivViewDrawers;

IMPORT
   PrivViews, Views;
   
TYPE
   SinDrawer = POINTER TO RECORD (PrivViews.Drawer)
   END;
   
   CosDrawer = POINTER TO RECORD (PrivViews.Drawer)
   END;
   
   TanDrawer = POINTER TO RECORD (PrivViews.Drawer)
   END;
   
PROCEDURE (d : SinDrawer) Draw- (f : Views.Frame; l, t, r, b : INTEGER);
BEGIN
   тут рисуем синус
END Draw;

PROCEDURE (d : CosDrawer) Draw- (f : Views.Frame; l, t, r, b : INTEGER);
BEGIN
   тут рисуем косинус
END Draw;

PROCEDURE (d : TanDrawer) Draw- (f : Views.Frame; l, t, r, b : INTEGER);
BEGIN
   тут рисуем тангенс
END Draw;

PROCEDURE SetSinDrawer* (v : Views.View);
VAR s : SinDrawer;
BEGIN
   WITH v : PrivViews.View DO
      NEW(s); PrivViews.SetDrawer(v, s)
   ELSE
   END
END SetSinDrawer;

PROCEDURE SetCosDrawer* (v : Views.View);
VAR c : CosDrawer;
BEGIN
   WITH v : PrivViews.View DO
      NEW(c); PrivViews.SetDrawer(v, c)
   ELSE
   END
END SetCosDrawer;

PROCEDURE SetTanDrawer* (v : Views.View);
VAR t : TanDrawer;
BEGIN
   WITH v : PrivViews.View DO
      NEW(t); PrivViews.SetDrawer(v, t)
   ELSE
   END
END SetTanDrawer;

END PrivViewDrawers.
```


Пользуемся например так:
## Код:
```
PROCEDURE DepositTan;
VAR v : Views.View;
BEGIN
   v := PrivViews.New(); PrivViewDrawers.SetTanDrawer(v); Views.Deposit(v)
END DepositTan;
```
