Stream : InputStream, OutputStream
От: igna Россия  
Дата: 26.05.06 09:14
Оценка:
Что говорит за и что против наличия классов InputStream и OutputStream (и произведения от них класса Stream), если язык позволяет множественное наследование?
Re: Stream : InputStream, OutputStream
От: WolfHound  
Дата: 26.05.06 09:43
Оценка:
Здравствуйте, igna, Вы писали:

I>Что говорит за

Здравый смысл.

I>и что против

Глупость.

I>наличия классов InputStream и OutputStream (и произведения от них класса Stream), если язык позволяет множественное наследование?

И еще нужно выделить InputRandomStream и OutputRandomStream
И иерархия должна быть примерно такой
InputStream 
OutputStream
InputRandomStream : InputStream 
OutputRandomStream : OutputStream
Stream : InputStream, OutputStream
RandomStream : Stream, InputRandomStream, OutputRandomStream
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Stream : InputStream, OutputStream
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 26.05.06 10:23
Оценка:
Здравствуйте, igna, Вы писали:

I>Что говорит за и что против наличия классов InputStream и OutputStream (и произведения от них класса Stream), если язык позволяет множественное наследование?


Аргументация простая: Input/Output — это спецификация для пользователей классов. Функция, получающая InputStream на вход ни при каких условиях не сможет что-то записать в поток. Примерный аналог const-спецификации для параметра.

То же самое справедливо и для Output: отдавая куда OutputStream, мы уверены, что пользователь только запишет что-то туда, но не прочёт.

В общем, ключевое слово — специфицирование.
<< Под музыку: Песни индейцев Боливии. Звуки Анд. Inti Raumi (Chuntunqui) >>
<< При помощи Януса: 1.2.0 alpha rev. 650 >>
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[2]: Stream : InputStream, OutputStream
От: igna Россия  
Дата: 26.05.06 10:31
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>RandomStream : Stream, InputRandomStream, OutputRandomStream

Почему не

RandomStream : InputRandomStream, OutputRandomStream

?
Re[3]: Stream : InputStream, OutputStream
От: WolfHound  
Дата: 26.05.06 10:34
Оценка: 1 (1) +1
Здравствуйте, igna, Вы писали:

I>
I>RandomStream : InputRandomStream, OutputRandomStream
I>

I>?
А RandomStream разве не является Stream?
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re: Stream : InputStream, OutputStream
От: ie Россия http://ziez.blogspot.com/
Дата: 28.05.06 08:30
Оценка:
Здравствуйте, igna, Вы писали:

I>Что говорит за и что против наличия классов InputStream и OutputStream (и произведения от них класса Stream), если язык позволяет множественное наследование?


Против — плохой дизайн.
Как правило Stream не гарантирует одновременно возможность чтения и записи в него. Для спецификации этого добаляют методы типа: IsReadable/IsWritable. Добавление метода IsReadable в InputStream достаточно нелепое решение. Однако, недобавление такового ведет к нарушению контракта, т.к. теоритически доступный для чтения поток, может стать недоступным практически.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Превратим окружающую нас среду в воскресенье.
Re: Carrier-Rider-Mapper
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 30.05.06 08:56
Оценка: 8 (2) +3
Здравствуйте, igna, Вы писали:

I>Что говорит за и что против наличия классов InputStream и OutputStream (и произведения от них класса Stream), если язык позволяет множественное наследование?


Создавать Stream как расширение InputStream и OutputStream — безумие.

1) В одних задачах нужен объект отвечающий только за чтение, а в других задачах нужен объект отвечающий только за запись. Каков смысл создавать третий объект умеющий и читать и писать одновременно если можно вместо него использовать первые два объекта, которые и уже есть?

2) Есть паттерн проектирования Carrier-Rider-Mapper.
Carrier — носитель информации.
Rider — это либо считыватель (Reader) либо записыватель (Writer) информации из/в Carrier.
Mapper — это либо сканер (Scanner) либо форматтер (Formatter) — преобразователи форматов данных.
    +------->-----Reader----->-----Scanner----->-----
    |
Carrier          "Rider"          "Mapper"
    |
    +-------<-----Writer-----<-----Formatter----<----

Может быть много разных сканеров, каждый из которых соединяется по заранее установленному интерфейсу со считывателем.
Может быть много разных форматтеров, каждый из которых соединяется по заранее установленному интерфейсу с записывателем.
Может быть много разных носителей информации, каждый из которых предлагает одни и теже считыватели и записыватели информации из/в себя.

Из-за того, что интерфейсы подключения Reader->-Scanner и Writer-<-Formatter жестко определены, можно использовать разные мапперы с разными райдерами — это победа над геометрической прогрессией количества классов объектов, которые были бы нужны в противном случае. Поэтому объединение классов Reader и Writer в один класс — безумство.

Вырезка из хелпа к BlackBox:

In terms of design patterns, the Carrier-Rider-Mapper pattern solves the problem of flexible and convenient access to a data carrier, however it is implemented. It can be regarded to consist of two simpler and very basic design patterns: the separation of one object into several objects to allow many-to-one relations; and the separation of one object into two objects to allow for independent extensibility:

Split an abstraction into two interfaces if several clients may access an instance simultaneously, and if independent state may have to be managed for every client.

Split an abstraction into two interfaces, if it needs to be extended independently in two different dimensions.


The Carrier-Rider-Mapper separation goes back to a research project ["Insight ETHOS: On Object-Orientation in Operating Systems"; Clemens Szyperski; vdf, Zьrich, 1992, ISBN 3 7281 1948 2] predating BlackBox. This project used several design patterns and design rules (e.g., avoidance of implementation inheritance) that are also described in Design Patterns. In the Design Patterns terminology, a Rider-Mapper combination (or Carrier-Mapper combination if there is no rider) forms a bridge pattern.

Re[2]: Carrier-Rider-Mapper
От: Kluev  
Дата: 30.05.06 11:26
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>2) Есть паттерн проектирования Carrier-Rider-Mapper.

СГ>Carrier — носитель информации.
СГ>Rider — это либо считыватель (Reader) либо записыватель (Writer) информации из/в Carrier.
СГ>Mapper — это либо сканер (Scanner) либо форматтер (Formatter) — преобразователи форматов данных.
СГ>
СГ>    +------->-----Reader----->-----Scanner----->-----
СГ>    |
СГ>Carrier          "Rider"          "Mapper"
СГ>    |
СГ>    +-------<-----Writer-----<-----Formatter----<----
СГ>

СГ>Может быть много разных сканеров, каждый из которых соединяется по заранее установленному интерфейсу со считывателем.
СГ>Может быть много разных форматтеров, каждый из которых соединяется по заранее установленному интерфейсу с записывателем.
СГ>Может быть много разных носителей информации, каждый из которых предлагает одни и теже считыватели и записыватели информации из/в себя.

Интересная мысль. Было бы любопытно глянуть на список методов каждого класса.
Re[3]: Carrier-Rider-Mapper
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 30.05.06 14:32
Оценка:
Здравствуйте, Kluev, Вы писали:

K> Интересная мысль. Было бы любопытно глянуть на список методов каждого класса.


Фрагменты интерфейсов модулей BlackBox (работа с документами):
DEFINITION TextModels;

    IMPORT Stores, Ports, Fonts, Properties, Containers, Models, Views;

    ...
    
    TYPE
        Model = POINTER TO ABSTRACT RECORD (Containers.Model)
            ...
            (m: Model) NewReader (old: Reader): Reader, NEW, ABSTRACT;
            (m: Model) NewWriter (old: Writer): Writer, NEW, ABSTRACT;
            ...
        END;

        Reader = POINTER TO ABSTRACT RECORD 
            eot: BOOLEAN;
            attr: Attributes;
            char: CHAR;
            view: Views.View;
            w, h: INTEGER;
            (rd: Reader) Base (): Model, NEW, ABSTRACT;
            (rd: Reader) Pos (): INTEGER, NEW, ABSTRACT;
            (rd: Reader) Read, NEW, ABSTRACT;
            (rd: Reader) ReadChar (OUT ch: CHAR), NEW, ABSTRACT;
            (rd: Reader) ReadPrev, NEW, ABSTRACT;
            (rd: Reader) ReadPrevChar (OUT ch: CHAR), NEW, ABSTRACT;
            (rd: Reader) ReadPrevRun (OUT attr: Attributes), NEW, ABSTRACT;
            (rd: Reader) ReadPrevView (OUT v: Views.View), NEW, ABSTRACT;
            (rd: Reader) ReadRun (OUT attr: Attributes), NEW, ABSTRACT;
            (rd: Reader) ReadView (OUT v: Views.View), NEW, ABSTRACT;
            (rd: Reader) SetPos (pos: INTEGER), NEW, ABSTRACT
        END;

        Writer = POINTER TO ABSTRACT RECORD 
            attr-: Attributes;
            (wr: Writer) Base (): Model, NEW, ABSTRACT;
            (wr: Writer) Pos (): INTEGER, NEW, ABSTRACT;
            (wr: Writer) SetAttr (attr: Attributes), NEW;
            (wr: Writer) SetPos (pos: INTEGER), NEW, ABSTRACT;
            (wr: Writer) WriteChar (ch: CHAR), NEW, ABSTRACT;
            (wr: Writer) WriteView (view: Views.View; w, h: INTEGER), NEW, ABSTRACT
        END;

    ...
    
END TextModels.


DEFINITION TextMappers;

    IMPORT TextModels, Views;

    ...

    TYPE
        Formatter = RECORD 
            rider-: TextModels.Writer;
            (VAR f: Formatter) ConnectTo (text: TextModels.Model), NEW;
            (VAR f: Formatter) Pos (): INTEGER, NEW;
            (VAR f: Formatter) SetPos (pos: INTEGER), NEW;
            (VAR f: Formatter) WriteBool (x: BOOLEAN), NEW;
            (VAR f: Formatter) WriteChar (x: CHAR), NEW;
            (VAR f: Formatter) WriteInt (x: LONGINT), NEW;
            (VAR f: Formatter) WriteIntForm (x: LONGINT; base, minWidth: INTEGER; fillCh: CHAR; showBase: BOOLEAN), NEW;
            (VAR f: Formatter) WriteLn, NEW;
            (VAR f: Formatter) WriteMsg (msg: ARRAY OF CHAR), NEW;
            (VAR f: Formatter) WritePara, NEW;
            (VAR f: Formatter) WriteParamMsg (msg, p0, p1, p2: ARRAY OF CHAR), NEW;
            (VAR f: Formatter) WriteReal (x: REAL), NEW;
            (VAR f: Formatter) WriteRealForm (x: REAL; precision, minW, expW: INTEGER; fillCh: CHAR), NEW;
            (VAR f: Formatter) WriteSString (x: ARRAY OF SHORTCHAR), NEW;
            (VAR f: Formatter) WriteSet (x: SET), NEW;
            (VAR f: Formatter) WriteString (x: ARRAY OF CHAR), NEW;
            (VAR f: Formatter) WriteTab, NEW;
            (VAR f: Formatter) WriteView (v: Views.View), NEW;
            (VAR f: Formatter) WriteViewForm (v: Views.View; w, h: INTEGER), NEW
        END;

        Scanner = RECORD 
            opts-: SET;
            rider-: TextModels.Reader;
            type, start, lines, paras: INTEGER;
            char: CHAR;
            int, base: INTEGER;
            lint: LONGINT;
            real: REAL;
            bool: BOOLEAN;
            set: SET;
            len: INTEGER;
            string: String;
            view: Views.View;
            w, h: INTEGER;
            (VAR s: Scanner) ConnectTo (text: TextModels.Model), NEW;
            (VAR s: Scanner) Pos (): INTEGER, NEW;
            (VAR s: Scanner) Scan, NEW;
            (VAR s: Scanner) SetOpts (opts: SET), NEW;
            (VAR s: Scanner) SetPos (pos: INTEGER), NEW;
            (VAR s: Scanner) Skip (OUT ch: CHAR), NEW
        END;
    
    ...

END TextMappers.

В этом примере мапперы хоть и коннектятся к самой модели, но работают с ней посредством её райдеров. В принципе, более универсальным было бы сделать мапперы коннектящиеся только к райдерам.

Работа с файлами:
DEFINITION Files;

    ...
    
    TYPE
        File = POINTER TO ABSTRACT RECORD
            ...
            (f: File) NewReader (old: Reader): Reader, NEW, ABSTRACT;
            (f: File) NewWriter (old: Writer): Writer, NEW, ABSTRACT;
            ...
        END;

        Reader = POINTER TO ABSTRACT RECORD 
            eof: BOOLEAN;
            (r: Reader) Base (): File, NEW, ABSTRACT;
            (r: Reader) Pos (): INTEGER, NEW, ABSTRACT;
            (r: Reader) ReadByte (OUT x: BYTE), NEW, ABSTRACT;
            (r: Reader) ReadBytes (VAR x: ARRAY OF BYTE; beg, len: INTEGER), NEW, ABSTRACT;
            (r: Reader) SetPos (pos: INTEGER), NEW, ABSTRACT
        END;

        Writer = POINTER TO ABSTRACT RECORD 
            (w: Writer) Base (): File, NEW, ABSTRACT;
            (w: Writer) Pos (): INTEGER, NEW, ABSTRACT;
            (w: Writer) SetPos (pos: INTEGER), NEW, ABSTRACT;
            (w: Writer) WriteByte (x: BYTE), NEW, ABSTRACT;
            (w: Writer) WriteBytes (IN x: ARRAY OF BYTE; beg, len: INTEGER), NEW, ABSTRACT
        END;

    ...
    
END Files.


DEFINITION Stores;

    IMPORT Files;

    TYPE
        Reader = RECORD 
            rider-: Files.Reader;
            cancelled-, readAlien-: BOOLEAN;
            (VAR rd: Reader) ConnectTo (f: Files.File), NEW;
            (VAR rd: Reader) Pos (): INTEGER, NEW;
            (VAR rd: Reader) ReadBool (OUT x: BOOLEAN), NEW;
            (VAR rd: Reader) ReadByte (OUT x: BYTE), NEW;
            (VAR rd: Reader) ReadChar (OUT x: CHAR), NEW;
            (VAR rd: Reader) ReadInt (OUT x: INTEGER), NEW;
            (VAR rd: Reader) ReadLong (OUT x: LONGINT), NEW;
            (VAR rd: Reader) ReadReal (OUT x: REAL), NEW;
            (VAR rd: Reader) ReadSChar (OUT x: SHORTCHAR), NEW;
            (VAR rd: Reader) ReadSInt (OUT x: SHORTINT), NEW;
            (VAR rd: Reader) ReadSReal (OUT x: SHORTREAL), NEW;
            (VAR rd: Reader) ReadSString (OUT x: ARRAY OF SHORTCHAR), NEW;
            (VAR rd: Reader) ReadSet (OUT x: SET), NEW;
            (VAR rd: Reader) ReadStore (OUT x: Store), NEW;
            (VAR rd: Reader) ReadString (OUT x: ARRAY OF CHAR), NEW;
            (VAR rd: Reader) ReadVersion (min, max: INTEGER; OUT version: INTEGER), NEW;
            (VAR rd: Reader) ReadXChar (OUT x: CHAR), NEW;
            (VAR rd: Reader) ReadXInt (OUT x: INTEGER), NEW;
            (VAR rd: Reader) ReadXReal (OUT x: REAL), NEW;
            (VAR rd: Reader) ReadXString (OUT x: ARRAY OF CHAR), NEW;
            (VAR rd: Reader) SetPos (pos: INTEGER), NEW;
            (VAR rd: Reader) TurnIntoAlien (cause: INTEGER), NEW
        END;

        Writer = RECORD 
            rider-: Files.Writer;
            writtenStore-: Store;
            (VAR wr: Writer) ConnectTo (f: Files.File), NEW;
            (VAR wr: Writer) Pos (): INTEGER, NEW;
            (VAR wr: Writer) SetPos (pos: INTEGER), NEW;
            (VAR wr: Writer) WriteBool (x: BOOLEAN), NEW;
            (VAR wr: Writer) WriteByte (x: BYTE), NEW;
            (VAR wr: Writer) WriteChar (x: CHAR), NEW;
            (VAR wr: Writer) WriteInt (x: INTEGER), NEW;
            (VAR wr: Writer) WriteLong (x: LONGINT), NEW;
            (VAR wr: Writer) WriteReal (x: REAL), NEW;
            (VAR wr: Writer) WriteSChar (x: SHORTCHAR), NEW;
            (VAR wr: Writer) WriteSInt (x: SHORTINT), NEW;
            (VAR wr: Writer) WriteSReal (x: SHORTREAL), NEW;
            (VAR wr: Writer) WriteSString (IN x: ARRAY OF SHORTCHAR), NEW;
            (VAR wr: Writer) WriteSet (x: SET), NEW;
            (VAR wr: Writer) WriteStore (x: Store), NEW;
            (VAR wr: Writer) WriteString (IN x: ARRAY OF CHAR), NEW;
            (VAR wr: Writer) WriteVersion (version: INTEGER), NEW;
            (VAR wr: Writer) WriteXChar (x: CHAR), NEW;
            (VAR wr: Writer) WriteXInt (x: INTEGER), NEW;
            (VAR wr: Writer) WriteXReal (x: REAL), NEW;
            (VAR wr: Writer) WriteXString (IN x: ARRAY OF CHAR), NEW
        END;

    ...
    
END Stores.

Stores.Reader и Stores.Writer — мапперы для Files.Reader и Files.Writer.
Re[4]: Carrier-Rider-Mapper
От: WolfHound  
Дата: 30.05.06 15:29
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Работа с файлами:

СГ>
СГ>DEFINITION Files;

СГ>    ...
    
СГ>    TYPE
СГ>        File = POINTER TO ABSTRACT RECORD
СГ>            ...
СГ>            (f: File) NewReader (old: Reader): Reader, NEW, ABSTRACT;
СГ>            (f: File) NewWriter (old: Writer): Writer, NEW, ABSTRACT;
СГ>            ...
СГ>        END;

СГ>        Reader = POINTER TO ABSTRACT RECORD 
СГ>            eof: BOOLEAN;
СГ>            (r: Reader) Base (): File, NEW, ABSTRACT;
СГ>            (r: Reader) Pos (): INTEGER, NEW, ABSTRACT;
СГ>            (r: Reader) ReadByte (OUT x: BYTE), NEW, ABSTRACT;
СГ>            (r: Reader) ReadBytes (VAR x: ARRAY OF BYTE; beg, len: INTEGER), NEW, ABSTRACT;
СГ>            (r: Reader) SetPos (pos: INTEGER), NEW, ABSTRACT
СГ>        END;

СГ>        Writer = POINTER TO ABSTRACT RECORD 
СГ>            (w: Writer) Base (): File, NEW, ABSTRACT;
СГ>            (w: Writer) Pos (): INTEGER, NEW, ABSTRACT;
СГ>            (w: Writer) SetPos (pos: INTEGER), NEW, ABSTRACT;
СГ>            (w: Writer) WriteByte (x: BYTE), NEW, ABSTRACT;
СГ>            (w: Writer) WriteBytes (IN x: ARRAY OF BYTE; beg, len: INTEGER), NEW, ABSTRACT
СГ>        END;

СГ>    ...
    
СГ>END Files.
СГ>

Вот объясни мне пожалуйста почему создатели черной коробки привязали RandomInputStream и RandomOutputStrem к файлам?
Особенно смешно это выглядит на фоне твоих громких заявлений о безумном дизайне и развязки модели и пользователей.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[4]: Carrier-Rider-Mapper
От: Cyberax Марс  
Дата: 31.05.06 08:01
Оценка:
Сергей Губанов wrote:
> K> Интересная мысль. Было бы любопытно глянуть на список методов каждого
> класса.
> Фрагменты интерфейсов модулей BlackBox
> <http://www.oberon.ch/blackbox.html&gt; (работа с документами):
В морг.

Во-первых, нет разделения между типами входных данных (покажите мне
SetPos на сокете).

Во-вторых, дизайн записывальщиков/читальщиков — неудачный. Как мне
установить кодировку, например?

Тут лучше всего посмотреть на Java. Для чтения там есть потоки
ввода-вывода, причем их можно комбинировать.

Например:
FileInputStream str=new FileInputStream(...);
GzipInputStream gz=new GzipInputStream(str);
BufferedInputStream buf=new BufferInputStream(gz);


То есть можно произвольным образом комбинировать потоки, получая при это
огромную гибкость. Потоки при этом работают на уровне бинарных данных,
без какой-либо их интерпретации.

Дальше идут уже манипуляторы, которые работают над потоками. Например,
InputStreamReader:
InputStreamReader rd=new InputStreamReader(stream,"utf-8");
rd.readChars(...);


Как показывает практика, эта абстракция замечательно подходит для
большинства случаев.

Однако, в дизайне Java-потоков тоже есть проблемы.

В интерфейсе потока присутствуют методы reset, mark, available и т.п. Я
бы заменил их одним методом "Object getSource()", который бы возвращал
объект "источник" (кто сказал слово "generic"?). У источника можно было
бы спрашивать интерфейсы: Seeakable (для источников произвольного
доступа), Lockable (для поддерживающих блокировку объектов),
MemMapCapable (для файлов, которые можно отображать в память) и т.п.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[5]: Carrier-Rider-Mapper
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 31.05.06 08:25
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Вот объясни мне пожалуйста почему создатели черной коробки привязали RandomInputStream и RandomOutputStrem к файлам?


Что? Где Вы там увидели RandomInputStream и RandomOutputStrem?
Re[5]: Carrier-Rider-Mapper
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 31.05.06 08:30
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Во-первых, нет разделения между типами входных данных (покажите мне SetPos на сокете).


Где Вы там увидели сокеты?

C>Как мне установить кодировку, например?


Мапперами естественно.
Re[6]: Carrier-Rider-Mapper
От: WolfHound  
Дата: 31.05.06 09:05
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

WH>>Вот объясни мне пожалуйста почему создатели черной коробки привязали RandomInputStream и RandomOutputStrem к файлам?


СГ>Что? Где Вы там увидели RandomInputStream и RandomOutputStrem?

Сравни это с тем что я процитировал
interface IInputStream
{
    int ReadBytes(byte[] buf, int start, int count);
}
interface IOutputStream
{
    int WriteBytes(byte[] buf, int start, int count);
}
interface IInputRandomStream : IInputStream
{
    long Position { get; set; }
}
interface IOutputRandomStream : IOutputStream
{
    long Position { get; set; }
}

ReadByte/WriteByte и eof избыточны
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[6]: Carrier-Rider-Mapper
От: Cyberax Марс  
Дата: 31.05.06 09:46
Оценка: +1 -1
Сергей Губанов wrote:
> C>Во-первых, нет разделения между типами входных данных (покажите мне
> SetPos на сокете).
> Где Вы там увидели сокеты?
Это я к тому, что эта архитектура ввода-вывода не подходит для других
целей кроме чтения файлов. А вот потоки прекрасно подходят.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[7]: Carrier-Rider-Mapper
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 31.05.06 11:07
Оценка:
Здравствуйте, WolfHound, Вы писали:

И что мешает написать в точности тоже самое для моего примера?
DEFINITION IO;

  TYPE
    Reader* = POINTER TO ABSTRACT RECORD
      (r: Reader) ReadBytes (OUT buf: ARRAY OF BYTE; offset, count: INTEGER): INTEGER, NEW, ABSTRACT;
    END;

    RandomReader* = POINTER TO ABSTRACT RECORD
      (r: Reader) Pos (): INTEGER, NEW, ABSTRACT;
      (r: Reader) SetPos (pos: INTEGER), NEW, ABSTRACT;
    END;
 
   ...

END IO.


MODULE MyIOFileWrapper;

  IMPORT IO, Files;

  TYPE
    Reader = POINTER TO RECORD (IO.RandomReader)
      rider: Files.Reader
    END;

  PROCEDURE (this: Reader) ReadBytes (OUT buf: ARRAY OF BYTE; offset, count: INTEGER): INTEGER;
    VAR pos: INTEGER;
  BEGIN pos := this.rider.Pos();
    this.rider.ReadBytes(buf, offset, count);
    RETURN this.rider.Pos() - pos
  END ReadBytes;

  ...

  PROCEDURE NewRandomReader* (r: Files.Reader): IO.RandomReader;
    VAR a: Reader; 
  BEGIN ASSERT(r # NIL, 20);
    NEW(a); a.rider := r;
    RETURN a
  END NewRandomReader;

END MyIOFileWrapper.
Re[8]: Carrier-Rider-Mapper
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 31.05.06 11:12
Оценка:
Поправочка:

СГ> RandomReader* = POINTER TO ABSTRACT RECORD (Reader)
Re[7]: Carrier-Rider-Mapper
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 31.05.06 11:12
Оценка:
Здравствуйте, Cyberax, Вы писали:

>> Где Вы там увидели сокеты?


C>Это я к тому, что эта архитектура ввода-вывода не подходит для других

C>целей кроме чтения файлов.

Архитектура говорите не подходит, ну-ну...

C> А вот потоки прекрасно подходят.


И что же может помешать их использовать?

http://www.rsdn.ru/Forum/Message.aspx?mid=1928427&amp;only=1
Автор: Сергей Губанов
Дата: 31.05.06
Re[8]: Carrier-Rider-Mapper
От: WolfHound  
Дата: 31.05.06 11:17
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

СГ>И что мешает написать в точности тоже самое для моего примера?

Вот и я спрашиваю что мешало великим гениям создавшим черную коробку правильно спроектировать интерфейсы системы?
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[8]: Carrier-Rider-Mapper
От: WolfHound  
Дата: 31.05.06 11:25
Оценка: -1
Здравствуйте, Сергей Губанов, Вы писали:

СГ>Архитектура говорите не подходит, ну-ну...

Именно. Тебе пора наконец понять что оберон создавали простые смертные люди которые тоже могут ошибаться. И в данном случае они ошиблись.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.