Related
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
So I'm working on this class that's supposed to request help documentation from a vendor through a web service. I try to name it DocumentRetriever, VendorDocRequester, DocGetter, but they just don't sound right. I ended up browsing through dictionary.com for half an hour trying to come up with an adequate word.
Start programming with bad names is like having a very bad hair day in the morning, the rest of the day goes downhill from there. Feel me?
What you are doing now is fine, and I highly recommend you stick with your current syntax, being:
context + verb + how
I use this method to name functions/methods, SQL stored procs, etc. By keeping with this syntax, it will keep your Intellisense/Code Panes much more neat. So you want EmployeeGetByID() EmployeeAdd(), EmployeeDeleteByID(). When you use a more grammatically correct syntax such as GetEmployee(), AddEmployee() you'll see that this gets really messy if you have multiple Gets in the same class as unrelated things will be grouped together.
I akin this to naming files with dates, you want to say 2009-01-07.log not 1-7-2009.log because after you have a bunch of them, the order becomes totally useless.
One lesson I have learned, is that if you can't find a name for a class, there is almost always something wrong with that class:
you don't need it
it does too much
A good naming convention should minimize the number of possible names you can use for any given variable, class, method, or function. If there is only one possible name, you'll never have trouble remembering it.
For functions and for singleton classes, I scrutinize the function to see if its basic function is to transform one kind of thing into another kind of thing. I'm using that term very loosely, but you'll discover that a HUGE number of functions that you write essentially take something in one form and produce something in another form.
In your case it sounds like your class transforms a Url into a Document. It's a little bit weird to think of it that way, but perfectly correct, and when you start looking for this pattern, you'll see it everywhere.
When I find this pattern, I always name the function xFromy.
Since your function transforms a Url into a Document, I would name it
DocumentFromUrl
This pattern is remarkably common. For example:
atoi -> IntFromString
GetWindowWidth -> WidthInPixelsFromHwnd // or DxFromWnd if you like Hungarian
CreateProcess -> ProcessFromCommandLine
You could also use UrlToDocument if you're more comfortable with that order. Whether you say xFromy or yTox is probably a matter of taste, but I prefer the From order because that way the beginning of the function name already tells you what type it returns.
Pick one convention and stick to it. If you are careful to use the same names as your class names in your xFromy functions, it'll be a lot easier to remember what names you used. Of course, this pattern doesn't work for everything, but it does work where you're writing code that can be thought of as "functional."
Sometimes there isn't a good name for a class or method, it happens to us all. Often times, however, the inability to come up with a name may be a hint to something wrong with your design. Does your method have too many responsibilities? Does your class encapsulate a coherent idea?
Thread 1:
function programming_job(){
while (i make classes){
Give each class a name quickly; always fairly long and descriptive.
Implement and test each class to see what they really are.
while (not satisfied){
Re-visit each class and make small adjustments
}
}
}
Thread 2:
while(true){
if (any code smells bad){
rework, rename until at least somewhat better
}
}
There's no Thread.sleep(...) anywhere here.
I do spend a lot of time as well worrying about the names of anything that can be given a name when I am programming. I'd say it pays off very well though. Sometimes when I am stuck I leave it for a while and during a coffee break I ask around a bit if someone has a good suggestion.
For your class I'd suggest VendorHelpDocRequester.
The book Code Complete by Steve Mcconnell has a nice chapter on naming variables/classes/functions/...
I think this is a side effect.
It's not the actual naming that's hard. What's hard is that the process of naming makes you face the horrible fact that you have no idea what the hell you're doing.
I actually just heard this quote yesterday, through the Signal vs. Noise blog at 37Signals, and I certainly agree with it:
"There are only two hard things in Computer Science: cache invalidation and naming things."
— Phil Karlton
It's good that it's difficult. It's forcing you to think about the problem, and what the class is actually supposed to do. Good names can help lead to good design.
Agreed. I like to keep my type names and variables as descriptive as possible without being too horrendously long, but sometimes there's just a certain concept that you can't find a good word for.
In that case, it always helps me to ask a coworker for input - even if they don't ultimately help, it usually helps me to at least explain it out loud and get my wheels turning.
I was just writing on naming conventions last month: http://caseysoftware.com/blog/useful-naming-conventions
The gist of it:
verbAdjectiveNounStructure - with Structure and Adjective as optional parts
For verbs, I stick to action verbs: save, delete, notify, update, or generate. Once in a while, I use "process" but only to specifically refer to queues or work backlogs.
For nouns, I use the class or object being interacted with. In web2project, this is often Tasks or Projects. If it's Javascript interacting with the page, it might be body or table. The point is that the code clearly describes the object it's interacting with.
The structure is optional because it's unique to the situation. A listing screen might request a List or an Array. One of the core functions used in the Project List for web2project is simply getProjectList. It doesn't modify the underlying data, just the representation of the data.
The adjectives are something else entirely. They are used as modifiers to the noun. Something as simple as getOpenProjects might be easily implemented with a getProjects and a switch parameter, but this tends to generate methods which require quite a bit of understanding of the underlying data and/or structure of the object... not necessarily something you want to encourage. By having more explicit and specific functions, you can completely wrap and hide the implementation from the code using it. Isn't that one of the points of OO?
More so than just naming a class, creating an appropriate package structure can be a difficult but rewarding challenge. You need to consider separating the concerns of your modules and how they relate to the vision of the application.
Consider the layout of your app now:
App
VendorDocRequester (read from web service and provide data)
VendorDocViewer (use requester to provide vendor docs)
I would venture to guess that there's a lot going on inside a few classes. If you were to refactor this into a more MVC-ified approach, and allow small classes to handle individual duties, you might end up with something like:
App
VendorDocs
Model
Document (plain object that holds data)
WebServiceConsumer (deal with nitty gritty in web service)
Controller
DatabaseAdapter (handle persistance using ORM or other method)
WebServiceAdapter (utilize Consumer to grab a Document and stick it in database)
View
HelpViewer (use DBAdapter to spit out the documention)
Then your class names rely on the namespace to provide full context. The classes themselves can be inherently related to application without needing to explicitly say so. Class names are simpler and easier to define as a result!
One other very important suggestion: please do yourself a favor and pick up a copy of Head First Design Patterns. It's a fantastic, easy-reading book that will help you organize your application and write better code. Appreciating design patterns will help you to understanding that many of the problems you encounter have already been solved, and you'll be able to incorporate the solutions into your code.
Leo Brodie, in his book "Thinking Forth", wrote that the most difficult task for a programmer was naming things well, and he stated that the most important programming tool is a thesaurus.
Try using the thesaurus at http://thesaurus.reference.com/.
Beyond that, don't use Hungarian Notation EVER, avoid abbreviations, and be consistent.
Best wishes.
In short:
I agree that good names are important, but I don't think you have to find them before implementing at all costs.
Of course its better to have a good name right from the start. But if you can't come up with one in 2 minutes, renaming later will cost less time and is the right choice from a productivity point of view.
Long:
Generally it's often not worth to think too long about a name before implementing. If you implement your class, naming it "Foo" or "Dsnfdkgx", while implementing you see what you should have named it.
Especially with Java+Eclipse, renaming things is no pain at all, as it carefully handles all references in all classes, warns you of name collisions, etc. And as long as the class is not yet in the version control repository, I don't think there's anything wrong with renaming it 5 times.
Basically, it's a question of how you think about refactoring. Personally, I like it, though it annoys my team mates sometimes, as they believe in never touch a running system. And from everything you can refactor, changing names is one of the most harmless things you can do.
Why not HelpDocumentServiceClient kind of a mouthful, or HelpDocumentClient...it doesn't matter it's a vendor the point is it's a client to a webservice that deals with Help documents.
And yes naming is hard.
There is only one sensible name for that class:
HelpRequest
Don't let the implementation details distract you from the meaning.
Invest in a good refactoring tool!
I stick to basics: VerbNoun(arguments). Examples: GetDoc(docID).
There's no need to get fancy. It will be easy to understand a year from now, whether it's you or someone else.
For me I don't care how long a method or class name is as long as its descriptive and in the correct library. Long gone are the days where you should remember where each part of the API resides.
Intelisense exists for all major languages. Therefore when using a 3rd party API I like to use its intelisense for the documentation as opposed to using the 'actual' documentation.
With that in mind I am fine to create a method name such as
StevesPostOnMethodNamesBeingLongOrShort
Long - but so what. Who doesnt use 24inch screens these days!
I have to agree that naming is an art. It gets a little easier if your class is following a certain "desigh pattern" (factory etc).
This is one of the reasons to have a coding standard. Having a standard tends to assist coming up with names when required. It helps free up your mind to use for other more interesting things! (-:
I'd recommend reading the relevant chapter of Steve McConnell's Code Complete (Amazon link) which goes into several rules to assist readability and even maintainability.
HTH
cheers,
Rob
Nope, debugging is the most difficult thing thing for me! :-)
DocumentFetcher? It's hard to say without context.
It can help to act like a mathematician and borrow/invent a lexicon for your domain as you go: settle on short plain words that suggest the concept without spelling it out every time. Too often I see long latinate phrases that get turned into acronyms, making you need a dictionary for the acronyms anyway.
The language you use to describe the problem, is the language you should use for the variables, methods, objects, classes, etc. Loosely, nouns match objects and verbs match methods. If you're missing words to describe the problem, you're also missing a full understanding (specification) of the problem.
If it's just choosing between a set of names, then it should be driven by the conventions you are using to build the system. If you've come to a new spot, uncovered by previous conventions, then it's always worth spending some effort on trying extend them (properly, consistently) to cover this new case.
If in doubt, sleep on it, and pick the first most obvious name, the next morning :-)
If you wake up one day and realize you were wrong, then change it right away.
Paul.
BTW: Document.fetch() is pretty obvious.
I find I have the most trouble in local variables. For example, I want to create an object of type DocGetter. So I know it's a DocGetter. Why do I need to give it another name? I usually end up giving it a name like dg (for DocGetter) or temp or something equally nondescriptive.
Don't forget design patterns (not just the GoF ones) are a good way of providing a common vocabulary and their names should be used whenever one fits the situation. That will even help newcomers that are familiar with the nomenclature to quickly understand the architecture. Is this class you're working on supposed to act like a Proxy, or even a Façade ?
Shouldn't the vendor documentation be the object? I mean, that one is tangible, and not just as some anthropomorphization of a part of your program. So, you might have a VendorDocumentation class with a constructor that fetches the information. I think that if a class name contains a verb, often something has gone wrong.
I definitely feel you. And I feel your pain. Every name I think of just seems rubbish to me. It all seems so generic and I want to eventually learn how to inject a bit of flair and creativity into my names, making them really reflect what they describe.
One suggestion I have is to consult a Thesaurus. Word has a good one, as does Mac OS X. That can really help me get my head out of the clouds and gives me a good starting place as well as some inspiration.
If the name would explain itself to a lay programmer then there's probably no need to change it.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I have a comics website, http://hittingtreeswithsticks.com, and I guess I'm unclear as to which style, procedural or OO, that it's written in.
Basically, there are several "templates", homepage.php, viewall.php, viewFullSize.php, which call upon various scripts... namely, the templates all include imageDisplay.php, which has several scripts which determine how to query based on which category, tag, or subsite is selected.
I've read a lot about the benefits of OO programming- when it's used and when it's not... but am still having trouble answering this question.
The way I understand the difference between OOP and procedural from an example standpoint is:
OOP: If you have a website where a user can create an object, such as a forum where a user can submit a post... then you'd want to go with OOP because you'd want to allow users to create several instances of the Article class.
Procedural: I went with what I think is procedural because my comics website simply displays comics out to users. A user can submit a comment using DISQUS, or like/dislike. I don't see where I'd be able to fit the OOP paradigm into a simple image display site.
So, the question is:
To use OOP, do you necessarily need to have several objects that would be instantiated? Or are there other benefits I'm missing?
Thanks
Do both.
Just call the procedures "methods", or your methods "procedures".
Objects don't need to correspond to real world objects, it's as much about modularization and moving code into isolated (!) chunks as about "objects".
All in all, a website is not the best to understand OOP. Too little inheritance happening.
Instead, write a simulation. For example, a road with maybe a crossroad and a few drivers driving around.
Start with a stupid driver, then try to allow for subclassing it with different smarter drivers. Or aggressive drivers. And see if they can cause more traffic jams.
Try to start with a problem where you have natural objects that share a lot of traits, and only differ in a few.
Always code OOP. The only reason people ever code procedural PHP is because they're using pre PHP 5.
To answer your question, no. You can have a single object. OOP is just for code organization and the implementation of DRY principals.
OO is normally a better aproach, as long as you document correctly and are aware of class dependencies/herance/hierarquy.
Besides adding a bit of security to your code, an correctly implemented OOP is trully powerfull for adding and upgrading new features, organize code, reuse logic.
As everything is within it's object definition, you always know where and what to look for.
Yes, is kinda tricky at times but it pays.
Non OOP is good practice only in basic methods, small coding.
Something like the "Hello world" :p
Or a non server content dependedence of content or better known as static websites.
For OO you don't require an object to have definition like parametters or whatever.
In your case, you could have an object for db handling, another for top menu bar, another that handle comic book related stuff like sorting, listing...
Basicly wraping everything in it's corresponding place, reusing code more efficiently..
Hope this helped
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
This is just an opinion question but I don't want to elicit debate. I just want professional feedback on whether it's good practice or bad practice to have your classes do all the work to where you just need to instantiate the object. if everything goes well, then you do the next step whatever it is in your application, within the class. If something goes wrong, you create a function to emit the errors within the class also.
I do all of this with the magic __construct method, and all my properties are private (or protected if i need to extend something)... most of my methods are private/protected also, except for getters and setters which i don't use much anyway, since everything happens inside the class.
For example, I have a login class, and you just feed it the username and password parameters when you instantiate it, and everything happens with the __construct I don't need to do anything with my script using that class. Also... same thing with my registration class.. you just feed it the parameters again and the class does everything. I don't need to be manipulating my classes at all with scripts.
Good practice or bad practice? I want to be a professional and I want to start coding like one, but maybe I'm doing it OK?
I voted to close this since it will probably spark a relatively useless debate.
Anyway, there are two big theories on constructors: single stage and multiple stage. You're doing single stage. Many people argue for single stage. However, I think it's bad practice. Why?
Because it makes it more difficult to test. When you write tests you want to test individual functionality of an object .. but if your constructor does everything that becomes impossible.
It also makes it harder to reuse the object for a different purpose later. Your object may do everything you need it to do except for one extra method call in the constructor -- so now you have to rewrite it a bit and change how it's called in at least a couple places.
The real answer is do what you're most comfortable with in the confines of your project.
The method __construct should only instantiate (validate/prepare values for instantiation) object and nothing else. That's all. It's not logical that your class do all the work in the constructor.
EDIT:
Good practice:
Application app = new Application(context); // create application
app.run(); // run it
Bad practice:
new Application(context) // create & run application
[just my 2 cent]
To be honest, you might as well just use a function for what you describe.
It seems to me you are using your Class as a collection of functions/functionality.
This is OK, and it makes your code more structured, but you don't really use the power of OOP.
The real power of OOP isn't only the fact that you can bundle functions conceptually (which can also be done with appropriate include files that hold conceptual related functions), but the real power of OOP lies more in the fact that you can subclass useful existing Classes.
In my opinion, don't feel forced to go fully OOP if you feel uncomfortable with it. All tasks done with OOP can also be done with procedural approach.
And often, for more mundane tasks, procedural approach is faster to program, and is just as clear as object oriented.
This question is along the lines of "is it better to use an integer or a floating point". Well, it depends on the situation.
What WORKS and what is "standard" are not the same. If your method works, and for you is easy to debug and maintain, then it's a great solution to use.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I dont know much about classes, but have a reasonable knowledge of PHP/MySQL.
But why should I learn classes? I know they are important but what benefits can I see using them that I cant with?
Encapsulation, for one.
Steve Jobs once used a good analogy (it was in an interview). To paraphrase from memory, he said
If I want my clothes cleaned, and give
them to a friend, he will return them
cleaned. I do not care if he had to
get a cab, got a bite to eat or
whatever, I just want to give him my
clothes and have them returned clean.
Also, I found the interview. Interesting read.
Basically, he is saying that he doesn't care about the implementation details. That's what OO can do. Hide all the stuff inside a class through visibility and so forth. If you want a list of files from a folder, you could do
$files = new FilesInFolder('your/path');
$files->getByExtension('*.jpg');
You don't care if it uses glob() or readdir().
Update
As opposed to a file full of global functions such as functions.php: you can group all of the functions to specific tools. For example in the example above, you could have getFiles() and filterFilesByExtension() but these 2 related functions will be in the global scope, not to mention the second one will require you pass the files as an array back to it.
Actually, I've found that it is often simpler to use function-based programming in php than object oriented. There are a lot of ways in which just using function libraries and trying to keep your code simple and direct make your php scripts more maintainable, especially if you minimize state to increase reproducibility.
Objects & classes are one tool that you should get to know so that you can choose between the different options, but certainly not the only choice, now that php 5.3 has first class functions, moving more in the direction of true functional programming is another tool that you could get to know.
Php's background is very function-based, a huge portion of the native language provided is functions and sometimes the square peg of objects doesn't fit in php's round hole.
This certainly wouldn't apply to Java, but php's background is very rooted in functions.
Edit:
Let's be clear, to be effective at php you will have to have a good grasp of objects, because you are going to encounter it frequently, and if you work for other people in php, you'll probably have to write OO yourself on your employer's behalf. So get to know it well. But don't stop at OO and consider it the be-all-end-all solution. In fact, when it comes to dealing with other people's bad php code, I have found solid function-based programming to often be a simpler tool for refactoring and cleaning up bad code.
I would say there are a few ways to write php code:
Bad procedural code (little reusability, probably uses functions, but not well, probably uses objects, but not well).
Good function-based code (maximized reusability, minimized complexities of state, separation of concerns)
Bad object oriented code (large multifaceted objects, complex hierarchies, etc)
Good object oriented code (specific-task objects, clear separation of concerns like MVC)
And eventually, as php 5.3 matures, we'll be able to start throwing in a bit more functional programming into the "good function-based code" category and it will become an even more effective alternative. In the meantime, though, get comfortable with 2 and 4 because you'll need 'em both.
Classes are important when dealing with code reuse, they also provide well organized and cleaner code, in my opinion.
Depending on specific applications/projects you are working on, classes can make sense.
Update:
Also, it might be worth glancing at, and noting that Wikipedia has a section in Class (computer science) called Reasons for using classes which demonstrate a few key points for using classes.
Also, from your previous questions it seems you do a lot of work with PHP and MySQL. To demonstrate how beneficial classes are, you could create a Connection class that handles connecting to your MySQL database, so any changes made to the database you can edit in one single place, (your Connection class) rather than finding all the lines of code when it's called.
One of the main points of object oriented programming (objects and classes) is to make your programs more modular; when you work on one part, you don't have to work on the details of another part of the program. Depending on what kind of code you are writing, this may or may not be important.
A lot of people on a page like this will claim that a) OOP is the only good way to write programs and b) it is desperately needed for any program and/or home-page. I think if you think of what you are writing as a home-page, you probably do not need OOP, unless it's a very large home-page.
OOP is by far the most common programming paradigm, which makes it important to learn, if you want to be a programmer. However, most PHP is not written in an object oriented style and some of it is ok anyway (even though a lot of it is not).
If you think that the PHP that you are writing is hard to manage, learning OOP is probably a good idea, even if you only get the practice. You might even want to try it out in another language like, say, Java or Ruby. It is probably easier to find good books about OOP in those languages.
Classes and objects in PHP make one very important aspect of programming much much easier: abstraction.
Like many languages that have objects in addition to scalar types, objects in PHP simple take the aggregated item concept one step further. Things like arrays/lists let you work with a collection of data as one item. Objects make that just a little easier and also let you have code specific to that collection to manipulate that collection.
How about an example? I was involved in an educational intranet application some years ago. Its prime goal was to track academic progress over time and to do that it has to know about student enrolments, class membership and thus timetables. We needed a data point for a particular scheduled class in time. Initially, it was a list of data parameters passed into functions. Year, term, week, day, period. Then it needed to be returned, as well. Now it was an array. Then we needed specialised functions for manipulating it, mainly turning it into a real time and back again. So I made it an object.
Now, as an object, the conversion routines were thoroughly abstracted away. You could ask the object to convert itself and without the calling code caring or knowing, the object could cache expensive calculations. Code to handle tricky things like daylight savings was written and debugged once. The object just made it so much easier to handle the data.
Much of the PHP code was still function oriented. The startup logic on each page called a dozen functions to get everything going. But there were objects, too, for when the data needed it. And it made a lot of the code a lot simpler and more robust.
As always depends what you have to do, the Object Oriented way can become useful for many reasons:
If well designed increase the order inside your projects that means much more code re-usability, reduce the written code, less time spent in troubleshooting.
Collaboration if you have to work with many other peoples it's much more simple to maintain the code
Modularity it will give you a very good project organization
Encapsulation By implementing classes you can hide the code complexity inside the objects and keep "only" the logic part in the main code.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
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?
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.
As with every powerful tool, you have to use it properly.
As with every powerful tool, it takes time to learn how to use it properly.
As with every powerful tool you will make mistakes.
As with every powerful tool you will have to practice a lot.
As with every powerful tool you should read a lot about it, and read what other people think. Learn from others.
But, as with every powerful tool, there are people out there who misuse it. Learn to not learn bad practices from them. This is hard.
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.
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.
As long as your object has clearly defined inputs and outputs, the way that the object does what it does doesn't matter at all - storing/retrieving data could go from flat file to XML to memcache to MySQL to Oracle, and you only ever have to concern yourself with one single object.
As long as your object has clearly defined inputs and outputs, you can completely replace it with another object that has the same inputs/outputs. Decide at runtime whether you want MySQL, Postgres, memcached, or HTTP POST/GET requests to a sketchy server in Indonesia.
OO makes unit testing easier. If you can define what a specific object should do (i.e what results it should give you for a given input) then you can easily write code to test thousands of values against that code and check the results, and you'll know instantly if something breaks.
The more of your code you 'hide' in objects, the less of it you have to see when you're using that functionality. I wrote a polling application once in PHP that handled all aspects of polling - database interaction, poll generation, voting, ranking, sorting, and displaying - and I only needed one line of code on my website (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.
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.
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.
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.
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...
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.
If you tend to think of functions and the data they operate on as separate things, then you are a procedural programmer.
If you tend to think of functions and the data they operate on as being connected, then you are an object-oriented programmer.
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:
Encapsulation
Classes vs instances/objects
Inheritance and polymorphism
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:
Q: "Should I learn (OO, FP, concurrent, logic-based, event-driven, ...) programming?"
A: "Yes, learning a new paradigm is always useful, even if you don't use it directly every day."
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.
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'm a long-time procedural PHP programmer who occasionally dabbles in object oriented PHP. Joel's answer above is an excellent summary of the benefits. In my opinion, a subtle secondary benefit, is that it forces you to better define your requirements from the start. You have to understand the relationships between the objects and the methods that will be acting upon them.
A good book to help with the transition is Peter Lavin's "Object-Oriented PHP".
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.
http://www.onlamp.com/pub/a/php/2005/07/28/oo_php.html
I would say there are two primary benefits:
Encapsulation: code in libraries that shouldn't be called from outside the library can be hidden, preventing misuse, and easing changes to the internal structure of the library while preserving the external interface. In a good OO design, changes are introduced more easily once the code is complete.
Abstraction: instead of dealing with arrays of arrays you're dealing with employees, departments, and so on. This means you can focus on the business logic, and write fewer lines of code. Fewer lines means fewer bugs.
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.
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 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
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:
insert
update
select
delete
exists (check if a row exists)
search
list
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!