On class design

Discussion in 'C++' started by jakash3, Nov 21, 2011.

  1. jakash3

    jakash3 Guest

    I've noticed that in Languages like Java and C#, some classes have
    methods named "GetInputStream" and "GetOutputStream" rather than
    having the class inherit from a stream class. For example. Instead of
    having something like this:

    Code:
    File f;
    f.open("foo.txt");
    f.print("hello world!\n");
    f.print("aslkdfj sladkfj sladkf");
    f.close();
    
    (where File inherits from both InputStream and OutputStream)

    You have something like this:

    Code:
    File f;
    OutputStream os;
    os = f.GetOutputStream();
    os.print("hello world!\n");
    os.print("asdfj sladkfj sladkf");
    f.close();
    
    Which design is better?
     
    jakash3, Nov 21, 2011
    #1
    1. Advertising

  2. jakash3

    Goran Guest

    On Nov 21, 2:02 am, jakash3 <> wrote:
    > I've noticed that in Languages like Java and C#, some classes have
    > methods named "GetInputStream" and "GetOutputStream" rather than
    > having the class inherit from a stream class. For example. Instead of
    > having something like this:
    >
    >
    Code:
    > File f;
    > f.open("foo.txt");
    > f.print("hello world!\n");
    > f.print("aslkdfj sladkfj sladkf");
    > f.close();
    > 
    > (where File inherits from both InputStream and OutputStream)
    >
    > You have something like this:
    >
    >
    Code:
    > File f;
    > OutputStream os;
    > os = f.GetOutputStream();
    > os.print("hello world!\n");
    > os.print("asdfj sladkfj sladkf");
    > f.close();
    > 
    >
    > Which design is better?


    First is clearly better if a "File" class is sufficient for all
    "streaming"^^^ needs you'll ever have. Second is better if your
    streams aren't always files (e.g. you want to "save" something by
    sending it to another server over the network, and indeed, you can
    find file-like objects that talk to an FTP server, or if you merely
    want to "save" it without any disk operation (e.g. a memory stream).
    Also, separate stream helps if you want specific features on top of
    what streaming through a file offers. For example, having a buffered
    stream helps in speeding up file operations, and having a
    "compressing" stream (the one that turns "raw" stream into a
    compressed form, say, by gzip-ing the data) helps in taking less space
    or bandwidth.

    Streaming: not watching porn over internet ;-), but rather, turning
    data from arbitrary structure into a byte-after-byte stream of bytes
    (for the purpose of reverting that into original data at a later
    stage).

    Goran.
     
    Goran, Nov 21, 2011
    #2
    1. Advertising

  3. jakash3 <> wrote:
    > I've noticed that in Languages like Java and C#, some classes have
    > methods named "GetInputStream" and "GetOutputStream" rather than
    > having the class inherit from a stream class. For example. Instead of
    > having something like this:
    >
    >
    Code:
    > File f;
    > f.open("foo.txt");
    > f.print("hello world!\n");
    > f.print("aslkdfj sladkfj sladkf");
    > f.close();
    > 
    > (where File inherits from both InputStream and OutputStream)
    >
    > You have something like this:
    >
    >
    Code:
    > File f;
    > OutputStream os;
    > os = f.GetOutputStream();
    > os.print("hello world!\n");
    > os.print("asdfj sladkfj sladkf");
    > f.close();
    > 
    >
    > Which design is better?


    In the case of a File class I would strongly prefer the second variant,
    because a File class is usually used for moving, copying, deleting, or
    testing for existence of a file. That means, the actual file does not have
    to be open or even existent to construct a File object.
    However, to use stream functionality, you need an existing file, you need
    the correct permissions and you must open it correctly.
    The GetXxxStream() method provides you a clearly defined point where the
    file is opened and a single point of failure in the case that you can't.
    And by closing the stream you can unlock the actual file and use again the
    File methods for example to delete it.

    So use the second variant always if the class does not represent a stream
    by itself, but some other resource that can be used to acquire a stream by
    e.g. opening a file, establishing a connection, or something similar.

    Tobi
     
    Tobias Müller, Nov 21, 2011
    #3
  4. jakash3

    Jorgen Grahn Guest

    On Mon, 2011-11-21, Tobias Müller wrote:
    ....
    >>
    Code:
    >> File f;
    >> OutputStream os;
    >> os = f.GetOutputStream();
    >> os.print("hello world!\n");
    >> os.print("asdfj sladkfj sladkf");
    >> f.close();
    >> 
    >>
    >> Which design is better?

    >
    > In the case of a File class I would strongly prefer the second variant,
    > because a File class is usually used for moving, copying, deleting, or
    > testing for existence of a file. That means, the actual file does not have
    > to be open or even existent to construct a File object.
    > However, to use stream functionality, you need an existing file, you need
    > the correct permissions and you must open it correctly.
    > The GetXxxStream() method provides you a clearly defined point where the
    > file is opened and a single point of failure in the case that you can't.


    Then I'd prefer to call it Open(). GetXxxStream() makes it sound as
    something that cannot fail (as if the opening took place a long time
    ago and you're just picking up a reference to the result).

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Nov 22, 2011
    #4
  5. Jorgen Grahn <> wrote:
    > Then I'd prefer to call it Open(). GetXxxStream() makes it sound as
    > something that cannot fail (as if the opening took place a long time
    > ago and you're just picking up a reference to the result).
    >
    > /Jorgen


    True. But the concept of separating the functionality is still better IMO.
    It's better to enforce correct programs by the type system rather than just
    document the correct call sequence (Not to call print() before open() for
    example)

    Anyway, it would be interesting to see a concrete example with such a
    GetXxxStream() method (from the Java API or similar) rather than just
    speculate.

    Tobi
     
    Tobias Müller, Nov 22, 2011
    #5
  6. jakash3

    jakash3 Guest

    I think I should make a stream class and 2 derived line stream and
    buffer stream classes. None of those classes will be abstract, instead
    the core putc and getc methods will just fail with a ENOTSUP error
    instead of being pure virtual. Specialized derived classes like
    Filestream and Socketstream and Memoerystream will have to overload
    them so that it will work. So then I should have something like this:

    Code:
    Linestream *lns;
    Stream *s;
    socket::tcp sock;
    
    sock.connect("www.google.com", "80");
    lns = sock.getstream();
    s = sock.getstream();
    lns->puts("GET / HTTP/1.1\r\nHost: www.google.com\r\n\r\n");
    con.put(s->read(1, atoi(lns->drink("\r\n\r\n").slurp("Content-Length:
    "))));
    sock.close();
    delete lns;
    delete s;
    
    where sock.getstream will return a new socketstream object which can
    be assigned to one of the stream, linestream, or bufstream pointers
    for polymorphism.
    lns.drink("\r\n\r\n") means read data from socket as string until a \r
    \n\r\n sequence is detected. and the .slurp("Content-Length: ") means
    remove "Content-Length: " from this string and all character preceding
    it. con.put means write this object to the console screen. Stream
    s.read(size_t size, size_t nmemb) means read nmemb elements each of
    size byte long from this stream and return it as a data object.

    The project relating to this that I'm working on is this:
    http://sourceforge.net/projects/libaxcel/
     
    jakash3, Nov 22, 2011
    #6
  7. jakash3

    Jorgen Grahn Guest

    On Tue, 2011-11-22, Tobias Müller wrote:
    > Jorgen Grahn <> wrote:
    >> Then I'd prefer to call it Open(). GetXxxStream() makes it sound as
    >> something that cannot fail (as if the opening took place a long time
    >> ago and you're just picking up a reference to the result).
    >>
    >> /Jorgen

    >
    > True. But the concept of separating the functionality is still better IMO.
    > It's better to enforce correct programs by the type system rather than just
    > document the correct call sequence (Not to call print() before open() for
    > example)


    No conflict there -- I imagined a

    std::eek:stream& Foo::eek:pen();

    method.

    > Anyway, it would be interesting to see a concrete example with such a
    > GetXxxStream() method (from the Java API or similar) rather than just
    > speculate.


    Yes -- the OP seemed to be heavily based in Java and C#, but I know
    nothing about the background in that world for his question.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Nov 23, 2011
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. E11
    Replies:
    1
    Views:
    4,937
    Thomas Weidenfeller
    Oct 12, 2005
  2. christopher diggins
    Replies:
    16
    Views:
    784
    Pete Becker
    May 4, 2005
  3. John_Woo

    class design vs. db design

    John_Woo, Dec 19, 2006, in forum: Java
    Replies:
    2
    Views:
    355
    John_Woo
    Dec 19, 2006
  4. Joseph Turian
    Replies:
    5
    Views:
    627
  5. Bartholomew Simpson

    class design/ design pattern question

    Bartholomew Simpson, Jun 12, 2007, in forum: C++
    Replies:
    2
    Views:
    462
    Daniel T.
    Jun 12, 2007
Loading...

Share This Page