"David Tillman" <dtillman / ozarkaircraftsystems.com> wrote:
>   1. The reply from David Alan Black (ruby-talk:18683) got me
>   to thinking a bit about object design.  When two objects
>   interact, how do you decide which object handles the interaction?
>
>   It could be that a good OOP design book would clear this up for me,
>   _Design_Patterns_ perhaps?
>
>   Example: in my HTML (HTMLoop) library for Ruby you can either pass
>   an Array to a Table object or you can tell an Array to output itself
>   as a table.  (I think it is convenient to have both as myArray.table
>   returns a string immediately but the Table object waits for a puts,
>   to_s, etc.)

A rule of thumb is to avoid cyclic dependencies between classes and never
have cyclic dependencies between packages (Ruby files and modules), which
means no cyclic dependencies between classes in different modules.  So, if
Table depends on Array, Array should not depend on Table.  Therefore you
should pass an array to a Table to fill in the table contents, rather than
add a method to Array to turn it into a Table.

By following this rule, a program becomes organised as layers of packages,
with generic, low-level packages at the bottom (data structures, file i/o,
networking, etc.) and application-specific packages at the top.  It sounds
like your HTMLoop package fits somewhere in the middle -- it's used by
application code and depends on generic packages.

Secondly, a class should depend on abstractions, rather than on concrete
classes.  In strongly typed languages, this means classes depend on abstract
interfaces.  In Ruby it means classes should use well-defined protocols to
communicate.  E.g. a Table should be able to process an enumerable object
(one that has an each method), rather than only Array objects.  This also
suggests that you should add the method to the Table class rather than the
Array class.

 Despite the title, The book Large Scale C++ Design by John Lakos has some
good guidelines for organising modules and classes that are applicable to
Ruby programming.

Cheers,
    Nat.