Navigation
Recherche
|
11 rules for writing better code
mercredi 26 février 2025, 10:00 , par InfoWorld
You can’t develop software and manage software projects for 30 years and not learn a thing or two or twelve about writing good code. Here are a near-dozen nuggets of coding wisdom I picked up along the way.
Simpler is better This basic idea almost goes without saying, but I am frequently surprised at how often the KISS principle (“Keep it simple, stupid”) is ignored. Developers seem to love newfangled ways of doing things. Why do a “simple create and use an object” when you can pass around lambdas to do all the work? Why use a simple, standard data structure when you can build your own, custom, cutting-edge solution? What’s another layer of abstraction among friends? Just because that new language feature is cool and complex doesn’t mean you have to use it. Complexity is the opposite of simplicity, and the way to avoid complex code is to never write anything complex. Only write simple things. Be clear I am astonished at how often developers will unintentionally obfuscate their code. Just because you know what the variable named TxMgrObj means doesn’t mean the next developer does. Why not just type out TransactionManager? This hurts my eyes: const txMgrObj = getTxMgr(); txMgrObj.process(); But I find this pleasing: const transactionManager = getTransactionManager(); transactionManager.process(); And if you say to me “That’s too much typing,” I’ll respond with “Lazy is no way to go through life, my friend.” Thinking that saving a few keystrokes is going to save you time and effort is foolish and ridiculous. Being clear often means more lines of code. For instance, always use an explaining variable. Instead of an if statement with four different boolean conditions, how about four boolean variables, and then a fifth that defines the relationship between the first four, and use that in the if statement? (Or better yet, avoid the if statement entirely—see below.) Sure, naming things is hard, but a nice long name can explain a lot. Don’t be afraid to have a variable named NumberOfSpacesAllowedOnaPrinterLine. Trust me, no one will complain. Follow the Law of Demeter When you go up to the checkout station at the grocery store, you don’t hand over your whole wallet to pay. You pull out your card. The Law of Demeter states that you should limit interactions to the absolute minimum. If your method requires a transaction number, pass in the transaction number. Don’t pass in a class that has the transaction number in it, or a query object that contains the transaction number. Code for 0, 1, or N I worked on a system with a tax array that was hard-coded to six and no more than six elements. The whole system was designed with that limitation. I’m sure that when the code was written the developer thought that six different taxes for an order was an absurdly large number and made it six “just in case.” Well, do I even need to tell you what happened? Sometimes you need to make sure that there are zero things in an order before deleting it. Sometimes you need to ensure that there is only one event handler for a given event. Sometimes you need to allow any number of event handlers. And you need to be very, very sure before you decide that there can be no more than three of anything in your system. A corollary to this rule is… Don’t hard-code anything This seems obvious, but some developers love to hard-code stuff. Sweet baby Elvis, I even see this kind of thing all the time: someString.PadLeft(13); I mean, really? Why 13? Why not 14? Or 12? How about a constant that explains the meaning of the value? You may not think so, but every time you create an object inside a class, you are hard-coding that class and its implementation. For example: class SimpleEncryptor { public encrypt(plainText: string): string { const weakEncryption = new WeakEncryptionAlgorithm(); return weakEncryption.encrypt(plainText); } } So what if you want to change the encryption algorithm? Instead, use dependency injection, and you can use any algorithm you want: interface IEncryptionAlgorithm { encrypt(plainText: string): string; } class SimpleEncryptor { public encrypt(plainText: string, encryptionAlgorithm: IEncryptionAlgorithm): string { return encryptionAlgorithm.encrypt(plainText); } } Often ‘over-engineering’ is proper engineering Believe me, I get the notion of over-engineering. I just told you to keep things simple. But sometimes, doing things “the right way” looks like over-engineering. Whenever you think you are over-engineering, stop and consider that, well, maybe you aren’t. Creating interfaces and coding against them can seem like over-engineering. I know it’s a fine line to walk, but planning ahead for something you know you will need is not wrong. And this leads me to… Sometimes you are going to need it I’ve never quite understood the YAGNI principle (“You aren’t gonna need it”). All too often, you find that, well, you know, you did end up needing it. And by then, implementing this thing you “weren’t going to need” has become such a nightmare that you dearly wish you had gone ahead an laid the groundwork for it. Maybe you hard-coded something (you weren’t going to need flexibility here, right?). Maybe you didn’t plan on ever needing seven taxes, or a different encryption algorithm. I see no harm in thinking “You know, eventually, we are going to need to deal with more than widgets here” and coding so that changes are easy when new cogs and sprockets inevitably come along. Make the command line your first user interface All of your business logic and other, non-interface code should be accessible via a command-line application. If you can’t run your code at the command line, and it requires some kind of GUI or other interface to run, then you have improperly coupled your code and possibly tied it in knots. This is an approach that I started taking when I realized that at the heart of all crappy code is the tying of business logic to the user interface. The two should be treated like oil and vinegar, but all too often they are mixed together like Kool-Aid. Separate your concerns and prove it by running your code with a command-line application. Be wary of if statements (very wary) I am a firm believer that every use of an if statement should cause the humble developer to stop and think “Should this be two routines?” Or better, “Should this be a whole new class?” The vast majority of awful spaghetti code and impossibly huge routines that I see are the result of a massive number of deeply embedded if statements. You know what I’m talking about. It’s the routine that literally handles 47 different situations, all in one giant, thousands-of-lines-long procedure. Be very wary of if statements, because they often lead to violations of the final lesson, which is… Everything should do one and only one thing This might be the single most important rule a software developer should know. Everything should do one thing. Everything. Every line of code. Every routine. Every class. Everything. As Ryan Singer has said, there is no end to the misery caused by trying to make one thing do two things. Just think of the awfulness that is having one thing do 26 things. Every time I see a procedure name with “and” in it, I want to scream. ProcessAndStoreOrder()? No! If you see an opportunity to use Extract Method refactoring, do it. Do you ever wonder “What is the longest I should let my procedures be?” The answer is simple: Keep making them shorter with your Extract Method tool until you can’t apply that refactoring anymore. The code will quickly become a collection of discreet methods that do only one thing. Sure, you’ll end up with countless little functions and procedures. But of course, what is encapsulation other than gathering functions, procedures, and data together? Complexity hurts If there is one rule that sums it all up, it’s that complexity makes you miserable. Writing good code means writing simple, clear, “boring” code—code that minimizes the cognitive effort required to understand it. And if there is one last thought you walk away with here, let it be this advice from John Woods: “Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.”
https://www.infoworld.com/article/3832644/11-rules-for-writing-better-code.html
Voir aussi |
56 sources (32 en français)
Date Actuelle
mer. 26 févr. - 20:36 CET
|