Subscribe to Martyr2's Programming Underground        RSS Feed
***** 1 Votes

Top 10 Tips for PHP Programmers

Icon 7 Comments
I thought that it was time for me to give a few helpful tips to those PHP wizards out there on how to write better scripts. I wanted to provide some tips that are a bit different than what you may have read on other blogs or seen in other articles on the subject. While some of these tips are universal (and thus you may have seen already), I am hoping that a few of these give you a different perspective on the ideas of what makes good PHP programming. In addition, I try to mix in a bit of my own philosophy into these. As someone who has come into a lot of projects and cleaned them up, over the last 16+ years, I think I have had a pretty good amount of experience in what makes good PHP work. Don't use these as hard fast rules, but just guidelines to make your code a tad bit cleaner. By doing this you can help me, and other developers, out in the event we end up looking at your code one day.

Top 10 PHP Programming Tips

  • Use classes and functions to the best of your ability to manage complexity - We all know that you can write a script in PHP that doesn't have a single custom function or class anywhere to be found. Sometimes that is fine especially if the script is on the order of 50 - 200 lines (even though line count shouldn't be a determining factor of whether or not one should create functions or classes). I have written many utility scripts that are straight PHP procedural code. However, once the script starts growing in length and complexity, leveraging functions and classes can keep things simple. This principle is not just for PHP, but programming in general. PHP is definitely a language where complexity can grow rampant quickly! So always think about when it is a good time to use functions. You will quickly discover that once you create a nice reusable function in PHP, it will serve you well in a ton of other scripts. That idea alone should encourage you to go to functions as soon as you can!

  • Watch your return values like a hawk - One of the most common complaints about PHP is that it lacks consistency in the language itself. Some functions return null on error, some return false, some return -1 or some may throw an exception. You may start adopting this pattern of inconsistency in your functions and you should try to stick to a consistent method across all your functions. Don't write a function that in one instance returns false on error and another where it returns an empty string; especially if both functions are designed to return a string. Look at what the function is designed to return and pick the best return value that fits. It should also fit with what other functions are expecting it to return.

  • Try to steer clear of nulls where you can - As a tie-in to tip number 2, try to avoid returning null everywhere. By reducing the amount of nulls being passed around you reduce errors related to calling methods on null objects or having to design complex null tests. The only time I really think about returning a null from a function is when the function is expected to return an object. In this case I can plan that there may be a null coming back from that function. Perhaps it doesn't make sense to return an empty string from a function that you are expecting returns an object. All I can really advise is try to keep the number of nulls down and try to opt for empty strings, false, or error codes / exceptions rather than returning null. But I found that nulls in PHP are just a part of life. Just make sure you also don't create some crazy mechanism JUST to avoid using a null. Nulls are ok when used sparingly... like butter in your diet. ;)

  • Keep it as simple as you can - This tip goes for all programming languages. Yeah we like to be clever, but simple is always better. Nice simple code with great variable names, function and class names and simple tests go a long way in readability and reducing complexity. If you can read a function like you can read a book, all the better. Believe me, your future self will be grateful if you make things as simple as can be. Once everything is rock solid, then perhaps you can go back and optimize "a little". Even then simple straight forward code is going to help you do that.

  • Leverage comments - Ok, lets put a stake in this right now, comments are a good thing when used in moderation. You SHOULD have comments. There is a movement out there that is saying that your code should be self documenting. That is true, it should be, but doesn't mean that you can leave out comments. Your code should show the "how" and the comments should show the "why". You can document through code that a variable should be the result of calculating interest against a loan over N terms. Your comments should show why you need to do this. Is it to fix a bug? Is it in response to a business requirement? Is it to compensate for a bad system that you can't fix? As long as you keep the comments straight and to the point, and that you are not commenting every line, comments are good. I strive to keep a single line of commenting equal to 5 - 10 lines of code. But there is no hard fast rule about this. If you find yourself commenting a lot then it usually means you are violating tip number 4 and your code is not being as simple as it can be.

  • Put the PHP manual website on your bookmark bar - Due to the problem I mentioned in tip 2, where PHP itself lacks a bit of consistency in the language itself, you almost always have to reference the <a href="http://php.net/manual/en/index.php" rel="noopener" target="_blank">online manual</a> to see which order parameters go into functions, what functions return or what versions of PHP a particular function can be used in. The manual itself is very good in breaking down parameters, return values and showing some simple examples of their use. Be sure to always look at any warning boxes on the page! More often than not you will find a function that looks like it will work for your situation only to find out that it won't work due to some problem outlined in a warning or error box. One last thing I will mention is the user comments. They are great but PHP.net has a habit of keeping comments up for years and often times examples may refer to PHP from 8 years ago and just doesn't apply anymore. Always take comments with a grain of salt and verify if they still work.

  • Use PHP 7 whenever you can - PHP 7 has been a fantastic change of pace for PHP. It has an increased speed which is noticeable (and keeps getting faster), it has removed a lot of old legacy code that has bad practice in it, it introduces newer concepts which have served other languages for years and can even cut down your development time greatly. I know it is hard to find hosts out there that have moved over to PHP 7 still, but there are more and more popping up all the time. PHP 7 will just make PHP that much more enjoyable to work with.

  • Readability is paramount, so use good variable names and simplify test conditions! - To go with tips 4 and 5 I recommend always making use of good variable names and simple test conditions to keep your code readable and maintainable. Good names and simple tests help you simplify and reduce complexity by an order of magnitude. Plus they become self documenting and increase readability. Again you should have code that almost reads like a book and paired with good comments, you have code that is solid and easy to understand for when it needs a change. This rule applies not just to PHP but to other languages as well. Readability is one of the fundamental pillars of programming!

  • Read others code - It is said that you can only get better when you are surrounded by others who are better than you. You need people who bring new ideas, new ways of doing things, new perspectives on old problems. If you read their code and see what they did, you can learn from them. In turn others will then learn from you. It is a never ending chain of learning that will help everyone. The more code you read the more you learn and the better you become. It is just that simple. I am nearly 20 years in as a developer and I still read other's code often.

  • Use frameworks only when they make sense - Lastly a small tip on frameworks like Laravel or CakePHP. Use frameworks only when they make sense. There is no need to add a whole system if your script is only going to be a few hundred lines max. Frameworks are awesome and have their place like everything else, but they often add complexity to simple projects. They can bloat your tasks and really be a pain to debug for simple projects. However, if your project is going to grow into something much bigger, frameworks can simplify the process and work to your advantage. It is up to you to evaluate frameworks, look at what they solve and if your project is the right size and fit for them. Always have a good reason to use a framework and that reason shouldn't be "because it is what everyone else is using".


Conclusion

In this article we covered 10 great tips for PHP programmers and I hope that you found them useful and enlightening. If you start with these and grow from there you will find that your PHP programming with become that of legend. These tips will also save you time and in some cases money if you use them for client work. But by no means is this all of the tips out there and you should definitely find what others have to say about the topic. Take what works for you. However, I encourage you adopt many of the tips above and use them in your work. People like me, and other maintenance programmers that follow you (maybe your future self), will certainly appreciate it. Also, if you have some great tips that have helped you out over time, be sure to share them in the comments below. I am sure others in the community would love to read them.

I wanted to thank you for reading! If you are interested in applying these tips on your next web project and looking for that project, consider "The Programmers Idea Book" offered here on the Coders Lexicon. It consists of 200 programming project ideas, many which can be done using PHP and have a ton of different levels of difficulty. If you are interested in learning more development tips, also check out our ebook on diagnosing the problem. In that book we show how to break down problems and debug them with useful tips and tricks to become a rockstar developer. :)

7 Comments On This Entry

Page 1 of 1

jon.kiparsky 

14 March 2018 - 06:31 PM
Regarding comments, my standard is, if you need to use a comment, you should use a comment. On the other hand, a comment is an indication that the code you've written is not sufficiently clear, and should be reworked so that the comment is not necessary. This goes, in my opinion, for any language.
One common cause of comments is functions that are too long. A few years ago, the received wisdom was that a function should be small enough to fit on your screen without scrolling. Current consensus says that functions should be no more than ten lines in length, the logic being that ten lines is enough space to express one and only one action. Often, comments indicate a place where you need to name the functionality directly, by writing a function. In this case, the comment itself names the function, so it's an easy change to make.
If you find that you're explaining the logic of a function with a comment, to me that indicates that you need more functions. Needless to say, you will seldom be tempted to explain the logic of a ten-line function, though you might be tempted to change the name to improve clarity.
0

Martyr2 

15 March 2018 - 11:53 AM

Quote

a comment is an indication that the code you've written is not sufficiently clear


I whole heartily disagree. Again comments should be to service the "why" something is done. As in, business rules or reasons for the function. Comments can also serve to express additional information on usage, parameter values etc. You can write fully readable functions but still not know why something is being done. You can write a function which adds two numbers together. One line very simple. You can see it adds two numbers together. A comment might be used to explain that you need to add two numbers together to help add tax to an subtotal or whatever.

Codebases of comments, no matter how well written they are, is a system that doesn't explain itself. Comments should follow some simple rules...

1) Be clear and to the point as to "why" the function exists.
2) They should be written with good grammar and please try your best on spelling
3) They should NOT restate what is written code. Yeah you add two numbers together, you don't need a comment saying "Add two numbers together".
4) If you are using comments to explain something that might be cryptic, well, that is a break down in your code. Don't make it cryptic.

Believe me, I have had many years as a dev brought in to fix systems and comments help! Especially if you are not going to have product documentation either (which you should have and a whole other article).

But again I disagree strongly that code can speak entirely for comments. This very idea is why I am trying to fight in the industry. There are reasons why in just about every good programming structure design book there is a chapter on commenting. Use them! :)
1

Martyr2 

15 March 2018 - 11:54 AM
Correction: Codebases "void" of comments...
0

jon.kiparsky 

15 March 2018 - 12:38 PM
Okay. As long as you (and your readers) understand that you're going very much against the grain of current best-practice. Reader beware: the current best-practice is important because the places you want to work tend to follow it. To be quite blunt about this, if your code is littered with comments you're going to have a hard time getting it through review in many shops these days.

Of course, there are some exceptions where I think comments are quite helpful, but not the ones discussed here. For example, sometimes code is deliberately written in an obscure fashion because of a demonstrated performance issue with more literate code. Code like this should be heavily commented. In most high-level languages, this is not a thing you're going to see, but it can happen. The comment in this case should explain in some detail why the code should not be changed to be more readable, and indicate some ways to demonstrate the cases where the performance degradation would be expected. In addition, I would want the obscure code to be isolated from the rest of the code as much as possible - at a minimum, it should be in its own function.

Also, sometimes there's a subtle reason why code should not be "improved" in certain obvious (but wrong) ways. In this case, a comment can save the next developer from rediscovering a painful gotcha, and that comment is a good thing. Obviously, if you can express the correct behavior in a way that does not need a comment, that's much better. Also, if you write this comment without writing tests to catch the painful gotcha, you're a Bad Person and should be ashamed of yourself.

Finally, in some high-level languages there are mechanisms for including API documentation in a class or function definition, and these mechanisms often make use of comments. This is a Good Thing and should be used if you're writing code that you expect third-party developers to use.

These are pretty specific exceptions, though. In general, I agree with folks like Uncle Bob: comments typically indicate unclear code, and when you find unclear code you should try to make it more clear.
0

Martyr2 

15 March 2018 - 03:09 PM

Quote

Okay. As long as you (and your readers) understand that you're going very much against the grain of current best-practice.


Ok I am sorry but that is such a load of crock! I have been coding for nearly 20 years and been on dozens of projects and commenting is always part of the deal. I recommend my readers go to github and go to any of the top companies (facebook, google etc) and look at their project source code you will see comments. Are they every line? No. Comments should be used sparingly and should not be used to reiterate what is clearly stated in code, should straight to the point and tell developers "why". But having comments is definitely a good best practice when not abused.

Google's own github style guide for C++ mentions using comments. Yes they say code should be clear and to use comments sparingly but again comments are "absolutely vital to keeping our code readable" - https://google.githu...e.html#Comments

Jeff Atwood says on his blog Coding Horror "No matter how simple, concise, and clear your code may end up being, it's impossible for code to be completely self-documenting. Comments can never be replaced by code alone" - https://blog.codingh...s-tell-you-why/

Lastly Uncle Bob, while a man who does say he prefers minimal comments, also does recognize that comments may be needed from time to time. https://blog.cleanco...ryComments.html.

But while there are many times they are not needed or abused, their presence alone (when used correctly) does not at all indicate a violate of some best-practice. And as many readers can see, there are a lot of differing opinions on the matter. But I believe the first time you revisit your code years later and see a comment you left that helps you out, you will see the power of good commenting. :)
1

jon.kiparsky 

15 March 2018 - 06:28 PM
So, I'm not going to go trawling for quotes, because it's the internet and you can find all the quotes you want, but most of the people that I know in the industry take the line that Uncle Bob takes in the article you cite:

Quote

It is well known that I prefer code that has few comments. I code by the principle that good code does not require many comments. Indeed, I have often suggested that every comment represents a failure to make the code self explanatory. I have advised programmers to consider comments as a last resort.


I say "most" out of courtesy. I actually can't think of anyone that I know who would disagree with any of this, and I spend a lot of time with a lot of programmers. Maybe things are different where you are, but the prevailing wisdom as far as I can see agrees with the statement that Bob starts out with.

The google style guide you cite also makes the point: "while comments are very important, the best code is self-documenting". That is, if you see a comment, it probably indicates that the code can be improved. That is, comments are a code smell. Sometimes, as in the Uncle Bob piece, you look at them and say, yeah, that's the best solution to that particular problem, but when you see a comment you always ask "how can I improve this?".

Do you actually disagree with any of that? I don't think you do.

Quote

their presence alone (when used correctly) does not at all indicate a violate of some best-practice.


I see. You're disagreeing with things I didn't say. I said that comments are a code smell: they alert you to places where you can probably improve the code. I did not say that comments are a violation of best practice, in fact I said quite the opposite: if you need a comment, use the comment. It's just that you should try really hard to not need the comment. I think you're actually agreeing with me there.
What is a violation of best practice is the idea that "You SHOULD have comments". I read that to mean "without comments, your code is less good". I may have misread it, but as paraphrased it seems fundamentally wrong to me. Code that needs no comments should not have comments added, and code that does need comments should aspire to be code that needs none. If my paraphrase is incorrect, then I'm sorry for my mistake.


Quote

I believe the first time you revisit your code years later and see a comment you left that helps you out, you will see the power of good commenting.


I actually agree with that. But I also claim that my first move when that happens will be to try to revise the code to be readable without the comment. Because I started at my current job about three years ago, so I very often have the joy of reading code that I wrote years ago and understanding what it meant without comments, and I believe that the power of clean code trumps the power of good commenting any day of the week.

Just to be clear on this: I'm trying to get to some sort of agreement on this. I think that what I'm saying here is actually stuff you agree with because you've said stuff like this many times. If you think you disagree, please re-read before replying. If you agree with that first paragraph from Uncle Bob, you don't disagree with me.
1

BobRodes 

20 April 2018 - 12:57 PM

jon.kiparsky, on 14 March 2018 - 08:31 PM, said:

Regarding comments, my standard is, if you need to use a comment, you should use a comment. On the other hand, a comment is an indication that the code you've written is not sufficiently clear, and should be reworked so that the comment is not necessary. This goes, in my opinion, for any language.
One common cause of comments is functions that are too long. A few years ago, the received wisdom was that a function should be small enough to fit on your screen without scrolling. Current consensus says that functions should be no more than ten lines in length, the logic being that ten lines is enough space to express one and only one action. Often, comments indicate a place where you need to name the functionality directly, by writing a function. In this case, the comment itself names the function, so it's an easy change to make.
If you find that you're explaining the logic of a function with a comment, to me that indicates that you need more functions. Needless to say, you will seldom be tempted to explain the logic of a ten-line function, though you might be tempted to change the name to improve clarity.


While I take the point that "smaller is better" where function size is concerned, I think a 10-line function limit ought to be taken with a grain of salt. It's a good rule of thumb in maybe 75% of cases, but rather than putting arbitrary limits on the number of lines of code, it seems more important to me to correctly apply proper cohesion and coupling to function architecture. When you do that, functions become small in a more organic and relevant manner.

Here's a PHP function that opens a connection to a database in 10 lines or less. It does one and only one thing, and so represents an example that fits the criteria.
           function Connect()
            {
                $this->hostname     = '************';
                $this->usernamedb   = '************';
                $this->passworddb   = '************';
                $this->dbName       = "************";
        
                $this->connection = mysqli_connect(
                                                            $this->hostname,
                                                            $this->usernamedb,
                                                            $this->passworddb) or die(mysqli_error('Cannot establish connection'));
        
                $this->dbSelect = mysqli_select_db($this->connection, $this->dbName) or die(mysqli_error('Cannot select DB'));
                $this->bConnected = true;
        }


However, it seems obvious to me that there are numerous contexts in which 10 lines wouldn't be enough to get a single job done. Here's another example:
               static void doWork(object prms)
                {
                    try
                    {
                        if (!(prms is ThreadParams))
                        {
                            throw new ArgumentException(Thread.CurrentThread.Name + ": Argument passed on thread start is not of type ThreadParams; 
                                thread aborted");
                        }
        
                        var p = (ThreadParams) prms; // So we don't have to recast prms every time we want to use it
                        DataExporter de = DataExporter.Instance; // Simplest way to implement a singleton
                        var cRet = new NorthwindDataRetriever();
                               
                        MethodBase cMethod = cRet.GetType().GetMethod("GetData", new Type[] { p.listType.GetType().MakeByRefType() } );
        
                        dynamic[] cArgs = new object[1];
                        cMethod.Invoke(cRet, cArgs);
                        
                        de.OnExportFinished += new DataExporterEvent(de_OnExportFinished); // Subscribes to the OnExportFinished event
                        de.Export(cArgs[0], p.filePath, p.fileType);
                        de.OnExportFinished -= new DataExporterEvent(de_OnExportFinished); // Unsubscribes from same
                    }
                    catch (NullReferenceException ex)
                    {
                        Console.WriteLine("Null Reference Exception in " + Thread.CurrentThread.Name + ": " + ex.Message +
                            " (probable cause is incorrect object type in listType thread parameter)");
                        return;
                    }
                    catch (ArgumentException ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Unhandled Exception: " + ex.Message);
                    }
                }


That's 19. The function has strong cohesion and loose coupling characteristics, and attempts to break it up to fit under a 10-line cap strike me as artificial and counterproductive. (It would be reasonable to put the event listener setup into a separate function, but I'd still only save two lines. Nevertheless, it might still be an improvement: a setupOnExportFinishedEvent() method is an opportunity for self-documenting code.)

Here's a jQuery function that puts up a dialog box:
        $('#btnPartAdd, #btnPartRem').on('click', function(e, ui) {
            var aOrR = ('btnPartAdd' == this.id ? 1 : 0); // If the user hit Add, we're adding, if he hit Removed, we're removing
            $('#dialogChildren').load('vdrmodal.php?id=' + id + '&aorr=' + aOrR, function(table) {
                $('#dialogChildren').dialog( {
                    modal: true,
                    maxHeight: 580,
                    width: 1100,
                    position: {my:'top', at:'top+60'},
                    buttons: [
                        {
                            id: 'btnSave', 
                            text: 'Save',
                            click: function(e, ui) {
                                var theData = $('#vdrDetail').DataTable().rows().data();
                                var theNodes = $('#vdrDetail').DataTable().rows().nodes();
                                var paramString = '';
                                for(var i=0;i<theData.length;i++) { // find every checked row and add or remove its data from the appropriate
                                                                    // underlying table
                                    if (theNodes[i].cells[6].children[0].checked) {
                                        paramString = 'table=partsdists&field1=PartId&field2=DistId&aorr=' + aOrR + '&id1=' + theData[i].Id +
                                            '&id2=' + id;
                                        $.ajax( {
                                            url: 'cdchildren.php', // handles the adding or removing of child records
                                            data: paramString
                                        });                                
                                    }
                                }
                                $('#hdnId').val(id);
                                $('#hdnAccordionActive').val(2);
                                $('#frmPostVars').submit();
                                $(this).dialog('close');
                            },
                            disabled: true
                        },
                        {
                            text: 'Cancel',
                            click: function() {
                                $(this).dialog('close');
                            }
                        }
                    ],
                    title: (1 == aOrR ? 'Adding' : 'Removing') + ' Parts',
                    open: function(e, ui) {
                        $('#vdrDetail').DataTable().columns.adjust();
                        $('.ui-dialog-buttonset button:first-of-type .ui-button-text')
                        .text((1 == aOrR ? 'Add' : 'Remove') + ' Selected');
                    }
                });
            });
        });


There's about 40 lines here. We can pull the anonymous functions out into named functions and get the count down, but again that seems artificial, and even then, we have the click handler at 13 lines, and the load function still has about 25 lines. One could perhaps also get that count down further by saying that some of the comma-separated elements are really one line, but that doesn't seem like a useful way to get under the line-count criterion. Again, this function does one thing: it displays a dialog box.

As a final example, here's a piece of code that also does one thing: calculates the highest rebate value available for a car on a dealer lot. There's a combination of complex business logic and numerous CRUD operations. Consider these requirements:
           ' Calculates the total rebate for a single VIN, and stores it in the database.  
            
            ' Business Logic:
            ' A given VIN may be excluded from qualifying for a rebate because:
            ' 1. The rebate is the wrong program type.  (e.g., user has chosen lease and a rebate is only valid for buy).
            ' 2. The rebate has buyer criterion requirements that are not met by the prospective buyer.
            ' 3. The rebate has car model, option, or year requirements that the VIN does not meet.
            ' If the VIN is not eliminated for the above reasons, the following logic applies:
            ' Rebates are either incentives or not incentives.  Rebates with term value are incentives, rebates with no term
            ' value are not incentives.
            ' Qualifying rebates that are not incentives:
            ' 1. May be either dealer optional or not dealer optional.  If not dealer optional:
            '       a. Their cash accumulates, that is, they increment a total rebate cash amount by the value of their cash amount.
            ' 2. If dealer optional:
            '       a. User chooses the amount to allow, up to the cash amount of the rebate which is to be construed as a maximum.
            '          This amount is treated as a discount for tax purposes, that is, it is subtracted from the total dealer
            '          remuneration prior to calculating any taxes.
            ' Qualifying rebates that are incentives:
            ' 1. Must meet both lease/buy and term requirements to qualify.
            ' 2. Are not cumulative with respect to cash: only one cash value can qualify.
            ' 3. Are selected on a lowest payment basis; that is, the otherwise qualifying rate/cash combinations become selection
            '    candidates, and from these candidates, the combination which will result in the lowest payment becomes the
            '    successful candidate.
            
            ' Functional logic:
            ' 1. Iterate through the rs(6) (rebate) recordset.
            ' 2. Eliminate rebates that do not qualify by program type.
            ' 3. Eliminate rebates that do not qualify by rebate factor.
            ' 4. Eliminate rebates that do not qualify due to intrinsic aspects of the car.
            ' 5. If present rebate is not yet eliminated, and is not an incentive, and is not dealer optional:
            '       a. Add its cash to the cumulative rebate cash value, for lease, buy, or both (contained in RebateCashB,
            '          RebateCashL).
            '       b. Add its id, with the present VIN, to the rsRebToInv recordset (which is a recordset of all VINs and their
            '          qualifying rebates).
            ' 6. If present rebate is not yet eliminated, is not an incentive, and is dealer optional:
            '        a. Look up the rebate id in the rsDlrOptional recordset.  If the cash_to_use field is not 0:
            '           1) Add present value of reb_cash_to_use to the DlrOptCashB and/or DlrOptCashL variable(s).
            '           2) Add present value of rs(6)!rebate_id, along with rs(8)!vin, to the rsRebToInv recordset.
            ' 7. If present rebate is not yet eliminated, and is an incentive (i. e. has a term value):
            '       a. Calculate a (lease or buy, based on program type value) payment.  If payment is lower than present payment
            '          (contained in LowIncentivePmtL or LowIncentivePmtB), then:
            '           1) Replace present value in variable with the newly calculated payment.
            '           2) Replace appropriate BestIncentiveCash value with cash amount from current Rebate.
            '           3) Replace approrpiate BestIncentiveRate value with rate from current Rebate.
            ' 8. When iteration through rs(6) is complete:
            '        a. Add BestIncentiveCash values to RebateCash values.
            '        b. If BestincentiveRate values are lower than their corresponding RebateRate values, replace the latter with
            '           the former.



That set of logic is entirely cohesive: it does one thing and nothing else. Here is one CRUD operation in the implementation of the functional logic:
 With rsRebToInv
     .AddNew
     !inv_vin = rs(8)!inv_vin
     !reb_id = rs(6)!reb_id
     !reb_prog_number = rs(6)!reb_prog_number
     !reb_desc = rs(6)!reb_desc
     !reb_start_date = rs(6)!reb_start_date
     !reb_end_date = rs(6)!reb_end_date
     !reb_prog_type = rs(6)!reb_prog_type
     !reb_cash_amount = rs(6)!reb_cash_amount
     !reb_dlr_optional = rs(6)!reb_dlr_optional
     .Update
 End With


That's 13 lines, and is only one of several CRUD operations. The entire function runs to about 100 lines, has 12 variables and about eight function calls. Now, I could further isolate two or three of these CRUD operations into separate functions, but none of the operations are reused in the application, so I would be adding function call overhead with no return on the investment. While there is a good deal of decision logic in the function -- one of the red flags for poor cohesion -- that is due to the number of decisions the business rules require to achieve the result.

If you have a business rule that states "X is true if it's Tuesday, Wednesday, or Thursday, in an even-numbered month, but only if your grandmother wears a blue dress to church on Sunday, unless your grandfather wears a suit, but if they drive a red car she has to wear a red dress and your grandfather can't wear a suit; otherwise, Y is true if you have a purple house, unless your grandmother wears a red dress to church on Sunday and doesn't drive a red car," then perforce you are going to need a lot of decision logic (and more than 10 lines of code, no matter how much you break it into separate functions, unless you have functions calling functions just to stay under the cap) to calculate X.

I believe a more reasonable criterion for function size is to apply tight cohesion and loose coupling. Yes, a function should do one and only one thing. And a large amount of decision logic is a strong indicator that you have issues with cohesion, although there are exceptions as I believe I have shown. But if you have multiple function calls you can run into overcoupling issues, so the two ideals have to be balanced with one another.

This blog post does a nice job of laying out a more nuanced point of view.
1
Page 1 of 1

September 2018

S M T W T F S
      1
2345678
9101112131415
16171819202122
23 24 2526272829
30      

Recent Entries

Recent Comments

Search My Blog

1 user(s) viewing

1 Guests
0 member(s)
0 anonymous member(s)