Re: How to hide implementation details?
On May 26, 7:51 am, Puppet_Sock <puppet_s...@hotmail.com> wrote:
On May 25, 10:33 pm, Immortal Nephi <Immortal_Ne...@hotmail.com>
wrote:> I want to create an interface of a door.
[snip]
Um. And this isn't homework?
No, homework does not exist. Every reader is aware what my post was
said in the past. I learn independently doing self-study at home.
Every time, I post class example. They always said bad design. I
could not find any good book to explain how to do good design. I
found old post when someone posted to say how to break giant class
into pieces of classes.
They suggested a book. The second edition book's title is Code
Complete and author's name is Steve McConnell. I bought it from
Amazon. I spent all day reading Chapter 5 =96 Design and Construction
and Chapter 6 =96 Working Classes. That book is very interesting.
The client is able to see
the implementation behind the interface because inheritance is
present. The code is stored in the header. How do I hide the
implementation?
"But doctor! Doctor! It hurts when I do this!"
"Well, then, don't do that."
Don't put the implementation in the header file unless
there is a good reason for it. Some template stuff has
to go in the header, for example. I don't *see* any
templates in your files.
You are right. The client is able to see private data members and
private member functions in the class in header. The class should be
interface. I talk about abstraction and inheritance hierarchy.
A door is an abstraction of a particular arrangement of=
a rectangular
piece of material with hinges and a doorknob. It has four routines o=
f
Open(), Close(), isOpened(), and isClosed().
Ok. It seems like a pretty early stage in your class. Hmm...
May the 26th. Summer school has started?
No summer school like I said before.
And the doorknob is in turn an abstraction of a particu=
lar formation
of brass, nickel, iron, or steel. It has four routine of Lock(),
Unlock(), IsLocked(), and IsUnlocked().
As Daniel T said, this does not really work very well.
A door knob isn't a door, it's part of a dor. It does
not make a lot of sense to inherit here.
Possibly you might want door and knob to inherit from
some other class. Something like "stuff from the hardware
store" or something like that. Look up the factory idiom
to see why that *might* make sense.
And also, Color_Knob is in turn an abstraction of some =
colors.
How do I put three objects of Door, Knob, and Color_Kno=
b together
into a function or another class. Is it the way how design looks
good?
The inheritance does not make any sense, but it should =
be
composition. Open() and Close() belongs to Door and they have no
reasons to be inherited into doorknob class nor color_knob class.
Also, Lock() and Unlock() belongs to doorknob class and should not be
inherited into color_knob.
So, you already know it does not make sense. Ok.
I did not say very clear. House is an abstraction. You write =93class
house=94. How do you break complexity into simple code? You need to
divide or decompose house into several classes.
Several classes are derived from house, which is called windows,
doors, siding, wiring, plumbing, insulation, etc. I focus to
decompose door class. Knob class is derived from door class. Colored
knob class is derived from knob class.
I hope that you know what I mean. I talk about decomposing classes.
You can notice Lock() and Unlock() are in knob class and should not be
inherited into colored knob class. Also, Open() and Close() from door
class should not be inherited into knob class.
I guess you are suggesting not to use inheritance hierarchy. Then,
write two base classes of knob and colored knob. Put them into door
class as composition.
Do you understand what I am saying?
Should knob_door and color_knob objects be created into=
memory and
place them in Door class like composition?
That's one way. How you choose to combine functionality
of different parts of a problem will depend on context.
Does your application require to be able to have a door
as an object, and a knob as an object, as separate things?
That is, can you have a door with no knob? Can you have
a knob with no door? If you can, can they go together
after you make them? So, is it a door factory or some
such thing that you are running here? Or is it one or
more rooms with doors all set and just opening, closing,
locking, unlocking, etc.? That is, do you want to change
door configuration (knob, no knob, colour, no colour,
etc.) or not?
If you are never going to create doors except with knobs
already there, then maybe you don't want a separate
knob type at all. If you are going to be swapping knobs
in and out, maybe you want composition with the knob
being pointed at by a member pointer rather than as
a member object. Then you could have polymorphism on
knob type.
For example:
/* Header Door.h */
class Door
{
public:
Door() {}
virtual ~Door() {}
virtual void Open() {}
virtual void Close() {}
virtual bool IsOpened() { return m_door; }
virtual bool IsClosed() { return !m_door; }
private:
bool m_door;
};
Yeah. If you care about this implementation being visible,
then you put it in the source file (.cpp or .c++ or
.cxx or whatever your compiler calls it.) If you are
wanting to make the variables not visbible from the
header file the client sees, then look up the "pointer
to implementation" idiom. It's allso called PImpl.
Yes, I know what you mean. It is called private implementation. It
is annoying to create private implementation in **each classes**.
Maybe, you are suggesting let create interface in header and
implementation in source code.
After you put all headers and source codes into package, you create
package interface and private implementation. It becomes to be the
component library. The client will only see interface when they
include header into their code.
Also, m_door is a poor name. What about the door does
it contain? Maybe change that to something like m_isOpen
or something.
class Knob : public Door
We already talked about inheritance here.
Public inheritance is usually easiest to get right if
you use the substitution principle. If childClass
inherits from parentClass, then you should be able
to use an instance of childClass whenever an instance
of parentClass is required.
Can you proffer up a knob whenever a door is required?
Probably not.
Just to shake you up a bit, consider it the other way.
Can you proffer up a door whenever a knob is required?
Hmmm... In some contexts, if doors *always* have knobs,
then maybe you can. So maybe you can inherit the other
way, door from knob. Though, in most contexts, that
is going to be pretty bad.
{
public:
Knob() {}
virtual ~Knob() {}
virtual void Lock() {}
virtual void Unlock() {}
virtual bool IsLock() { return m_Knob; }
virtual bool IsUnlocked() { return !m_Knob; }
private:
bool m_Knob;
};
class Color_Knob : public Knob
{
public:
Color_Knob() {}
virtual ~Color_Knob() {}
void Select_Brass() { color = Brass; }
void Select_Nickel(){ color = Nickel; }
void Select_Iron(){ color = Iron; }
void Select_Steel(){ color = Steel; }
bool IsBrass() { return color == Brass; }
bool IsNickel() { return color == Nickel; }
bool IsIron() { return color == Iron; }
bool IsSteel() { return color == Steel; }
Ick. Next week you will want to add glass knobs.
Or fake ivory ones that are made of plastic.
And you will need to write new functions and
recompile the code to do it. Or brass knobs will
go out of style or something, and you will have
to remove those functions.
This is an example of where you probably want
stuff about the class to be visible.
private:
enum Color
{
Brass,
Nickel,
Iron,
Steel
} color;
Color Get_Color() { return color; }
This enum should probably be available to any client.
And you should just have one setcolour function and
one getcolour function.
Or you could have the colours as items in a config
file that can be modified without changing the code.
Then you could read in the list of colours that are
available at the store (factory, etc.) Store them in
a vector of some kind.
Context, always context. How likely is it that next
week you will have a different set of colours for
doors or knobs?
[rest snipped]
Socks- Hide quoted text -
- Show quoted text -- Hide quoted text -
- Show quoted text -