tags:

views:

602

answers:

12

I am learning php5 and have covered all the basics concepts.

Now to do the actual work. I realize the biggest challenge for me is dividing and organizing which classes should do what; I am stuck.

With proecedural, I would be half done by now...

What are some rules of deciding how many objects you should be using? Do you divide to smallest bits of objects as possible?

+2  A: 

It'll take time. There are some good books. I'd suggest start with "Head First OOA&D"

For now, Think of the entities (typically nouns) involved in your case, These are objects. Then try to note all the smallest actions (typically verbs) possible, These are methods. Then think which objects should be responsible for which action?

Of course its much more than this, but you can use this as a starting point.

Padmarag
+1  A: 

It is just depends on your scenario. You don't need to think about smallest bits everytime. Those are just rules of thumb.

If you can defend your design then you are done ;)

Just read some good books on OOP. You can find hundreds of resources very easily. Then you will gain some ability to think of a better design..

Chathuranga Chandrasekara
+14  A: 

If your a procedural man you think about a problem algorithmically -- i.e., what primitives do I need to use in a linear fashion to solve a problem. Your unit of modularization is a procedure/function.

Once you move to OOP your unit of abstraction becomes the object. Objects are at a higher level of abstraction and have the ability to model problems much better.

Each function may now be localized to an object (the functions state) -- in contrast to procedural programming where you have to keep global state, or have to provide references to state. Collections of functions and their state make up an object intrinsically.

Now for an example: Say you had to animate a man in some graphics software -- if it has OOP features you need to create a model of the main in terms of objects.

class man
{
    leg leftLeg;
    leg rightLeg;
    arm leftArm;
    arm rightArm;
    head _head;
}

Now if you wanted to move the man forward by one step the following might be an implementation of this method:

progressStepRight()
{
    leftLeg.moveForward();
    rightLeg.moveForward();
    rightArm.movebackward();
    leftArm.moveForward();
}

A man represents a torso and is composed of arms,legs, and a head (it is represented in-terms-of these items). You tell a man to move and the man object manages its legs and arms -- each arm and leg may have its own state (state is encapsulated by an object). For example the positions of the legs -- I just showed you the method which progressed the entire body Right -- however the legs and arms might know their positions (as their object state) so we could replace the position based methods with a simple move method:

Each of the limbs needs to move -- and its behavior is if limb is left then move limb forward right else move forward left. All four limbs share this behavior -- arms and legs are limbs!!. The OO world allows would allow you to specify that arms and legs are limbs, and by doing this the arms and legs will inherit the behavior of a limb.

--edit (after comment) --

However, if arms and legs begin to differ (during the evolution of the code) then it is best for a leg and an arm not to inherit any behavior from a limb -- but to implement the interface of the limb (they can still "move" but they do it in different ways).

-- edit/end --

If you were to implement the man's animation procedurally it would be a linear representation of what needs to happen, this source code representation has a lot less inferable knowledge than its OO counterpart. An OO representation is a lot more self-explanatory, and when you come back a few months later you should be able to understand and alter your algorithm much more quickly.

Hassan Syed
This is a very nice and comprehensive intro to OO modeling. Careful with the terminology though, especially when explaining to OOP newbies.Technically speaking, the torso _uses_ the limbs, which "encapsulate" their own _state_, and they don't "inherit" any behaviour in this example, they are more likely to _implement_ the limb's interface.
xtofl
Made some changes -- should show both the "inherit" and "interface" concept and why interface is likely to be a safer bet in this example. Also, encapsulate has been placed into a more OO specific context.
Hassan Syed
Likewise, be careful with the (sadly) ubiquitous confusion between "object" and "class". They are totally different things, albeit related.
CesarGon
+5  A: 

Think of your OOP inheritance and classes as being families and siblings where "properties" are "memories of individuals", "methods" are "abilities", and "individuals" being instanciated objects. Then try to start thinking as "if I were this object, what could I do and why?". After a while thinking this way becomes a natural feeling when designing classes and families of classes, which have common or distinctive abilities and properties. You can then advance to more advanced OOP design and techniques. Try always to find some real-life analogies. It will help a lot. That's how I learned about OOP back in the Turbo Pascal 5.5 times.

hurikhan77
+1  A: 

First read "Object-Oriented Analysis and Design with Applications" by Grady Booch. It is useful in starting thinking with OOP & OOD

skwllsp
+2  A: 

Write it down as you would do in procedural style (this will help you have a good understanding of the problem first). Then, half way through, imagine what would happen if you were to change a parameter. Or if you were to change a function signature, or a "property". When you start understanding how you could have done it in a different way you can actually start re-writing it inserting some objects. Yes, the first time it takes a while, but you're learning.

OOP programming for me was a "a-ha!" moment. At a certain point I realized how much useful they were, and how much I could have saved time, and how much the entire structure could have been more elegant. Like somebody said,

make the difficult easier, the easy simpler, and the simple elegant

Once you get past this point you start actually thinking in objects: to solve a problem you don't have to shape it around the programming language you're using, but you can start writing your problem down with objects.

If that does not help, I found Thinking In Java to be an extremely useful book, especially the first chapters. Take a look here for an excerpt of what OOP applied to the real world is (the link points to a source code describing various super-heroes ability in terms of Interfaces). If that does not stimulate your curiosity, I don't know what can :)

Oh, and if you are sure you understood how you can apply OOP to your problem the first time straight, you most certainly are wrong.

lorenzog
+2  A: 

You might want to start with something like StarUML or ArgoUML to draw the models of your appllication first. It helped me a lot to look at code (that hasn't been written yet) from different angles (class diagrams, action diagrams, etc.) in order to find errors/bugs or missing classes.

iRoybot
Thanks - I never heard of StarUML.
xtofl
you're very welcome. I prefer ArgoUML - we use those tools to draw diagrams, then compile PHP classes from the XMI files (you can save Zargo files as XMI in ArgoUML)
iRoybot
+1  A: 

You should look the Introduction to OOP article to get a basic introduction to OOP. I think that this is a good introduction to OOP. And the article was created by a PHP programmer.

Pedro Ghilardi
+3  A: 

If you follow MVC principles:

  • You should have one class for each database table (called a model)
  • You should have controller classes that do the work of taking user input and passing it to the models
  • Views arnt classes, just pages for displaying the objects recived from the controller
  • And any other helper classes that just make things easier
Petah
+2  A: 

There are some objects there are many of. Value objects like dates, integers and strings. Also your business objects like persons, tickets, cars and other things that represent something from the real world. These types of object are in my experience the ones that are most often used as examples when OO is taught, and they are the easiest to get right.

Then there are some objects there will only be one of in your application. These are more difficult to get right, because they typically do not represent something "real", but rather define the structure of your application. The reason these are difficult is because there is nothing about the business domain that can help you decide how to structure your application; there are infinite many ways to achieve the same result.

One thing that will help you here though, is OO patterns. Patterns are generic OO solutions. One of the well known patterns for structuring an application, is the Model-View-Controller pattern, which itself comes in many variations that make use of other patterns. The canonical book on patterns is "Gang of Four" and IMHO it is a must-read. Even if none of the patterns described in it is a perfect match to your problem, it is still a great inspiration of how to think OO design.

Other guidelines for good OO design:

Each class should have one and only one responsibility. Once a class starts to get big, ask yourself what the responsibility of the class is. If you find you can't answer this question simply, it probably means the class has too many responsibilities and you need to divide it into more classes with more clearly defined responsibilities.

Law of Demeter: Each object should only know about and talk to it's immediate collaborators. This is also known as the law of One Dot, meaning you should not dot your way through the object graph to get to the object you need.

Dependency injection. Make sure you provide an objects collaborators to it through its constructor. Objects should never instantiate their own collaborators, and they should not either have to ask others for them. (This is also known as the hollywood principle: "Don't call us. We'll call you")

Some other resources to improve you OO design:

Miško Hevery's blog - Great blog that explains how designing for testability also improves your OO design in general.

Refactoring Book - How to gradually improve your OO design.

KaptajnKold
+3  A: 

I recommend Head First books. They have a book about OOP, but also about Design Patterns. Really interesting and easy to read.

Bright010957
A: 

Try to think of objects as nouns and methods as verbs. Basically, every thing that is separate entity in your app that has its own distinct behavior would have its class (class and object is basically data+behavior). The classes can be related by containment (where contained object doesn't have separate life and significance except in the context of the container) and by use (where two objects have separate life and association depends on one object interacting with the other). That can be dependent on your app - so, the car engine is inseparable from the car from the driver's POV, since teh engine is useless without a car for him, but very much separable from the auto shop mechanic's POV, because he has to keep track of the stock, etc.If you notice the "kind of" relationship (like in example brought here arm and leg are "kind of" limb) that's a case for inheritance.

It may be useful to draw a class diagram before you begin, not necessarily formal but at least a sketch.

StasM