PS: in this thread
nobody has disagreed about what OO programming is.
The disagreement was
about *how to apply it*.
There actually seems
to be quite a lot of agreement that the
answer depends on what
your underlying goal is:
��- is this throw-away
code for a specific problem?
��- is this code to be
included in a useful program?
��- is this just for
practice in an unfamiliar language
�� ��where you already
understand all the concepts?
��- is this for
learning about radically new concepts?
And everyone agrees
that test cases are good for all of these.
You might find it
useful to join another exercism thread and
solve some of these
problems in a language that you are
comfortable with, then
solve them in Smalltalk (or Ruby).
This will help to
separate "how do I solve this problem?"
from "how do I express
this solution in language X?"
Another thing you
might find useful, having solved a
problem, is to try to
solve it a different way.
For example, in a
functional language, you might solve a
problem first in a
C-like way using mutable objects freely.
Then you might solve
it again using immutable values.
And then you might
solve it again using higher-order functions.
And then you might
solve it again using point-free style as
much as you can.
For another example,
in R, or Fortran 90, or Matlab, you
might solve a problem
first in an element-at-a-time way,
and then you might try
it again using vectorisation to
eliminate as many
loops as you can.
And in *this* example,
don't suppose that there is One Right
Way To Do It.�� Get ONE
solution going.�� ANY solution.�� I would
suggest my approach,
because (a) of course I would, and (b) it
really is a struggle
with exercism to find out what the problem
actually is, and you
want to get to SOME solution quickly.�� But
it doesn't matter so
much, because the point is to try it MORE
ways than one.�� This
is one way to learn design.�� Try more than
one approach and
discover which ones work out better.
I started out using
Point.�� Then I tried again just using bare
coordinates.�� I
started with position and velocity as instance
variables.�� Then I
tried again with them as method temporaries.
I eliminated one thing
after another until I was left with
obviously correct
code, and I felt no shame in using
#caseOf: to classify
characters, even though there are books
that will tell you
that using "if" and "case" is anti-OO.
I could do it again
eliminating #caseOf: in terms of "if" if
I saw any value in
doing so.
In this particular exercise, you are
simulating
ONE instance (the robot) of ONE kind
of thing (Robots).
That strongly suggests that your
solution might have
ONE class: Robot, or perhaps TWO:
Robot and RobotTest.
That's the one active thing.
This thing has properties: where it is
and which way it
is going.�� Now from the point of view
of differential
geometry, points and directions are
different things and
live in different abstract spaces, so
I would have a lot
of sympathy for having two classes:
Place (x,y) and
Direction (dx,dy) with #turnLeft and
#turnRight as
operations on Direction and
place plus: distance in: direction
as an operation on Place returning a
new Place.
But a good
programmer is a lazy programmer, and
looks for existing
code to use.�� And the classic
Point class in
Smalltalk combines Place and Direction
in one
"two-dimensional vector" concept, originally
designed for 2D
computer graphics rather than
geometry.�� It's good
enough, and Smalltalk programmers
can be expected to
know that Point exists (just as Java
programmers can be
expected to know about Java's point
classes), so I'd use
it.
So now, from one
mind, we have designs with
1�� Robot
2�� Robot, RobotTest
3�� Robot, RobotTest,
Point
4�� Robot, RobotTest,
Place, Direction
classes.�� ANY of
them could be defended as a good design,
depending on what
the ultimate aim is.