Stoooopid OOP question. (Really. You've been warned.)

Hey, all. I’ve never taken a for-real OOP-related course, and I’m 99%
sure I’m completely misunderstanding what is probably a very fundamental
OOP concept, and was wondering if someone would be kind enough to
enlighten me.

Say I’m parsing a file of pets/widgets/whatever. For simplicity’s sake,
let’s assume they have unique names. Everything I see about
instantiating an object says to do something like this:

foo = Pet.new

“foo”, though, doesn’t smell very unique to me. After I’ve created my
objects, how do I reference the ones associated with “Fido”, “Elsie” and
“Clifford”?

I’ve been doing things like

name = “Elsie”
pets = Hash.new
pets[name] = Pet.new

but my Spidey sense says I’m doing this just plain wrong. I’ve googled
and read, and while I’m sure the answer is “out there,” I’m guessing
that I’m simply not thinking this through the right way. Any pointers?

Thanks (and apologies),

-Ken

On 14-09-04, 14:26, Ken D’Ambrosio wrote:

I’ve been doing things like

name = “Elsie”
pets = Hash.new
pets[name] = Pet.new

Often that’s all you need, if all you want is a lightweight way to
gather objects together. I’m guessing that what you’re asking about is
how do you reference each unique object by some key? In that case, you
should have a hash of some sort that indexes them by the keys you need.

However, the “true” OOP way is to create a PetsCollection, which
internally stores your hash (or array), and then you can add the methods
you need for interacting with the collection of pets:

pets = PetsCollection.new(pets)
pets.dogs
pets.cats
pets.named("Elsie")

Andrew V.

On Sep 4, 2014, at 14:47, Andrew V. [email protected] wrote:

However, the “true” OOP way is to create a PetsCollection, which internally
stores your hash (or array), and then you can add the methods you need for
interacting with the collection of pets:

I can’t disagree with this more. There’s nothing about “true” OOP that
says each and everything is a unique and precious blossom and must have
hand crafted code. Stick to the XP(*) way:

Do the simplest thing that could possibly work.

In this case, a hash is just fine. Even an array would work depending on
the use cases.

*) Ward Cunningham and Kent Beck are frighteningly smart people. You
know what ELSE they are? Serious OOP guys.

How could it be more OOP to create a new type of object for storing
individual pets with methods to access them, when this is exactly what
the Array or Hash class does already?

pets = Array.new
pets.push Pet.new
puts pets[0]

How is this any different from

pets = PetsCollection.new
pets.push Pet.new
puts pets[0]

I prefer to think OOP as creating new data types, when the primitive
types the language provides are insufficient.

Of course, as was mentioned by Andrew, if you really need methods such
as pets.named, you may consider creating a new class, if that simplifies
your code. In ruby, almost anything is an object, so to me it can’t get
any more OOP-ish.

What Ryan said. Overdesigning and overbuilding are bad design
principles, not good OOP.

What I see in your proposed use case, Ken, is that the proposed
‘PetsCollection’ object doesn’t appear to represent a ‘noun’. The name
hints to me that it’s not representing a domain object with specific
functionality; it’s just a wrapper. If it’s just a wrapper, then leave
it as a hash until you find that you really need a PetStore class or a
Menagerie class.

On 5 September 2014 18:09, Ryan D. [email protected] wrote:

There’s nothing about “true” OOP that says each and everything is a unique
and precious blossom and must have hand crafted code.

I thought Java taught us that OOP = Enterprisey, and Enterprisey =
CLASSES
FOR EVERYTHING!!1

Although I suppose Enterprisey doesn’t mean “hand crafted code” so much
as
it means “rigorous application of patterns”.​

​/snark

On 14-09-05, 1:09, Ryan D. wrote:

I can’t disagree with this more. There’s nothing about “true” OOP that says each
and everything is a unique and precious blossom and must have hand crafted code.

For what it’s worth, I absolutely agree with you as long as the hash
serves the purpose. There’s a reason I wrote “true” OOP in quotes there.
Maybe I should have said “academic”?

Andrew V.

On 14-09-05, 6:32, NBarnes wrote:

What I see in your proposed use case, Ken, is that the proposed
‘PetsCollection’ object doesn’t appear to represent a ‘noun’. The name
hints to me that it’s not representing a domain object with specific
functionality; it’s just a wrapper. If it’s just a wrapper, then leave
it as a hash until you find that you really need a PetStore class or a
Menagerie class.

A “Collection” for lack of a better name to represent what’s actually
needed. (It is a noun by the way.)

It could be Murder.new(crows) for all I know.

Andrew V.

On Sat, Sep 6, 2014 at 12:59 AM, Andrew V. [email protected] wrote:

On 14-09-05, 1:09, Ryan D. wrote:

I can’t disagree with this more. There’s nothing about “true” OOP that
says each and everything is a unique and precious blossom and must have hand
crafted code.

For what it’s worth, I absolutely agree with you as long as the hash serves
the purpose. There’s a reason I wrote “true” OOP in quotes there. Maybe I
should have said “academic”?

Sounds slightly better to me. But even then there is the issue that
(academic or not) OOP does not mandate a single correct solution.
Giving that impression is misleading. Any software design should be
catered to the problem at hand that needs solving. That could be a
single Hash, a new class like you suggested or even a much more
complex class with automated indexing and whatnot. It all depends on
what the program is supposed to do eventually.

The core treat of OO to me is that you bundle data with the allowed
operations on it and can ensure that the internal state of an object
always stays within some bounds that the code establishes. That
avoids errors and mistakes. For me the concept of “Abstract Data
Type” comes very close to this property of OO.

And note, that I did not even mention inheritance, which often seems
to be seen very fundamental to OO. I rather think the fact that you
can have different implementations of the same abstract API is much
more important. But I’m digressing… :slight_smile:

Kind regards

robert

On Sep 4, 2014, at 5:47 PM, Andrew V. [email protected] wrote:

However, the “true” OOP way is to create a PetsCollection, which internally
stores your hash (or array)

This is correct except that

(a) OOP doesn’t say you can’t use Hash directly if its interface works
for you, and

(b) OOP doesn’t say you need to put the type of a thing in its name
(despite all the ServiceFactoryController nonsense out there). Do we
call you AndrewHuman or just Andrew? “Pets” works fine as a class name,
or “Zoo” or “Family” if you want to get whimsical.

class Pets
def initialize
@index = {}
end
def add(pet)
@index[pet.name] = pet
end

  • A