What is the best practices in naming methods in php? [duplicate] - php

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.

Related

Begin with OOP by using classes as a collection of methods? [closed]

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.
Is it wise to start with object-oriented PHP by using classes as a collection of methods? Are there any drawbacks with this approach?
I know OOP is much more than this, but my PHP-projects are too small to take advantage of all that OOP has to offer. On the other hand, my projects are becoming too big to update/maintain just with procedural programming.
I have read many topics about OOP and once in a while somebody says "OOP is more than just a collection of functions" (or something along these lines). It made me think: that may be true, but it also may be my chance to finally dive into the world of OO-programming by doing just that.
So, is this a smart first step to actually start using and learning OOP? Or are there serious drawbacks I need to know about?
Your question is real broad, however it deserves a simple answer you can memorize and keep with you while you continue your journey into the world of object oriented analysis and design (OOAD).
So, is this a smart first step to actually start using and learning OOP? Or are there serious drawbacks I need to know about?
As you can imagine, it is not possible that we answer this question directly. What is smart and what not depends a lot of our own abilities. E.g. for some persons it might be smart, because it helps them to stop errors early and this is the way to go. For others, it might be the complete desaster, because they don't spot any error, continue developing a software because they think: If I don't spot an error, this is totally right.
So how to resolve this dilemma? Easy, we have two parts in OOP you can easily learn about and keep with you. The first is called S.T.U.P.I.D. - you might imagine what it means if something falls into this category, and the second is called S.O.L.I.D. and it's likewise self-speaking how to treat the somethings in there.
So don't be STUPID, grasp SOLID.
Disclaimer: I haven't dealt with php in a while, so my syntax might be wrong.
The term OOP is a bit fuzzy imo, meaning that different people will think of slightly different things when they hear it, so don't be confused when you hear contradictory things about it.
Structuring similar functions together using classes won't hurt your code, but then you basically just use classes as namespaces for your functions. Usually, you will want to define classes in a way that encapsulates some aspect of your system, meaning that only the code of that class will ever have to deal with that aspect directly, and everyone else just uses that class.
For example, you could have a class that manages a print job queue. If you have some code that wants to print a document, it doesn't have to know how or where the jobs are queued or how they are sent to the printer, it only needs to know a print job queue object (let's call it $jobQueue), which might have a method like $jobQueue->enqueue($document).
Now you might argue: "That code could just as well use a global function enqueueJob($document)," and that is true until you want to have more than one queue (for different printers), and queues that work in different ways (store jobs in a database, in memory, or not at all - imagine a queue that goes right to the recycling bin :)). With OOP, this kind of scenario is no problem, and these details stay completely hidden from the code that wants to print a document - all it has to care about is that it has a job queue object with an enqueue method.
To get this kind of "interchangeability" of job queues they need to have a common interface (in this case, the enqueue method,) which has to be carefully chosen to cover all the needs of the code that wants to print things, but without making too many assumptions about how a print queue works. For example, you could imagine that the enqueue method takes a file path as argument which tells the queue where to store its files - but that interface would be useless for a queue that works on a database. This is the art of finding good abstractions.
Now to come back to your original question, just packing related functions together into a class is not really OOP in my opinion, as long as there is no thought about which abstractions / interfaces the new class is supposed to provide. Without that, all code that uses this new class will be hardwired to use it, and will need to be changed / reexamined if you ever decide that you DO need a different kind of printer queue. :)
However, "not OOP" is not the same as "not a good idea". I say go for it and rearrange your functions. In my opinion, it is important to keep in mind that not everything needs to be an object or fit some abstraction. But maybe you will find out that you do have some functions which do similar things (queue in file, queue in database) which could be abstracted to a common interface.
OOP is basicly just set of methods. But thinking in programming is different. In classes, you encapsulate similar funcionality. Code is more readable, you dont need to write same functionality over and over again. It is also more secure (private members), if you are writing library, end-user can change only what you want etc.
So I wouln´t recomment to try bypass OOP with set of functions and use real OOP instead. There is no reason why not.
I don't recommend, you will get used to write procedural code masked as OOP, which is not really what you want. Could be hard at first, but learn OOP with all it's features, read about patterns, emphasise on coding standards and, most important, study applications with object-oriented architecture.
Some things are functional, procedural and based on an object. Use the one that is the most appropriate for the circumstance. You will not got far wrong with that philosophy.
As this question isn't really related to php but to OOP in general, this answer should be valid for many languages.
There exists different pattern in OOP. I suggest reading about the "gang of four". It's a really nice book that explains some of the most basic pattern that can be used when doing OOP.
Instead of using a class to keep a sets of static function, you should consider storing all of your functions in a namespace.
Classes often define objects (like physical object). Any physical object has a sets of properties and behaviors.
When designing a class, you're trying to define those behaviors and properties. For example, a bag.
class Bag:
// Methods
function open: ...
function close: ...
function empty: ...
function add(item): ...
// Properties
array items: []
bool is_open: false
Some properties or method can be hidden or visible to the world. In my example, you could make the function add throw an exception whenever you try to empty or add an object to a closed bag. It's clear that all of the methods here are related to the actual object.
Adding methods or attribute that are unrelated to the bag should belong in a different namespace or class. It really depends on what you're trying to do.

Routine to keep names of methods, classes and functions organized?

I am working on a web application with a couple of colleagues for the moment. It have turned out that we all have our own way of naming the classes, methods or whatever functions that we currently are writing.
This is starting to get really annoying already so I know that we have a iceberg ahead if we continue like this.
Obviously the best way is to find one routine and stick to it - but how should that specific routine look? - What is common sense when naming pieces, objects, functions or whatever? Are there any standards out there?
Thanks a lot!
One standard you could adopt is the Zend Framework standards
You can take a look at the following: http://www.dagbladet.no/development/phpcodingstandard/
My work has implemented this, and while I don't always agree, at least it spawns consistency.
Take a look at the PEAR Coding Standards. It's pretty comprehensive and would make things easier if you ever use any pear packages.
It also might help to look up CRUD (Create Read Update Delete) on Wikipedia.
As for singulars vs plurals, I tend to try to stick with the conceptual style of my code. I find that with OOP, object names generally tend to be easier to wrap your mind around when you use singulars.
Even if your class is going to comprise information about multiple Dogs, instead of naming it Dogs, name it something else, like Pack, even if it's not technically a pack. It's easier to wrap your mind around multiple Packs than multiple Dogs's, and a "pack" is conceptually stronger than an amorphous group of "dogs". "Dogs" doesn't sound like a single object, whereas "pack" does.
I guess this is an obvious example, but if your class is only going to be used to define objects on an individual basis, don't make it plural. Or if your function is going to format only one string at a time, don't call it formatStrings().
Arrays are a little different. If you use an array for a list of all your dogs, you wouldn't name it $pack, because you'd expect that to contain information about a pack. Instead, you'd name it $dogs.
Use namespaces. Get together and come up with a logical namespace hierarchy policy, then use logical names within the namespaces for the elements.
Sit down with your colleagues, explain the problem you are watching develop, and then write down a standard that you all agree upon.
As you've identified, the only problem is consistency. Therefore, do not convince yourself that you also need a standard that is scientifically-proven to be optimal.

Is it acceptable to wrap PHP library functions solely to change the names?

I'm going to be starting a fairly large PHP application this summer, on which I'll be the sole developer (so I don't have any coding conventions to conform to aside from my own).
PHP 5.3 is a decent language IMO, despite the stupid namespace token. But one thing that has always bothered me about it is the standard library and its lack of a naming convention.
So I'm curious, would it be seriously bad practice to wrap some of the most common standard library functions in my own functions/classes to make the names a little better? I suppose it could also add or modify some functionality in some cases, although at the moment I don't have any examples (I figure I will find ways to make them OO or make them work a little differently while I am working).
If you saw a PHP developer do this, would you think "Man, this is one shoddy developer?"
Additionally, I don't know much (or anything) about if/how PHP is optimized, and I know that usually PHP performace doesn't matter. But would doing something like this have a noticeable impact on the performance of my application?
You might be the only developer now but will someone else ever pick up this code? If so you really should stick mainly to the standard library names if you're doing nothing more than simply wrapping the call.
I've worked with code where the author has wrapped calls like this and it really does harm the ability to quickly understand the code
If you saw a PHP developer do this, would you think "Man, this is one shoddy developer?"
Well no...but I'd think "Damn...I've got to learn this guys new naming standard which although well-intentioned will take me time"
I assume you are referring not only to naming conventions, but also to the merry mixture of function (needle, haystack) and function(haystack, needle) parameter orders.
I can totally understand the desire to build sane wrappers around these in self-defense. I still rather wouldn't do it, though, simply because it adds a proprietary layer to your project that will make it harder to understand for others. Everybody knows what array_push does, but MyArrayFunctions::push one may have to look up, or even look into to find out what it does.
I tend to stick with the standards, even though they're admittedly crappy in this case. Plus, with a decent IDE that can look up functions and parameters as you type, the problem is already much reduced.
On the other hand, I can't really see any harm in, say, a static class Array that brings all the push(), pop(), array_this() and array_that() into one standard form. I'd say it's up to you, really.
Simple wrappers wont hit your performance, but this might confuse any future developers on the project. As a PHP programmer you slowly come to expect the weird naming conventions.
If you are adding any functionality its great to have consistent conventions. I have worked with a PHP static class that did wrap the native array functions (and add new ones). It was quite convenient to always have the same argument placements.
In my opinion OOP implementations of for example an array are okay, you will wrap them and partially modify functionality, however just renaming functions and shuffling arguments I don't like.
If you really need to do it make sure you comment it with phpdoc so people can see the correct syntax in the autocomplete of their IDE.

How do i get out of the habit of procedural programming and into object oriented programming?

I'm hoping to get some tips to kinda help me break out of what i consider after all these years a bad habit of procedural programming. Every time i attempt to do a project in OOP i end up eventually reverting to procedural. I guess i'm not completely convinced with OOP (even though i think i've heard everything good about it!).
So i guess any good practical examples of common programming tasks that i often carry out such as user authentication/management, data parsing, CMS/Blogging/eComs are the kinda of things i do often, yet i haven't been able to get my head around how to do them in OOP and away from procedural, especially as the systems i build tend to work and work well.
One thing i can see as a downfall to my development, is that i do reuse my code often, and it often needs more rewrites and improvement, but i sometimes consider this as a natural evolution of my software development.
Yet i want to change! to my fellow programmers, help :) any tips on how i can break out of this nasty habbit?
What is the point in using object-oriented programming when you cannot find good reasons or motivation to do so?
You must be motivated by the need to conceive and manipulate ideas as objects. There are people who feel the need to be perceptive of concepts, flow or functions rather than objects and they are then motivated towards programming oriented towards concepts, ideas, or functional flow.
Some 13 years ago, I switched to c++ from c simply because there were ideas I needed but c would not easily perform. In short, my need motivated my programming oriented towards objects.
The object-oriented mind-set
First, you have bytes, chars, integers and floats.
Then your programme starts being cluttered with all kinds of variables, local and static.
Then you decide to group them into structs because you figured that all the variables which are commonly passed around.
Conglomeration of data
So like printer's info should have all its variables enclosed into the Printer struct:
{id, name, location,
impactType(laser|inkjet|ribbon),
manufacturer, networkAddr},
etc.
So that now, when you call function after function over printer info, you don't have functions with a long list of arguments or a large collection of static variables with huge possibilities of cross-talk.
Incorporation of information
But data conglomeration is not good enough. I still have to depend on a bunch of functions to process the data. Therefore, I had a smart idea or incorporating function pointers into the Printer struct.
{id, name, location,
impactType(laser|inkjet|ribbon),
manufacturer, networkAddr,
*print(struct printer),
*clean(struct printer)
}
Data graduates into information when data contains the processes on how to treat/perceive the data.
Quantization of information
Now laser, ribbon and inkjet printers do not all have the same set of information but they all have a most common set of denominators (LCD) in information:
Info common to any printer: id, name, location, etc
Info found only in ribbon printers: usedCycles, ribbon(fabric|cellophane), colourBands, etc
Info found only in inkjet: ink cartridges, etc
Info found only in lasers: ...
For me and many object-oriented cohorts, we prefer to quantize all the common info into one common information encapsulation, rather than define a separate struct/encapsulation for each printer type.
Then, we prefer to use a framework which would manage all the function referencing for each type of printer because not all printers print or are cleaned the same way.
So your preference/motivation oriented away from objects is telling you that your programming life is easier if you do not use objects? That you prefer to manage all those structural complexities yourself. You must not have written enough software to feel that way.
The necessity of laziness
Some people say - necessity is the mother of creativity. (as well as, Love of money is the root of evil).
But to me and my cohorts - laziness in the face of necessity are the parents of creativity. (as well as the lack of money is the other parent of evil).
Therefore, I urge you to adopt a lazy attitude towards programming so that the principle of the shortest path would kick into your life and you'll find but have no other choice than to graduate towards orienting yourself towards programming with objects.
Step 1. Read a good Design Patterns book. http://www.oodesign.com/
Step 2. Pick something you already know and rework it from an OO perspective. This is the Code Dojo approach. Take a problem that you already understand, and define the object classes.
I did this -- and wrote down what I did.
See http://homepage.mac.com/s_lott/books/oodesign.html#book-oodesign
You can do the same series of exercises to get the hang of OO design and code.
The OO mindset is based on principles that lie at a much more basic level than design patterns. Design patterns are somehow fashionable these days (and have been for a while), and they are useful, but they are just one more layer that you can put upon more basic stuff that you absolutely must learn and master if you want to do OO properly. In other words: you can do OO perfectly without design patterns. In fact, many of us did OO well before the phrase "design patterns" was even coined.
Now, there is stuff you can't do without. I suggest you start at the basics. Read and understand "Object-Oriented Software Construction" 2nd edition by Bertrand Meyer. It's probably the best book on OO programming around, both in width and depth. That is if you're interested in programming.
First, congrats on taking steps to learn something new! I hate it when developers decide to NOT evolve with technology.
As far as moving from procedural programming to OOP, I would say that one thing that you can do is take an existing app (as others have mentioned) and, before you even open a text editor, sit down and think about how each aspect of the application would be converted. I have found that more than half of OO programming is defining the conceptual objects in your mind first.
Again, I will agree with everyone's recommendations on design patterns. Specifically, I would look into the MVC (Model-View-Controller) pattern as this one might be the easiest one to grasp. You have already written code, so you should be able to look at your existing applications and begin putting each part into the M,V or C categories.
Best of luck and have fun!
There are already quite a few answers about where to find information on programming in an object-oriented fashion. Indeed, there are many great books out there that will define the basic concepts however I think the question was more on how to "stick with it" through development for someone new to the method.
Of the many concepts in object-oriented programming, the main one that will keep you on track as a newcomer is encapsulation. Does my class know how to take care of itself? Does my class have behaviour? If it doesn't, then you don't have a class, you have a structure and you'll likely be writing a lot of procedures to change its state (as it's said, "you are back to writing C in Java"). Does my class only expose methods publicly that are required for its use? Those questions may not be terribly elaborated upon but perhaps consider this thought experiment when designing your classes: What if each one of your application's classes were to be developed and maintained by a different developer on the internet and the classes also had to interact with eachother over the internet. Would each developer agree that the class they are writing and maintaining adheres to the single responsibility principle and therefore be happy that they aren't maintaining what should be someone elses code?
Regarding the design of class interfaces, consider writing all of the code that uses your classes first. Don't worry about what has to happen at the metal yet. You should be able to stub out the entire program in terms of the class relationships before you write your first bit-twiddling implementation detail. If you can't do this without twiddling bits or making a variable public, then it is time to go back to your class relationship diagram and see if you are missing an abstraction. Phrased another way, use your code before you write your code. Do this first, and you might be suprised how clean your code and interfaces turn out if you've never done it before.
While design patterns are certainly good to learn, and some are extremely powerful, they aren't generally intrinsically object-oriented and as some argue (and I tend to agree) design patterns are often just exposed weaknesses in the language. One language's design patterns is another's basic founding principles. So when starting, don't get hung up on whether or not some relationship is a good candidate for a bridge or a facade; this is not specific to object-oriented thought, this is related to what a specific language's constructs afford.
Don't.
First, learn writing. Second, learn user experience and interaction design. Third, learn business analysis. Fourth, learn role modeling.
Now that you know what objects are, you will come to see that objects are not found in code. They are found at runtime; in the space between the machine and the user's mind. This is what object orientation really means. Unfortunately recent academia has twisted it into an engineering concept. Nothing could be further off the mark. And try as they might to emulate, the end result is crap. Why? Because the "OOP" paradigm as the industry knows it today is built on a fundamentally flawed idea: decompositional analysis of identity. How is this flawed? Because identity in and of itself is meaningless. It is void. In a mathematical sense, in a philosophical sense. This is not how a human being perceives and interacts with the world.
Canon: Alan Kay, Trygve Reenskaug, James (Jim) Coplien
How I wish I was in your position. :)
I think it helps to first skim over some existing, decent, proven object-oriented code (e.g. Qt source code) so you can get a feel for "how it's done". After that, learning from a book or creating your own framework will be much more effective.
In general, it really helps to see things in context before reading about and practicing them, as it gives you moments to say to yourself, "Oh, that's why they did that!" At least that's how it works for me.
The hard part of OO is which stuff should be put together into one object. As you already mentioned the evolution of your source code, here you have a simple guideline on how to evolve your source code towards an OO design:
"Put stuff together that changes together."
When two pieces of code have similar change velocities, that's a hint that they should be placed in the same object. When the change velocities are different, consider placing them in different objects.
This is also known as "Change Velocity".
If you follow that guideline your code will naturally evolve towards a good OO design. Why?
Fragments of code often have similar
change velocities if they access a
common representation. Every time the
representation changes, all the pieces
of code that use it must change at
once. This is part of the reason we
use objects as modules to encapsulate
representation. Separating interface
from implementation makes sense under
this guideline too - the
implementation changing more often and
thus having a higher change velocity.
If a class has a stable part and an
unstable part, that's a difference in
change velocity that suggests moving
the stable part to a (possibly
abstract) base class.
Similarly, if a class has two parts
which change equally often but at
different times or in different
directions (that is to say, for
different reasons), then that again
suggests refactoring the class.
Sometimes replace "class" with
"method". For example, if one line of
a method is likely to change more
often than the rest - perhaps it is
the line which creates a new object
instance and contains the name of its
class - consider moving it to its own
routine. Then subclasses can easily
effect their change by overriding it.
I came across this concept on C2 wiki many years ago, but I've rarely seen it used since. I find it very useful. It expresses some crucial underlying motivation of object oriented design. Of course, it's therefore blindingly obvious.
These are changes of the program.
There is another sense of change
velocity - you don't want instance
variables changing at different rate,
or rather that is a sign of potential
problems. For example, in a graphics
editor you shouldn't keep the figures
and the handles in the same
collection, because the figures change
once a minute or once an hour and the
handles change once a second or once a
minute.
In a somewhat larger view, you want a
system to be able to change fast
enough to keep up with the changes in
the business.
PS: the other principle that you should follow is "Law of Demeter", that is, an object should only talk to its friends. Friends are: yourself, instance variables, parameters, locals, and members of friendly collections - but not globals and static variables.
You might consider using the CRC (Class/Responsibility/Collaboration) card approach to OO design. This is nothing too scary - just a way to sort out what your objects should be, and which object should be responsible for which tasks by writing stuff down on a bunch of file cards to help clarify your thoughts.
It was originally designed as a teaching tool for OO thought, and might work for you. The original paper is at: http://c2.com/doc/oopsla89/paper.html
A poster above suggested programming in Smalltalk to force you into OO habits, and to an extent that's a good suggestion - Smalltalk certainly did me a lot of good, but
a) you may not have the spare time to learn a new language. If you do, great.
b) I used to tutor a university course in OO programming, using Smalltalk, and the students did an excellent job of proving that old joke about how "You can write FORTRAN in any language".
Finally: when I was learning about OO (from books) I got the impression that you subclassed a lot, creating complicated class hierarchies. When I started working with OO programmers I realised it didn't happen as often as I thought. I think everyone makes this mistake when they're learning.
The only way to write better code is to write more code. Take a project you've implemented procedurally and convert it to OOP (assuming you're working in a language that supports both). You'll probably end up with a fragile, tightly coupled solution the first time around, but that's ok. Take the bad OOP implementation and start refactoring it into something better. Eventually, you'll figure out what works, and what doesn't.
When you're ready to take the next step, pick up a Design Patterns book and learn some of the OOP design terminology. This isn't strictly necessary, but it will give you a better grasp of some of the common problems and solutions.
I think you should convince yourself by researching all of the downsides with procedural programming, for example (some buzzwords following, watch out): scope, state ... practically you'd be able to extract many terms just by reading examples of design patterns (read: common examples of using objects together.)
Stressing yourself into learning something you don't believe in won't get you anywhere. Start being really critical on your earlier work and refactor it to avoid copied code and using the global scope, and you'll find yourself wanting more.
For me the ah-ha moment of OOP was the first time I looked at code and realised I could refactor common stuff into a base class. You clearly know your way around code and re-use, but you need to think around classes not procedures. With user authentication it's clear you're going to have a username and password, now they go into the base class, but what if you need a tokenId as well, re-use your existing login base class, and create a new subclass from that with the new behaviour, all your existing code works without change.
See how that works for you.
Well, first off design patterns are about the worst thing to pattern your programming to.
It's just a big set of things. It's nothing to do with OOP, and most of them such as singleton are constantly used for all the wrong reasons (ie initialization). Some of these things you have to use so telling you about them is pointless, others are counterproductive, and the rest are just special case things. If you try to learn anything this way everything will start to look like some bizarre doodad someone came up with for a very special problem or because they needed infinite genericity (which is seldom true). Don't let people con you into using a million iterators and templates for no reason and make things ten times more complicated.
Really OOP is a simple subject that gets massively overcomplicated. Unfortunately in C++ it has a lot of issues but really simple virtual methods are what matters. Pure virtual base classes used much like a java interface object are the most useful but also just plain virtual methods here and there will come in handy.
It's mostly been overblown. It also doesn't lend itself well to every problem. If you make database and gui stuff it lends itself well to that. If you make system tools it is usually not as helpful.
I found that one of the things which has really helped solidify the benefits of OOP for me has been writing unit tests with a mock object framework (such as EasyMock). Once you start to develop that way, you can see how classes help you isolate modules behind interfaces and also allow for easier testing.
One thing to keep in mind is that when people are first learning OOP, often there is an overemphasis on inheritance. Inheritance has its place, but it's a tool that can easily be overused. Composition or simple interface implementation are often better ways of doing things. Don't go so far in attempting to reuse code via inheritance that you make inheritance trees which make little sense from a polymorphism standpoint. The substitution principle is what makes inheritance/interface implementation powerful, not the fact that you can reuse code by subclassing.
A great step would be to start of with a OOP framework, you can still write procedural code in the framework but over time you can refine your coding habits & start converting functionality into objects.
Also reading about patterns & data modeling will give you more ideas about to code your logic in a OOP style.
I have found that a very intense way learning to train abstraction in programming is to build a OOP library with a defined functionality, and then to implement two projects with similar but still different requirements that are building on that library, at the same time.
This is very time-consuming and you need to have learned the basics of OOP first (S.Lott has some great links in the other answer). Constant refactoring and lots of "Doh!" moments are the rule; but I found this a great way to learn modular programming because everything I did was immediately noticeable in the implementation of one of the projects.
Simply practice. If you've read everything about OOP and you know something about OOP and you know the OOP principals implemented in your language PHP... then just practice, practice and practice some more.
Now, don't go viewing OOP as the hammer and everything else as the nail, but do try to incorporate at least one class in a project. Then see if you can reuse it in another project etc..
Learn a new language, one that helps to move you gently to OOP. Java is nice, but a bit bloated, though. But its system library is mainly OO, so you are force to use objects.
Moving to another language also helps you not to reuse your old code :-)
I think it´s important to learn the theory first. So reading a book would be a good start.
I believe that the mechanics of OOP seem completely arbitrary and make no sense until you read a book on design patterns and understand the "why" of it. I recommend Head First Design Patterns. I thought OOP was ridiculous and completely useless until I picked up this book and saw what it was actually good for.
OO makes a lot more sense when you understand function pointers and how it relates to indirect function calls and late binding. Play around with function pointers in C, C++, or D for a little while and get a feel for what they're for and how they work. The polymorphism/virtual function part of OO is just another layer of abstraction on top of this.
Procedural is the right tool for some jobs. Don't act like it's wrong. IMHO all three major paradigms (procedural, OO, functional) are valuable even at a fine-grained level, within a single module. I tend to prefer:
Procedural is good when my problem is simple (or I've already factored it enough with functional and OO that I now have a subproblem that I consider simple) and I want the most straightforward solution without a lot of abstraction getting in the way.
Object-oriented is good when my problem is more complex and has lots of state that makes sense in the context of the problem domain. In these cases the existence of state is not an implementation detail, but the exact representation is one that I prefer to abstract away.
Functional is good when my problem is complex but has no state that makes sense at the level of the problem domain. From the perspective of the problem domain, the existence of state is an implementation detail.

OutletORM and phpDataMapper

I've been playing around with two nice php based ORMs. OutletORM and phpDataMapper.
Does anyone have experience with them? Any advantages of one over the other. It's also a good question to ask which one has a bigger user-base.
The are both implementations of the Data Mapper pattern.
Whereas phpDataMapper is a more loyal approach to the pattern, I've found it to be a bit too idealistic and strict at times.
OutletORM, on the other hand, is a lot more pragmatic and flexible (doesn't require you to extend any base classes for instance). It is also a more mature project.
Doctrine is a great project but is huge and bloated for most simple uses.
I'd go with Outlet!
I'm working with phpDataMapper right now. Two issues I have run into so far are:
The "documentation", which is nothing but a bunch of examples that only covers part of the functionality. No reference...! You have to go through source files and experiment if you want to use anything that is not in there (like delete()!)
No "binary" (blob/mediumblob/binary/etc...) type. I had to add it myself!
Other things I have noticed:
Their "entity" model is kinda useless, I mean I am just adding functions to the mapping class itself... what was that for?
There is a "pagination" php file which looks interesting, but of course no documentation anywhere to be seen.
the source is surprisingly small and neat, which is really good since (sorry for repeating myself) there is no doc!
All in all a rather nice experience, but not exactly a magic time saving piece of code... if you want to use it be ready to do some code reading and modification on their source.

Categories