Появилась идея переделать модули XmlcoreScanner и XmlcoreWriter в виде абстрактных интерфейсов со скрытой реализацией. Сейчас всё это выглядит как что-то непонятное, с привязкой к типам из Files.
План такой.
Вообщем по модулю XmlcoreScanner: Описать абстрактную фабрику объектов.
Reader(курьер чтения): Описать абстрактный тип Reader, c набором методов, необходимых Сканнеру. В реализации Reader инкапсулировать Stores.Reader(или, в будущем, какой-нибудь другой Reader).
Для Scanner: Scanner.r объявить типа Reader. Scanner.ConnectTo также переделать, чтобы сканнер присоединялся к Reader, а НЕ к Files.File, как сейчас.
Остаётся нерешённым, как Reader присоединять к источнику данных. Я думаю, подойдёт метод фабрики dir.NewReader(source : ANYPTR). Тогда реализация Reader будет сама приводить тип к "своему" типу источника данных. Также потребуется незначительная модификация XmlcoreParser
Вообщем по модулю XmlcoreWriters: Переименовать XmlcoreWriters в XmlcoreFormatter. Переименовать тип Writer в Formatter.
Writer(курьер записи): Описать абстрактный тип Writer и методы, необходимые для Formatter. Присоединение к источнику данных сделать аналогично как в Reader, через метод фабрики, передавая указатель неопределённого типа.
Для Formatter: Присоединять Formatter к Writer, а НЕ к Files.File, как сейчас.
Также потребуется незначительная переделка Generator.
Вот примерный код:
Код:
MODULE XmlcoreScanner;
TYPE
Reader = POINTER TO ABSTRACT RECORD
<some fields>
END;
StdReader = POINTER TO RECORD (Reader)
<some fields>
rider : Stores.Reader;
END;
Scanner = POINTER TO RECORD
<some fields>
rider- : Reader;
END;
Directory = POINTER TO ABSTRACT RECORD END;
PROCEDURE (rd : Reader) ConnectTo(source : ANYPTR), NEW, ABSTRACT;
PROCEDURE (rd : StdReader) ConnectTo(source : ANYPTR);
BEGIN
ASSERT(source IS Stores.Reader) (* ну, или в зависимости от типа предпринимать действия *)
rd.rider := source;
<some actions>
END ConnectTo;
PROCEDURE (d : Directory) NewScanner(reader : Reader), NEW, ABSTRACT;
PROCEDURE ((d : Directory) NewReader(source : ANYPTR), NEW, ABSTRACT;
(* При работе нужно будет сделать что-то типа: *)
XmlcoreScanner.dir.NewScanner(XmlcoreScanner.dir.NewReader(source));
Код:
MODULE XmlcoreFormatter;
TYPE
Writer = POINTER TO ABSTRACT RECORD
<some fields>
END;
StdWriter = POINTER TO RECORD (Reader)
<some fields>
rider : Stores.Writer;
END;
Formatter = POINTER TO RECORD
<some fields>
rider- : Writer;
END;
Directory = POINTER TO ABSTRACT RECORD END;
PROCEDURE (wr : Writer) ConnectTo(source : ANYPTR), NEW, ABSTRACT;
PROCEDURE (wr : StdWriter) ConnectTo(source : ANYPTR);
BEGIN
ASSERT(source IS Stores.Writer) (* типы выдуманные, названия могут несовпадать*)
wr.rider := source;
<some actions>
END ConnectTo;
PROCEDURE (d : Directory) NewFormatter(writer : Writer), NEW, ABSTRACT;
PROCEDURE ((d : Directory) NewWriter(source : ANYPTR), NEW, ABSTRACT;
(* При работе нужно будет сделать что-то типа: *)
XmlcoreFormatter.dir.NewFormatter(XmlcoreFormatter.dir.NewWriter(source));