OberonCore
https://forum.oberoncore.ru/

Абстракция и реализация
https://forum.oberoncore.ru/viewtopic.php?f=29&t=2474
Страница 1 из 1

Автор:  Роман М. [ Вторник, 23 Март, 2010 14:57 ]
Заголовок сообщения:  Абстракция и реализация

В моей задаче требуется получить некоторую информацию от ОС, заполнив глобальные переменные полученными значениями.
Для примера я взял
Код:
   VAR
      message-: Dialog.String;

Модуль при инициализации должен получить некоторое значение от ОС и поместить его в переменную message.
Прочтя раздел 3.4 в руководстве Блэкбокса (Design Practices: Object creation), я попытался создать модуль абстракций и модуль реализации (якобы платформо-зависимый). Но для получения переменной message мне нужно создать модель с помощью модель.dir.New() в коде клиента.

Как (если возможно) избавиться от Inf := ModelsCore.dir.New(); в коде клиента, перенеся внутрь реализации эту строку?

Код:
MODULE TestModelsCore;

   IMPORT Dialog;
   
   TYPE
      Info* = POINTER TO ABSTRACT RECORD END;
      Directory* = POINTER TO ABSTRACT RECORD END;
   
   VAR
      message-: Dialog.String;
      dir-, stdDir-: Directory;

   (** Directory **)

   PROCEDURE (d: Directory) New* (): Info, NEW, ABSTRACT;

   (* Info *)   

   PROCEDURE (I: Info) SetMessage* (IN mes: ARRAY OF CHAR), NEW;
   BEGIN
      message := mes$
   END SetMessage;

   PROCEDURE (I: Info) RetrieveInformation* (OUT mes: ARRAY OF CHAR), NEW, ABSTRACT;

   PROCEDURE (I: Info) InitMessage*, NEW;
      VAR mes: Dialog.String;
   BEGIN
      I.RetrieveInformation(mes);
      I.SetMessage(mes$)
   END InitMessage;

   PROCEDURE SetDir* (d: Directory);
   BEGIN
      ASSERT(d # NIL, 20);
      dir := d;
      IF stdDir = NIL THEN stdDir := d END
   END SetDir;
   
END TestModelsCore.


Код:
MODULE TestModelsHost;

   IMPORT Kernel, ModelsCore := TestModelsCore;
      
   TYPE
      Info = POINTER TO RECORD (ModelsCore.Info) END;
      Directory = POINTER TO RECORD (ModelsCore.Directory) END;
   
   VAR
      dir: Directory;
   
   (* Implementation *)
   
   PROCEDURE (I: Info) RetrieveInformation (OUT mes: ARRAY OF CHAR);
   BEGIN
      mes := "Hello!"
   END RetrieveInformation;
   
   (* Directory *)
   PROCEDURE (d: Directory) New (): Info;
   VAR Inf: Info;
   BEGIN
      NEW(Inf);
      Inf.InitMessage;
      RETURN Inf
   END New;
   
   PROCEDURE Init;
   BEGIN
      NEW(dir);
      ModelsCore.SetDir(dir)
   END Init;
   
BEGIN
   Init
END TestModelsHost.


Код:
MODULE TestModels;

   IMPORT ModelsHost := TestModelsHost, ModelsCore := TestModelsCore, Log := StdLog;
   
   PROCEDURE Do*;
      VAR Inf: ModelsCore.Info;
   BEGIN
      Inf := ModelsCore.dir.New();
      Log.String(ModelsCore.message); Log.Ln;
      Inf.SetMessage ("Hello, world!");
      Log.String(ModelsCore.message); Log.Ln
   END Do;
   
END TestModels.

^Q TestModels.Do

Вложение:
TestModels.zip [2.34 КБ]
Скачиваний: 423

Автор:  Александр Ильин [ Вторник, 23 Март, 2010 15:07 ]
Заголовок сообщения:  Re: Абстракция и реализация

Роман М. писал(а):
Как (если возможно) избавиться от Inf := ModelsCore.dir.New(); в коде клиента, перенеся внутрь реализации эту строку?
Этот вызов достаточно переместить в TestModelsHost.Init. Тогда информация будет проинициализирована при загрузке модуля реализации (вы ведь в любом случае прилинкуете TestModelsHost к приложению). Главное - убедиться, что модуль TestModelsHost будет загружен до того, как кому-то потребуется информация из TestModelsCore.

Автор:  Роман М. [ Вторник, 23 Март, 2010 17:20 ]
Заголовок сообщения:  Re: Абстракция и реализация

Насколько я понимаю,
Код:
PROCEDURE (d: Directory) New* (): Info
вообще излишня, потому что нужно только инициировать глобальные переменные. Значит, можно переместить код
Код:
      NEW(Inf);
      Inf.InitMessage;
сразу после установки директории SetDir в TestModelsHost.Init.

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/