OOP and the 'real world'

Ready for a mind blowing philosophical OOP question?

I know that an object is supposed to be thought of as a SET of properties. I also know about inheritance, that child properties GENERALLY have the parent properties and method+ then some.

What I have been pondering is how/when to represent the REAL world in OOP form.

Yup, not a code code question, but the PHILOSOPHY BEHIND a best practice.

easy part first. I know that when something is contained by something else it is best represented by a property.

class  passenger{}
class vehicle{
     var  passengers;
     var  driver;
}
class car extends vehicle{

}

I know (and detest) the basic tutorial example:

class animal{}
class rabbit extends animal{}

but it seems somewhat academic when trying to envision a real world relational system.


class pet  extends animal {} 

ok, then represent my pet rabbit??? represent my pet rabbit among wild rabbits?? represent my pet rabbit among wild rabbit being chased by pet dogs?

it also seems that you can build any working class hierarchy system up until YOU have to scale it

Again:

class animal{}
class rabbit extends animal{}
class pet extends rabbit {}

works until there other animals you want to have as pets

class animal{}
class pet extends animal{}
class rabbit extends pets {}

works until there you realize not ALL rabbits are pets.

so

class animal{}
class rabbit extends animal{
    var $pet=flase;// default
    function makePet($owner){
         // now you have to set a property and create property that didn't exist before in the 'wild'
   }
}

or


class animal{
    var $specie;
}
class wild extends animal {
__construct($specie){}
}
class pet extends animal  {
__construct($specie,$owner,$name ){}
}

this is fine until you need to domesticate a will animal into a pet.

In short, all hierarchical systems need a SET start and a SET end… so as to be able to determine whats should be a class and what should be a property.

Well I am sorry I have made a mess of all my examples above. Simply phrased my question is … what criteria does an experienced OOProgramer use to determine what is a child class, an independent class or a property so that his/her code is scalable?

It’s a strange coincidence, I was just thinking about this earlier today. You might find the answer to this stack overflow question helpful.

Basically it suggests that you ask yourself if the quality you’re trying to represent with a subclass is permanent or not. In the case of an animal (such as the rabbit) it’s conceivable that it only becomes a pet at a certain point in its life, and it may also stop being a pet. With a subclass, a change in status would require creating a new object of a different type.

I needed a laugh today. and the whole thing about having to kill Fred is making me ROTFLMAO.

I hope you can se that the argument started for the same reason I outlined above IF YOU CAN TELL THE SCOPE before you start coding is fine, you can chose a path. But that is seldom the case. Projects up/downscale.

I like the idea of ‘roles’ but in PHP, because it would allow instances access to methods and properties o f other classes. But in PHP that seems somewhat convoluted

$dropDeadFred->currentRole->specificMethod();
sounds like asking for disaster.

Also:
this now leans to limiting the levels of inheritance and opting for ‘roles’ since in the real world most everything SPLITS or forks

We can only be sure that the rabit is an animal and either male or female. anything else could change during the course of it’s life.

so our representation end up being an unintuitive:

class animal{}
class female extends animal{}
class male extends animal{}
class rabbit extends …oops here is another fork… so even tho we are sure the animal will be a male bunny for life… we also end up adding a gender role.

so when do we get to extend?

The decorator pattern may be the best solution here. It allows behavior to be added at run-time. Though, this pattern requires some setup.

// the design-time groundwork:
// redirect all rabbit methods to a private rabbit object
abstract class RabbitDecorator extends Rabbit {
    private rabbit
    
    RabbitDecorator(rabbit) {
        this.rabbit = rabbit
    }
    
    someMethod1() {
        return this.rabbit.someMethod1();
    }
    
    someMethod2() {
        return this.rabbit.someMethod2();
    }
}

Now we can define behaviors that can be added at run-time.

class PetRabbitDecorator extends RabbitDecorator {
    someMethod1() {
        // something different
    }
}

class FemaleRabbitDecorator extends RabbitDecorator {
    someMethod2() {
        // something different
    }
}

Now we can write logic like this:

rabbit = new Rabbit()

// behaves like a normal rabbit
rabbit.someMethod1()
rabbit.someMethod2()

// turn it into a pet
petRabbit = new PetRabbitDecorator(rabbit);

// behaves like a pet
petRabbit.someMethod1()
petRabbit.someMethod2()

// turn it into a female
femalePetRabbit = new FemaleRabbitDecorator(petRabbit);

// behaves like a female pet
femalePetRabbit.someMethod1()
femalePetRabbit.someMethod2()

I think I like that approach. Normally, the Firefighter/Person would satisfy the inheritance test. A firefighter “is a” person. But you’re right that you wouldn’t want to start with a person object just to later destroy and replace it with a firefighter object, then later destroy and replace the firefighter object with a person object again.

@Jeff_Mott - I’ve not used decorators much, are there any disadvantages to them?

On disadvantage that I can think of is intuitiveness.

it’s unlikely , given the proposed structure of my OP . the changing creating a new variable/changing the name of the object is tantamount to killing it.

would this be possible:


bugs = new Rabbit()

// behaves like a normal rabbit
rabbit.someMethod1()
rabbit.someMethod2()

// turn it into a pet
bugs = new PetRabbitDecorator(bugs);

// behaves like a pet
petRabbit.someMethod1()
petRabbit.someMethod2()

// turn it into a female
bugs = new FemaleRabbitDecorator(bugs);

// behaves like a female pet
femalePetRabbit.someMethod1()
femalePetRabbit.someMethod2()  

I may not be understanding this pattern correctly, but another caveat… which was also the cause of my OP, is it doesnt seem expandable.

What if you have dozens of species?
would we need to have female/male classes for each species? That doesnt seem like an accurate representation of life…

I would figure the goal would be to have classes do this:

Animal->Gender->species->wild/dom (can change)->…
maybe the decorator should only be part of the species? Or maybe I am kind of lost about how it’s deployed.

Without knowing the actual logic you’re trying to model, the best I can say is that you may need a healthy combination of inheritance, composition, and possibly traits as well.

If we’re still talking about species, then I suspect inheritance will be the right choice in most cases, because the “tree of life” follows that kind of pattern. Gender would probably be a class property defined close to the root of the inheritance chain. Temporary or individualistic behaviors, such as being a pet, would probably be a decorator. And, yes, you may have to define several kinds of decorators, which may actually make sense, since it seems likely that different species will exhibit different behaviors as pets. Where common behaviors exist, you can put that logic in a base class decorator, such as perhaps PetAnimalDecorator.

Yeah… I understand what you guys are saying but am applying…“client logic”. So the problem is that am not talking about anything specific, but merely the whims of clients in representing a real world that seems simplistic to them. “now that you have structured our zoo to include all species… how hard could it be to make some animals male/female… some domesticated/wild.” even tho those weren’t criteria at the start of the project. I had an example involving cities and school districts… where building had rooms and rooms had teachers, but teaches were people, could change rooms …etc

which is why I phrased my question as looking for guidelines to ‘representing the real world’ via oop