今日推荐英文原文：《7 Ways to Limit Scope in Your Code》
今日推荐英文原文：《7 Ways to Limit Scope in Your Code》作者：Nick Hodges
7 Ways to Limit Scope in Your Code
Easy methods you can adopt to keep your code clean, concise, and testableAs a general rule, developers should limit the scope of variables and references as much as possible. Limiting scope in every way possible, from the big things (never, ever use global variables) to the subtle little things a language can do (declare
constwhenever possible), can contribute to clean, easy-to-test code.
The limiting of scope has all kinds of benefits. First, limiting the scope of a variable reduces the number of places where a given variable can be modified. The reason we rightfully abhor global variables is there is no telling where or when a global variable might be changed. A global variable hangs out there like that last donut in the break room. You know you shouldn’t touch it, but it’s so tempting and easy just to grab that variable and use it for whatever you need to do. Limiting the scope of a changeable thing reduces the chances that it will be changed in a way that it shouldn’t be — or worse, in a way you don’t even know about.
By definition, limiting scope is also a main feature of object-oriented programming. Encapsulation is probably the first thing you think of when you think of OOP, and its basic purpose — its whole reason for existing — is to formalize the process of limiting scope. They don’t call it “information hiding” for nothing. The term “information hiding” really means “Hide the scope of your variables so much that they can’t be changed except in the exact way you let them be.” Encapsulation enables you to ensure that data you don’t want to be exposed isn’t exposed. And if it isn’t exposed, it can’t be changed.
Limiting scope also limits the ability for people to depend on code that they shouldn’t be depending on. Loose coupling — the limiting of the dependencies within a system — is a good thing. Tight coupling is a bad thing. Limiting scope makes it harder for one class to latch on to another class and create dependencies that make code hard to test and difficult to maintain. It also makes it harder for changes in one area of code to have secondary effects in other, coupled areas. There is nothing worse than changing code in (metaphorically speaking) New York City and having that change cause a bug in code all the way over in Los Angeles. This is commonly called “Action at a distance” and is something that should be avoided like a bad burrito.
7 Ways to Limit ScopeThere are big, well-known ways of limiting scope (objects, making a variable local to a method, etc.), but there are a lot of smaller, subtler ways to limit scope as well. I’ve tried to list some ways that you can limit scope in your code:
- No global variables. None. Zero. This one isn’t so subtle, but it’s essential. It’s really easy to make sure that you never declare a variable as global. You can do it in many languages, but you never should. In languages like C# and Java, you actually can’t, strictly speaking, declare a global variable — everything has to be in a class — but you can create a field on your main class that is pretty much the same thing. Just because you can doesn’t mean you should. So don’t.
- Don’t create anything. Instead, ask for what you need. This topic is a big one unto itself and gets into the question of dependencies and dependency injection. But if you try to never actually create anything in the constructor of your class and instead pass the constructor existing instances of what it needs, you can limit the scope of a given class. Better yet, if you use a full-blown dependency injection container, you can very severely limit the scope of your classes and still fully benefit from their functionality.
- If a variable can be local to a routine, do it. This goes along with “No global variables ever,” but it needs to be said. If you can declare a variable in the scope of a single method, do it.
- Use constants whenever possible. If you are never going to change the value you assign to a variable, why make it a variable at all? Get in the habit of making something a constant and then only making it a variable if it needs to be. Do this even inside your methods.
- If you can make a variable private, do it. If you can’t, make it protected. If you can’t do that, make it public. This one is a little trickier because there are OOP principles to be considered. But generally, make field variables private and give access to them through public setter methods. This way, while the data can be changed, the actual storage device itself is not directly accessible. Also, you can control the ability to change the internal data through a setter method.
- Provide notification systems in your setters to monitor changing data. Sometimes, you might have data that needs to be changeable but is sensitive for some reason. As a result, you want to monitor and maybe even prevent the changing of your internal data. You can use something as simple as an event in the setter method or something more robust and flexible, such as the Observer pattern.
- Don’t reach into another class. Or even better, don’t create classes that someone else can reach into. This gets into the Law of Demeter, which I’ve discussed before.
ConclusionThat’s a short and probably incomplete list of ways to limit scope. What are other little methods and techniques that you all use to limit the scope of your variables?