Two months ago I got a job with a firm who’s in house project is, well, there’s a LOT of bindings. It’s so bad that to add a field to one form took 12 file edits, most of which are globally used and may take a couple weeks to test.
I’m getting to be of the mind that binding points are a programmer’s worst enemy. They are a necessary evil, but keeping them minimal and when they do appear intuitive is critical.
The use of global variables inside a function makes the function harder to use and debug because you can never be sure what piece of code last amended the global variable.
Methods of a class do not need many (or often any) arguments. Values are assigned to the class, then operations on those vars are performed using the methods of the class. Those methods do not need any arguments and shouldn’t have many (if any).
While you have effectively hit the head on the nail with regards to encapsulation, I for one, prefer to pass arguments directly to the function, thus limiting it’s scope even more.
Using object properties instead of arguments, is almost as bad as using globals, IMO. Instead of the entire application, the entire class can manipulate the variables. Not as bad as globals, but a change in a member variable (can and usually will) result in side effects in more than a single method.
I try and follow a functional programming ethos, even while building an OO application. Encapsulation is unavoidable at times, but many times by passing in the variable as an argument to a method, instead of setting a object member variable, results in more loosely coupled code and less side effects which are difficult to unwind, discover and debug.
Just like I like I decided to read to this post. Is it a rant or is their a point? - diverting to assertion code has little to no correlation to original post. ridiculing others for not understanding what you didn’t say either.
Trying to be object. Bindings, ok so 12 functions need an extra parameter for a new form field, not a big deal, just a PITA - so is working with PHP 4 code in general. If you can foresee that, why not turn that param into an array? Objects are fine too.
To me, trying to think…, the question is the purpose of those 12 methods. Each of them might be processing the that value into different ways. So it could also be the nature of that value rather?
I think anything more than 4 arguments begins to complicate matters. With that said, its not always possible to avoid such situations without creating even more complexity or convoluted code. I tend to shoot for a balance between simplicity, reuse and best practice. If 8 arguments will result in a more simple and reusable solution than so be it.
As programmers I think we are quick to judge other peoples code and design. However, in many cases regardless of whether of not you agree with decisions there is normally a pretty good reason as to way something was approached. I’m dealing with the same thing myself having switched to a new job recently. Some things I agree with and some things I don’t, that is just the way it is. I’m sure its the same for everyone, even those looking at your past code. Two months in-itself is very little time to fully embrace all the problems, situations, features and requests that have went into development before you were there. I generally find that with each new job, I disagree with a lot of decisions. However as time passes you begin to see why things were done the way they were and come to accept a majority as good decisions based on restraints and requirements past developers had to work within. You always have to remember that everything can be better and to chose you battles carefully.
That’s fine for one or two arguments. Beyond that it leads to a mess.
Three or more arguments lead to a mess? I have some methods which are a dozen or more. While I agree they can be unwieldy, there are techniques you can employ to circumvent all of the disadvantages.
Using a associative arrays in one such primitive technique.
You eliminate the importance of parameter order
You make adding/removing parameters easy
Yes it can convolute your interface but if you find this happening you look into a robust solution, using reflection or similar.
That statement leads me to believe you don’t understand OOP at all. The ability to have methods act upon members is pretty much the point of OOP in the first place.
Let it lead you to wherever it must I guess.
And it follows that the whole thing is too difficult to maintain. Well here’s a newsflash for you - perhaps you are asking too much of your classes.
Functions should do one thing only. Classes should only do a handful of tightly related things.
Thanks for the newsflash.
I ask very little of my classes, in fact, most are rarely above and beyond 50-60 lines. My models are about the only classes which break this rule of thumb, simply because, that is the nature of the beast.
I adhere to SRP with extreme zealous fervor.
Just curious but can you provide examples of aforementioned classes you speak of, that do not require more than 2-3 arguments? I agree there are cases where using properties/members make sense, but I am none-the-less curious.
Any point in the code where a value is passed from one variable to another.
Example: The arguments of a function are it’s binding point to it’s calling code - for this reason a function should have as few arguments as possible because the more there are the harder the code becomes to debug.
It goes back to the idea of DRY coding - Don’t Repeat Yourself. The more repeats, the more chance for error.
That is kind of intriguing, how the heck is that application operating if a simple thing like that require you to edit that many files. Dont even want to think what you need to do if any more serious changes are required…
Its horror stories like that one, which makes me glad I am able to decide what projects that I want to work on.
I think there was a point, but it got obscured in a rant.
What I gather the OP is saying is that these 12 functions have to be manually edited when adding or deleting a form field, and he would rather you define the field and the functions just automatically take care of what needs to happen.
Well, okay, so then refactor the code. Done. Problem solved.
The code more than likely started out as it is because at the time it was written, it was the path of least resistance for the programmer writing the code. It’s no doubt grown since then, and now adding a new field is just repetitive and tedious. It smells a bit. Time to do the dance and refactor.
I don’t really get the point in *****ing about legacy code. Nobody gets code perfect the first time. Or 2nd. Or 3rd. Truly elegant code comes from a continual and ongoing process of refactoring. If a piece of code is bothering you that much, do your duty as a programmer and improve it.
Be that as it may, it’s hard to respect someone as a coder when they write a 400 line class to replicate the assert() function because they couldn’t be bothered to read the PHP manual. Some people just make bad decisions, and the code base I’m dealing with has some truly awful ones.
That’s fine for one or two arguments. Beyond that it leads to a mess.
Using object properties instead of arguments, is almost as bad as using globals, IMO.
That statement leads me to believe you don’t understand OOP at all. The ability to have methods act upon members is pretty much the point of OOP in the first place.
Instead of the entire application, the entire class can manipulate the variables. Not as bad as globals, but a change in a member variable (can and usually will) result in side effects in more than a single method.
And it follows that the whole thing is too difficult to maintain. Well here’s a newsflash for you - perhaps you are asking too much of your classes.
Functions should do one thing only. Classes should only do a handful of tightly related things.
Encapsulation is unavoidable at times, but many times by passing in the variable as an argument to a method, instead of setting a object member variable, results in more loosely coupled code and less side effects which are difficult to unwind, discover and debug.
If you are having trouble debugging a class then more likely than not the class is just too busy and can be broken up into a group of classes.
Who said anything about using global variables? I didn’t. And modifying global variables is just plain bad practice - I don’t know where you are getting that from my statement.
Don’t send 3 dozen variable arguments to a function. If a function needs to work with that many variables chances are other functions do as well. <sarcasm>Wouldn’t it be nice if PHP provided a way to bind these functions together with their shared variables?? </sarcasm> That is what it means to encapsulate in the first place. Methods of a class do not need many (or often any) arguments. Values are assigned to the class, then operations on those vars are performed using the methods of the class. Those methods do not need any arguments and shouldn’t have many (if any).
The main reason for that is the order of function arguments is important. Past the 3 argument mark it gets hard to remember what the order should be without a code hinting. And things get uglier when the arguments have defaults and don’t always need to be supplied.
In a class you can assign the values to the class then call the relevant method. You don’t have to assign the variables in any particular order. You don’t have to define the defaults in every function working with the value - the class itself can store the defaults or the constructor can read them in from a config file. (though __construct methods should never do anything beyond set defaults ).
You bring up some interesting points Alex. I tend to use object properties when manipulating data that have been stored with a method such as $obj->storeData($array) but use method arguments when getting data.
No point writing $obj->setId(1) then $obj->get() when you can just write $obj->get(1).
And if you are manipulating a objects properties (member vars) wouldn’t you want other methods to have the changed properties any way? In a general sense. That said you sometimes need the old value. Suppose it makes sense to return the new value than the old.
<sarcasm>What’s wrong with 12 or 24 arguments?, real coders remember their methods argument order as well as their defaults.</sarcasm>