Connecting Tech Pros Worldwide Forums | Help | Site Map

Question about class design

fernandez.dan@gmail.com
Guest
 
Posts: n/a
#1: Aug 20 '05
I'm still learning how to use Object Oriented concepts. I'm have a
basic question dealing with design. I have two classes that deal with
I/O pertaining to network and usb that inherit from an abstract parent
with four basic functions: Open, Read, Write, and Close.

// Note alot of the stuff has been left out
// just to give a basic picture
class IO
{
public:
virtual int Open(..) =0;
virtual int Read(..) =0;
virtual int Write(..) =0;
virtual int Close(..)=0;
};

class network : public IO{
....
};

class usb: public IO {
...
};

Now I want to create a class that uses the network or usb to
read/write. The different ways of doing these and I'm not sure which is
appropriate. Here my inital thoughts

1)
class MyProtocol
{
IO* m_io;

public:
MyProtocol(IO *);
};

Here I could give my class MyProtocol either Network or Usb and it
wouldn't care. The other choice
2)
class MyNetworkProtocol: public Network
{};

class MyUsbProtocol: public Usb
{ };

Here I will create two classes for each one but each class would have
the same logic.

These are the two choices that I thought of but I'm not sure which one
is appropriate. I'm still unsure about the design, I'm open to any
advice. Thanks

Danny


Cy Edmunds
Guest
 
Posts: n/a
#2: Aug 20 '05

re: Question about class design


<fernandez.dan@gmail.com> wrote in message
news:1124493440.686319.43080@g44g2000cwa.googlegro ups.com...[color=blue]
> I'm still learning how to use Object Oriented concepts. I'm have a
> basic question dealing with design. I have two classes that deal with
> I/O pertaining to network and usb that inherit from an abstract parent
> with four basic functions: Open, Read, Write, and Close.
>
> // Note alot of the stuff has been left out
> // just to give a basic picture
> class IO
> {
> public:
> virtual int Open(..) =0;
> virtual int Read(..) =0;
> virtual int Write(..) =0;
> virtual int Close(..)=0;[/color]

virtual ~IO() {} // or is that one of the things left out?
[color=blue]
> };
>
> class network : public IO{
> ....
> };
>
> class usb: public IO {
> ...
> };
>
> Now I want to create a class that uses the network or usb to
> read/write.[/color]

Why? An IO* points to exactly such a class. It seems to me you're done.
[color=blue]
> The different ways of doing these and I'm not sure which is
> appropriate. Here my inital thoughts
>
> 1)
> class MyProtocol
> {
> IO* m_io;
>
> public:
> MyProtocol(IO *);
> };[/color]

Pointless. This just wraps an IO* in a class. An IO is already a class.
[color=blue]
>
> Here I could give my class MyProtocol either Network or Usb and it
> wouldn't care. The other choice
> 2)
> class MyNetworkProtocol: public Network
> {};
>
> class MyUsbProtocol: public Usb
> { };[/color]

Polymorphism is for when you want to treat a family of classes as being the
same type when they actually aren't. For instance, you could have an array
of IO pointers and call Open on all the objects without knowing or caring
which type they actually are. The only thing you really could use is a smart
pointer:

#include "boost/shared_ptr.hpp"
typedef boost::shared_ptr<IO> IOPtr;

That will save you a lot of memory leak problems.

[snip]

--
Cy
http://home.rochester.rr.com/cyhome/


Alf P. Steinbach
Guest
 
Posts: n/a
#3: Aug 20 '05

re: Question about class design


* fernandez.dan@gmail.com:[color=blue]
> I'm still learning how to use Object Oriented concepts. I'm have a
> basic question dealing with design. I have two classes that deal with
> I/O pertaining to network and usb that inherit from an abstract parent
> with four basic functions: Open, Read, Write, and Close.
>
> // Note alot of the stuff has been left out
> // just to give a basic picture
> class IO
> {
> public:
> virtual int Open(..) =0;
> virtual int Read(..) =0;
> virtual int Write(..) =0;
> virtual int Close(..)=0;
> };
>
> class network : public IO{
> ....
> };
>
> class usb: public IO {
> ...
> };
>
> Now I want to create a class that uses the network or usb to
> read/write. The different ways of doing these and I'm not sure which is
> appropriate. Here my inital thoughts
>
> 1)
> class MyProtocol
> {
> IO* m_io;
>
> public:
> MyProtocol(IO *);
> };
>
> Here I could give my class MyProtocol either Network or Usb and it
> wouldn't care. The other choice
> 2)
> class MyNetworkProtocol: public Network
> {};
>
> class MyUsbProtocol: public Usb
> { };
>
> Here I will create two classes for each one but each class would have
> the same logic.[/color]

Assuming that the same protocol _may_ be used with both 'network' and 'usb'
choice 2 would mean redundant code, which is nearly always Evil (e.g., think
of maintenance, keeping two corresponding implementations in synch).

Also, the inheritance should probably not be public, because a protocol
isn't an 'io': you wouldn't want client code to circumvent the protocol,
calling 'read' and 'write' directly, would you?

However, you could do something like choice 2 as

3)
template< class IoProvider >
class Protocol: private IoProvider
{
...
};

The difference between choices 1 and 3 is that 1 provides _run-time_
selection of the IoProvider, while 3 provides _compile-time_ selection.

Choice 1 is far more flexible. While choice 3 can help you avoid things
like using an inappropriate Protocol/IoProvider combination, catching such
errors at compile time (e.g. a partial specialization with no
implementation) I don't think that's very much of an advantage in practice.
Also, choice 3 is more difficult to implement and debug.

[color=blue]
> These are the two choices that I thought of but I'm not sure which one
> is appropriate. I'm still unsure about the design, I'm open to any
> advice. Thanks[/color]

It may be that also Protocol should be designed as a pluggable class. And
perhaps it might be a good idea to think about protocol stacks, i.e.
protocols plugged into protocols for a few levels. But whether you need
that depends on the application you have in mind, and since generality
nearly always has some cost, both in development time and run-time, it is a
matter of biting nails, throwing dice, soliciting advice, perusing budgets,
checking what others have done, and so on, so as not to overdo generality.

Final word of advice: think about whether Protocol should be directly used
by client code.

Perhaps the design will be a lot cleaner if Protocol is designed as
pluggable into some class X that has a public interface adapted exclusively
to the client code's needs (implementing X might help design Protocol)?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
fernandez.dan@gmail.com
Guest
 
Posts: n/a
#4: Aug 20 '05

re: Question about class design


Thanks for your advice. Sometimes it's hard to think of the design
choices when you are your own client, just writing my own code for
myself.
[color=blue]
>Perhaps the design will be a lot cleaner if Protocol is designed as
>pluggable into some class X that has a public interface adapted exclusively
>to the client code's needs (implementing X might help design Protocol)?[/color]

Right on, I do have a class that contains my class Protocol. At the
time, I wrote it to make it cleaner to call my Protocol class. Well
thanks for the advice.

Closed Thread