OOP Question

  • Thread starter Thread starter RSH
  • Start date Start date
R

RSH

I was reading a tutorial on OOP principals and design and I stumbled on
something that I don't understand. The tutorial used a Oven class. In that
class there was a private field called temperature.

class Oven {
private int _temperature;

public int Temperature {
get {
return _temperature;
}
set {
_temperature = value;
}
}
}

This is the implementation I would normally employ. BUT... The article
says...
"The type Oven exposes its temperature as a property, which is a direct
reference to the variable _temperature. This means that the internal oven
temperature implementation is tied directly to its external interface. The
point of good object-oriented programming is to avoid this sort of
programming."

That seems strange to me...what if I have to expose temperature? What if my
cookie object needs to preheat the oven to 350 degrees dont I need to
monitor the temperature of the oven object?

Damn just when I started to think I was getting OOP!

Thanks,

Ron
 
I was reading a tutorial on OOP principals and design and I stumbled on
something that I don't understand. The tutorial used a Oven class. In that
class there was a private field called temperature.

This is the implementation I would normally employ. BUT... The article
says...
"The type Oven exposes its temperature as a property, which is a direct
reference to the variable _temperature. This means that the internal oven
temperature implementation is tied directly to its external interface. The
point of good object-oriented programming is to avoid this sort of
programming."

That sounds like a bad book to me. The implementation will always be
tied to the interface - the point is to avoid the *reverse* being
true, i.e. exposing the implementation itself as the interface.

I've certainly heard people saying that properties should almost
always be avoided etc, but it's not a particularly commonly-held view.

Jon
 
Ron,

I am curious, what does the article recommend is the workaround? I
think that what it is trying to say is that you would have a Temperature
object which you would expose which would expose all the details of working
with temperature.

Of course, eventually, one will reach the point of diminishing returns,
meaning that you could only extend this so far before it becomes impossible
to work with (expose an object for temperature, which exposes an object for
degrees, etc, etc).

Oh, and the cookie wouldn't change the temperature, the Baker instance
would. The Baker instance would add the Cookie to the Sheet, and then add
the Sheet to the Oven. Then the Bake method would be called on the Oven,
which would change the Baked property of the individual Cookie instances on
the sheet over time.
 
Nicholas and Jon,

I appreciate both of your input...I highly respect the both of you and have
learned alot from you both.

This is the solution that they suggest:

delegate void OnTemperature( int temperature);

class Oven {
private int _temperature;
OnTemperature _listeners;

public void BroadcastTemperature() {
_listeners( _temperature);
}
public void AddTemperatureListener( OnTemperature listener) {
_listeners += listener;
}
}
class Controller {
public Controller( Oven oven) {
oven.AddTemperatureListener(
new OnTemperature( this.OnTemperature));
}
public void OnTemperature( int temperature) {
Console.WriteLine( "Temperature (" + temperature + ")");
}
}http://en.csharp-online.net/CSharp_Coding_Solutions—Dont_Expose_a_Class_Internal_StateRon"Nicholas
Paldino said:
Ron,

I am curious, what does the article recommend is the workaround? I
think that what it is trying to say is that you would have a Temperature
object which you would expose which would expose all the details of
working with temperature.

Of course, eventually, one will reach the point of diminishing returns,
meaning that you could only extend this so far before it becomes
impossible to work with (expose an object for temperature, which exposes
an object for degrees, etc, etc).

Oh, and the cookie wouldn't change the temperature, the Baker instance
would. The Baker instance would add the Cookie to the Sheet, and then add
the Sheet to the Oven. Then the Bake method would be called on the Oven,
which would change the Baked property of the individual Cookie instances
on the sheet over time.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

RSH said:
I was reading a tutorial on OOP principals and design and I stumbled on
something that I don't understand. The tutorial used a Oven class. In
that class there was a private field called temperature.

class Oven {
private int _temperature;

public int Temperature {
get {
return _temperature;
}
set {
_temperature = value;
}
}
}

This is the implementation I would normally employ. BUT... The article
says...
"The type Oven exposes its temperature as a property, which is a direct
reference to the variable _temperature. This means that the internal oven
temperature implementation is tied directly to its external interface.
The point of good object-oriented programming is to avoid this sort of
programming."

That seems strange to me...what if I have to expose temperature? What if
my cookie object needs to preheat the oven to 350 degrees dont I need to
monitor the temperature of the oven object?

Damn just when I started to think I was getting OOP!

Thanks,

Ron
 
I appreciate both of your input...I highly respect the both of you and have
learned alot from you both.

This is the solution that they suggest:

<snip>

So basically an event model with no direct "read on demand" other than
telling *all* listeners the temperature, and also with no control over
the temperature.

That kind of thing will be appropriate *sometimes*, but far from
always - in particular, I can't see why one client should be able to
make the oven notify all the other listeners of the temperature,
whether or not it's changed (the most obvious reason for wanting to
know).

Jon
 
Jon,

Thank you...I thought I was losing it! I agree the Observer pattern is
without question a powerful pattern and has its place...but this seemed to
me like someone was overcomplicating design just to match an acedemic
interpretation, and not looking at the maintainability of actual coding. i
mean it seems to me that if you have a complex series of objects
communicating like this it would be almost impossible to debug and unit
test.

Ron
 
Nicholas Paldino said:
Ron,

I am curious, what does the article recommend is the workaround? I
think that what it is trying to say is that you would have a Temperature
object which you would expose which would expose all the details of
working with temperature.

Of course, eventually, one will reach the point of diminishing returns,
meaning that you could only extend this so far before it becomes
impossible to work with (expose an object for temperature, which exposes
an object for degrees, etc, etc).

Oh, and the cookie wouldn't change the temperature, the Baker instance
would. The Baker instance would add the Cookie to the Sheet, and then add
the Sheet to the Oven. Then the Bake method would be called on the Oven,
which would change the Baked property of the individual Cookie instances
on the sheet over time.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

RSH said:
I was reading a tutorial on OOP principals and design and I stumbled on
something that I don't understand. The tutorial used a Oven class. In
that class there was a private field called temperature.

class Oven {
private int _temperature;

public int Temperature {
get {
return _temperature;
}
set {
_temperature = value;
}
}
}

This is the implementation I would normally employ. BUT... The article
says...
"The type Oven exposes its temperature as a property, which is a direct
reference to the variable _temperature. This means that the internal oven
temperature implementation is tied directly to its external interface.
The point of good object-oriented programming is to avoid this sort of
programming."

That seems strange to me...what if I have to expose temperature? What if
my cookie object needs to preheat the oven to 350 degrees dont I need to
monitor the temperature of the oven object?

Damn just when I started to think I was getting OOP!

Thanks,

Ron

In my case, where I AM THE BAKER, the BAKED property is an enumeration.

Values of BAKED:

Uncooked,
Undercooked,
Burned,
DUDEYourHouseIsOnFire


Temperature property is similar:

Off,
LukeWarm,
TemperatureOfTheSun,
HotterThanTheSun,
DUDEYourHouseIsOnFire

:)

Mythran
 
Hmmm... Get and set the _desired_ temperature seems to be an attribute
of the oven. When I want to know the actual temperature of our oven I
need to use a thermometer. I suppose some ovens have a built in
thermometer, in which case the oven class could contain a thermometer
with a get only property. I suppose the oven could beep when the preset
temperature is reached, so there could be an event that fires when the
desired temperature is reached.

Regards,
Jeff
 
Hmmm... Get and set the _desired_ temperature seems to be an attribute
of the oven. When I want to know the actual temperature of our oven I
need to use a thermometer. I suppose some ovens have a built in
thermometer, in which case the oven class could contain a thermometer
with a get only property. I suppose the oven could beep when the preset
temperature is reached, so there could be an event that fires when the
desired temperature is reached.

That is similar to my oven. I can set the temperature through one
control and read the temperature using a different control. Both
controls are public members of some oven-control type. All objects of
type oven should have a controller member. This indirection is likely
what the original quote in question meant.

"The type Oven exposes its temperature as a property, which is a
direct reference to the variable _temperature. This means that the
internal oven temperature implementation is tied directly to its
external interface. The point of good object-oriented programming is
to avoid this sort of programming."

regards
A.G.
 
AG... Without access to the tutorial I really don't know what the author
meant:)

Off the top of my head, I don't see any problem with the Oven class
having a get temperature property. The use of a get Temperature as a
_property_ still involves indirection. For instance, say get is in
degrees F. In the future, the oven could be redesigned using an internal
hidden "thermometer" which "reports and stores" in degrees C without
affecting the public view which could still return in degrees F.

As I see it, the use of events instead of get only is a different design
decision: get/polling vs push/events. An "event",
OnTemperatureChangedOneDegreeF:) would be useful to avoid polling.

FWIW, some have argued against the use of the term "Broadcasters" or
"Broadcast" with events and listeners. I certainly used that naming
convention in the past, but Broadcast in IP is used to notify all nodes
and the term Broadcaster fell out of favor for events with a limited
domain of listeners.

Regards,
Jeff
That is similar to my oven. I can set the temperature through one
control and read the temperature using a different control. Both
controls are public members of some oven-control type. All objects of
type oven should have a controller member. This indirection is likely
what the original quote in question meant.
<
 
AG... Without access to the tutorial I really don't know what the author
meant:)
You are correct.
Off the top of my head, I don't see any problem with the Oven class
having a get temperature property. The use of a get Temperature as a
_property_ still involves indirection. For instance, say get is in
degrees F. In the future, the oven could be redesigned using an internal
hidden "thermometer" which "reports and stores" in degrees C without
affecting the public view which could still return in degrees F.
Let me correct myself and say layers of indirection. I see an oven as
a complex type with many different piece parts. In an electric oven
the temperature is managed by a thermostatic controller. The
_temperature value would be a property of the controller.

class Oven {
private ThermostaticController Controller;

public int Temperature
{
get { return this.Controller.Temperature; }
set { this.Controller.Temperature = value; }
}

If it seems like organizational semantics that is because it is. In an
OOP tutorial I would expect to come across the concept of objects
containing objects containing objects and sibling interaction through
the use of events.

As you say without access to the tutorial we'll never really know.
As I see it, the use of events instead of get only is a different design
decision: get/polling vs push/events. An "event",
OnTemperatureChangedOneDegreeF:) would be useful to avoid polling.
With an oven you wouldn't be polling the temperature. The time at
temperature is the important value and that would be a property of the
oven's timer.

It is difficult to design a virtual oven without understanding how a
real one works. Perhaps we should start at howstuffworks.com ;)
FWIW, some have argued against the use of the term "Broadcasters" or
"Broadcast" with events and listeners. I certainly used that naming
convention in the past, but Broadcast in IP is used to notify all nodes
and the term Broadcaster fell out of favor for events with a limited
domain of listeners.
Broadcast is a misnomer when it comes to events. An event is more
pay-per-view because the pre-registration requirement, that limited
domain of subscribers versus everyone.

regards
A.G.
 
Jeff Louie said:
AG... I got carried away coding. Never got past the Temperature class:)
Any thoughts.

http://www.geocities.com/jeff_louie/OOP/oop38.htm

I haven't read through it in detail, but my initial thought is that
you've got a class which claims to be a test, but actually only outputs
stuff to the console. Turn it into a unit test, and that way you can:

1) Call the methods which should throw exceptions
2) Specify the expected output
3) Actually run it to make sure everything works as expected
 
AG... I got carried away coding. Never got past the Temperature class:)
Any thoughts.

http://www.geocities.com/jeff_louie/OOP/oop38.htm
There seems to be much more complexity than is needed. A temperature
is a number from a scale that describes a point on a line. The scale
used has no effect on the point's position. Zero degrees Celsius and
32 degrees Fahrenheit both describe the same point.

Think about
1 - enumerating the scales.
2 - a temperature type with a Degrees and a Scale property
3 - a thermostatic type used to with temperature objects. Thermostatic
because some devices are read-only (thermometer) while others can be
set as well (controller).

In general...
Then think about it again. Be able to express your design to yourself
in words before trying to write code. As you mentally step through the
design, weak points and gotchas can be discovered. Try and figure out
the different ways the problem may be solved. Write some throw-away
code to prototype the different ideas.

Once you're done abstracting ideas and have settled on and understand
a design, writing the types and their interactions will be a matter of
translating your well thought-out ideas into code. There will be no
surprises because you'll have mentally written the pseudo-coded
numerous times.

Some important things to remember are
- don't try to discover the answer by writing 'real' code
- the first idea is seldom the best or most complete solution
- if something is hard to do, there is probably a better way to do
it.
- simple is not bad
- the big investment should be in the wetware's understanding of the
problem and possible solution(s)
- always look for and consider real-world models when considering a
design.

It can take some time to really understand OOP/A/D but the transition
will be instantaneous. One minute you'll kind of understand it and the
next you'll "get" it.

For some mental gymnastics try the "man walks into a bar..." scenario.
The first thing you'll need to do is provide a Door type member for
the Bar object. Or would that be a member derived from a Door type?

regards
A.G.
 
AG.. A few expensive rockets and space vessels have crashed using simple
numbers. I'll pass :).

Regards,
Jeff
 
AG.. A few expensive rockets and space vessels have crashed using simple
numbers. I'll pass :).
There have been a few notable incidents resulting from the failure to
convert from one unit of measure to another. I mean simple by avoiding
unnecessary complexity. It is better to use the formula
C = 5(F-32)/9;
than
C = Sqrt((5F ^ 2 - 320F + 5170) / 81);

regards
A.G.
 
For some mental gymnastics try the "man walks into a bar..." scenario.
The first thing you'll need to do is provide a Door type member for
the Bar object. Or would that be a member derived from a Door type?

regards
A.G.

Another post from me that has nothing to do with the topic...my apologies,
but I couldn't help it for this post :)



Well, it depends on whether the bar the man walks into is the type of bar
you order drinks, or just a vertical or horizontal metallic bar that hurts
if you walk into it! :)

Mythran
 
Back
Top