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.

Reply via email to