I'm a PHPer, and am not writing object-oriented code.
What are the advantages of OO over procedural code, and where can I learn how to apply these ideas to PHP?
I'm a PHPer, and am not writing object-oriented code.
What are the advantages of OO over procedural code, and where can I learn how to apply these ideas to PHP?
Objects help keep your code isolated between different sections, so that if you need to make a change to one section you can be confident it won't affect other sections: loose coupling.
Then, when you've done that for a while, you'll start finding that objects you created for one app are also useful in others, and you start getting better code re-use as well. So the new app has part of the work already done, and is using time-tested code: software is built faster with fewer bugs.
People will tell you various things about OOP, from various perspectives. But if you want to form your own opinion, rather than take someone else's, then I suggest reading Bertrand Meyer's "Object-Oriented Software Construction".
Essentially, he takes non-OOP programming techniques, and analyses their basic flaws. He then derives an alternative technique which addresses those flaws. Put another way, he derives OOP from first principles. It's a marvellous piece of work, and very convinving.
Read it, you'll learn the why, when and what in a way that you can back up with reasoning.
Yes, if you really get it.
It helps you visualize how parts of a larger system can interact with each other. It's very useful at the design level.
If you are just writing a few lines of code, the only benefit you will get is that it is generally a little easier to use a library broken into well-designed objects than just functions.
To make good use of it, you also need to follow sound OO design practices. Always encapsulating ALL your data, using many small classes, never large "catch-all" classes. Having the class do your work for you instead of asking it for data and doing the work outside the class, etc.
It's probably not going to help you much for a while, and possibly never if you are always doing small websites (I can't say this for sure, I don't really do php), but over time and on large projects it can be invaluable.
There was a time, back when i first started programming, that i wrote user-oriented code. It worked great, but was hard to maintain.
Then, i learned OO, and the code i wrote become easier to maintain, easier to share between projects, and life was good... for everyone except my users.
Now, i know the true silver bullet of computer programming. I write OO code, but first i objectify my users. Treating people as objects may seem rude at first, but it makes everything much more elegant - you get to write all of your software to work with clearly-defined interfaces, and when a user sends an unexpected message you can merely ignore it, or, if marked with a flag signifying sufficient importance, throw an exception at them.
Life, with OO, is good...
A large system, such as Wordpress, Drupal, or XOOPS, uses OOP concepts. You can see the benefits of their use there. Code reuse, modularity, maintainability, and extensibility.
You have the ability to modify parts of objects and it affects the entire application; no searching to replace every spot you did some operation (and possibly missing it).
You can reuse objects all over, saving an awful lot of copying and pasting. Patching a bug requires patching the one object, not 16 pages of code that all do the same thing.
When you encapsulate the logic and "hide" the implementation, it's easier to use the objects, both for you 6 months from now when you've forgotten why you did something, and for the nest guy or gal who uses your code. For example, all you do to loop through posts in Wordpress is call a function. I don't need to know how it works, I only need to know how to call it.
OOP is really procedural code wrapped in object methods/functions. You do still need to know how to write decent linear code in order to implement methods and functions of objects. It just makes it far easier to reuse, scale, fix, debug, and maintain your things.
It doesn't help you automatically. You can write worse "OO" programs than structural programs, and vice versa. OOP is a tool which allows you to create more powerful abstractions.
I would put it this way: If you write anything complex, you should encode the concepts you think in, rather than trying to think in concepts that are somehow native to the language you are using. This way you make less bugs. The formalization of those concepts is called design.
Functional programming lets you define concepts that are associated with verbs, since each function is essentially a verb (e.g., print()). OO programming, on the other hand, lets you also define concepts associated with nouns.
Objects help encapsulate complexity. For most PHP programming, it's impossible to write good, clean code for any reasonably complicated application. Writing OO PHP helps you put that code into its own box, isolating it from everything else. This has several benefits.
Poll::Display()
) to implement the entirety of what the app could do - which made maintaining my homepage far easier.Keep one thing in mind - OO in PHP (even PHP5) isn't very good OO compared to a language like Python or Ruby. The everything-is-an-object model in Python is what made me OO programming really click for me - and as a former PHP programmer (and doubly-certified Zend engineer), I strongly recommend exploring Python's OO if you want to understand what OO is all about. It will help you write better PHP code, at the very least.
One thing no one has mentioned is that OO code facilitates writing readable code:
sherry.changePhoneNumber();
phoneCompany.assignNewPhoneNumberTo(sherry);
sherry.receive(new PhoneNumber().withAreaCode("555").withNumber("194-2677"));
I get a strange satisfaction from such aesthetics.
To learn OO in PHP I'd recommend try to use some good written OO PHP framework.
You may want to look at Zend Framework.
I would say there are two primary benefits:
Reuse I wouldn't strictly qualify as an OO benefit, because in a purely procedural model smart library organization lets you reuse code as well.
On the other hand, using lots of objects in PHP tends to decrease performance compared to a procedural model, because there is too much object construction overhead for every request. Finding a good balance between procedural-style and oo-style code is imperative.
I am a PHP aswell, although I do have a strong OOP background, I would say the best book on using OOP with PHP has to be PHP 5 Objects Patterns and Practice
The huge win for me is inheritance, or making an object that behaves almost exactly like another but with a few differences. Here's a real-world example from my office:
We needed code to process TIFF files that a customer sent to us, convert them to a standard format, insert some information about the file into a database, then send a result email. I wrote this in a set of classes (in Python, but the idea is the same). The "fetcher" class got emails from a POP3 mailbox and handed them to a "container" class which knew how to read attachments from an email. That class handed each image off to a "file object" class that did the necessary processing.
Well, one day we got a customer who wanted to send PDF files. I subclassed the "TIFF file object" class and rewrote the "normalize" function to take a PDF as input instead, but left every other bit of code untouched. It worked the first time and I was pretty pleased.
A change to our mailserver meant that I needed to fetch emails via IMAP. Again, I subclassed the "POP3 fetcher" so that it could speak IMAP. Problem solved.
Another customer wanted to mail us CDs, so I subclassed the "email container" class with a "filesystem directory" class. Voila - done.
In each of those cases, the new code was 95% similar to the old code. For example, the "TIFF file object" class has about 15 methods. The "PDF file object" class defines exactly one: the method that converts files in a specific format into our standard. All others it gets from its parent class.
Now, you can definitely do the same kind of stuff procedurally, such as by writing:
if fileobjecttype == 'TIFF':
data = <snip 30 lines of code to read and convert a TIFF file>
elif fileobjecttype == 'PDF':
data = <another 45 lines to read a PDF>
elif fileobjecttype == 'PNG':
data = <yep, another one>
The biggest difference is that I believe you can make OOP look much cleaner and more organized. My PDF class looks like:
class PDFReader(GenericImageReader):
def normalize(self):
data = <45 lines to read a PDF>
and that's it. You can tell at a glance that it only does one thing differently than the class it inherits from. It also forces you - or at least strongly encourages you - to make clean interfaces between the layers of your application. In my example, the PDFReader has no idea and doesn't care whether its image came from a POP3 mailbox or a CD-ROM. The POP3 fetcher knows absolutely nothing about attachments, since its job is merely getting emails and passing them along. In practice, this has allowed us to do some pretty amazing things with the absolute minimum amount of coding or redesign.
OOP isn't magic, but it's a pretty fantastic way to keep your code organized. Even if you don't use it everywhere, it's still a skill that you really should develop.
To elaborate on Joeri's answer a little:
The International Organisation for Standardization defines encapsulation as, 'The property that the information contained in an object is accessible only through interactions at the interfaces supported by the object.'
Thus, as some information is accessible via these interfaces, some information must be hidden and inaccessible within the object. The property such information exhibits is called information hiding, which Parnas defined by arguing that modules should be designed to hide both difficult decisions and decisions that are likely to change.
Note that word: change. Information hiding concerns potential events, such as the changing of difficult design decisions in the future.
Consider a class with two methods: method a() which is information hidden within the class, and method b() which is public and thus accessible directly by other classes.
There is a certain probability that a future change to method a() will require changes in methods in other classes. There is also a certain probability that a future change to method b() will require changes in methods in other classes. The probability that such ripple changes will occur for method a(), however, will usually be lower than that for method b() simply because method b() may be depended upon by more classes.
This reduced probability of ripple impacts is a key benefit of encapsulation.
Consider the maximum potential number of source code dependencies (MPE - the acronym is from graph theory) in any program. Extrapolating from the definitions above, we can say that, given two programs delivering identical functionality to users, the program with the lowest MPE is better encapsulated, and that statistically the more well-encapsulated program will be cheaper to maintain and develop, because the cost of the maximum potential change to it will be lower than the maximum potential change to the less well-encapsulated system.
Consider, furthermore, a language with just methods and no classes and hence no means of information hiding methods from one another. Let's say our program has 1000 methods. What is the MPE of this program?
Encapsulation theory tells us that, given a system of n public nodes, the MPE of this system is n(n-1). Thus the MPE of our 1000 public methods is 999,000.
Now let's break that system into two classes, each having 500 methods. As we now have classes, we can choose to have some methods public and some methods private. This will be the case unless every method is actually dependent on every other method (which is unlikely). Let's say that 50 methods in each class is public. What would the MPE of the system be?
Encapsulation theory tells us it's: n((n/r) -1 + (r-1)p) where r is the number of classes, and p is the number of public methods per class. This would give our two-class system an MPE of 499,000. Thus the maximum potential cost of a change in this two-class system is already substantially lower than that of the unencapsulated system.
Let's say you break your system into 3 classes, each having 333 classes (well, one will have 334), and again each with 50 public methods. What's the MPE? Using the above equation again, the MPE would be approximately 482,000.
If the system is broken into 4 classes of 250 methods each, the MPE will would be 449,000.
If may seem that increasing the number of classes in our system will always decrease its MPE, but this is not so. Encapsulation theory shows that the number of classes into which the system should be decomposed to minimise MPE is: r = sqrt(n/p), which for our system is actually 4. A system with 6 classes, for example, would have an MPE of 465,666.
The Principle of Burden takes two forms.
The strong form states that the burden of transforming a collection of entities is a function of the number of entities transformed. The weak form states that the maximum potential burden of transforming a collection of entities is a function of the maximum potential number of entities transformed.
In slightly more detail, the burden of creating or modifying any software system is a function of the number of program units created or modified.
Program units that depend on a particular, modified program unit have a higher probability of being impacted than program units that do not depend on the modified program unit.
The maximum potential burden an modified program unit can impose is the impacting of all program units that depend on it.
Reducing the dependencies on an modified program unit therefore reduces the probability that its update will impact other program units and so reduces the maximum potential burden that that program unit can impose.
Reducing the maximum potential number of dependencies between all program units in a system therefore reduces the probability that an impact to a particular program unit will cause updates to other program units, and thus reduces the maximum potential burden of all updates.
Thus, encapsulation is a foundation stone of object orientation and encapsulation helps us to reduce the maximum potential number of dependencies between all program units and to mitigate the weak form of the Principle of Burden.
I would argue that OOP suits those who think in 'objects', where an object consists of data as well as the functions that operate on that data.
I'd caution against going out and learning about patterns. In order to do object-oriented programming well, you need to teach yourself to think like an object-oriented programmer. You'll need to get to the point where you understand and can name the benefits of:
It will help you to be a better programmer only in the sense that the more styles of programming a programmer knows, the more range in his repertoire for solving problems and writing elegant code. You cannot go off and write all your code object-oriented and automatically have good code, but if you really understand how OOP works, and you're not just copy-pasting some popular design patterns of the day, then you can write some pretty good code, especially when writing a large application.
It seems everybody is responding to your question literally, i.e., the specific benefits/drawbacks of OO.
You should learn OO, but not because OO has any specific magic that you need.
The more general form is:
One of the best thing that I did with OOP in PHP is the class generator. In any given table, it will involve almost the same SQL operations:
Now I don't have to write all these SQL statements anymore, except on special conditions. Not only I've cut down coding to 1 minute in doing above, I've also saved time from debugging codes.
So whenever there are changes to the table structure, I simply regenerate the class.
Probably you should try the same as it works for me and my customers like it!