Why Closed Software Is Better Than Open
Tags: programming, webdev, javascript, dev
Published: 2021-08-24 00:26:49

## Restrict the scope of your software by default. Increase the scope as the need arises.

----

When you build software, you may end up in situations where the integration between several components becomes significantly hard to understand. Say you're reasoning about a component that is dependent on a set of variables or functions, and you share those variables or functions between other elements in the same system.

Several principles help you create software that humans can understand ([SOLID](https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)), [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself), [Atomic Commits](https://medium.com/@fagnerbrack/one-commit-one-change-3d10b10cebbf), etc.). Those principles are practical regardless of the programming paradigm or language you use. However, there is one principle many communities follow, and you can apply it anywhere regardless of the paradigm or programming language:

> ### Restrict the scope by default. Increase the scope as the need arises.

If there is a component — be it a variable, function, class — that doesn't need knowledge of an outer scope, you should start writing it with a restricted scope first. Later, you expose to other scopes as necessary.

If you don't expose the component, then it's unlikely a developer will try to "reuse" for a purpose different than the one you intended. Also, you won't have to think about the requirements that don't exist.

Think of the "[Principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege)" applied to the process of software development and design.

### Java

In Java, there are access modifiers you can use to change the visibility of the members in a class. When you start to write a class or its members, you shouldn't spend time thinking if that functionality should be exposed or not. By default, use the private modifier, which represents the maximum access restriction. If there is a legitimate need later, you increase the visibility scope for that class or member and use it outside its strict initial scope.

{% gist https://gist.github.com/FagnerMartinsBrack/ab14ebcccc0e3a86399c2c59b123d181 %}

Another example is the `final` modifier. Although it's not concerned with visibility, it restricts the binding. If you use it in a class, [it prevents subclassing](http://stackoverflow.com/questions/218744/good-reasons-to-prohibit-inheritance-in-java/218761#218761). Likewise, if you use it in a variable, it prevents the reference to change, ensuring the binding remains consistent, even in a multi-threaded environment.

> ### By default, use the final modifier in all declarations. If there is a legitimate need later, you increase the visibility scope for that class or member and use it outside its strict initial scope.


{% gist https://gist.github.com/FagnerMartinsBrack/581f016cca884e0af9eb06e5b4bec137 %}

It looks like there is a conflict between the Strictness Principle and the [Open-closed Principle](https://en.wikipedia.org/wiki/Open/closed_principle) when you think about Strictness in the context of inheritance. Does it make sense to create everything with a restricted scope if subclasses require you to change the code instead of extending it?

If you want to subclass, it's probably part of the requirements, not speculation; therefore, it's better to design [the class to be extensible](http://stackoverflow.com/a/218769/1400037) from day one. Strictness should be the minimum necessary to achieve that extension, not more. Be aware, though, subclassing through classical inheritance is a [code smell](https://fagnerbrack.medium.com/code-smell-92ebb99a62d0). You should consider other forms of class extensions instead of inheritance, such as [composition](https://en.wikipedia.org/wiki/Composition_over_inheritance) or [prototypal inheritance](https://en.wikipedia.org/wiki/Prototype_pattern).

### JavaScript

As of May 2016, JavaScript is not as robust as Java for handling visibility access. It requires [Duck Typing](https://en.wikipedia.org/wiki/Duck_typing) and lexical closure techniques. Still, it does have some features that could leverage the **Strictness Principle**, and you can find that knowledge within the community.

For example, it's impossible to create something block-scoped in pre-[ES2015](http://www.ecma-international.org/ecma-262/6.0/); therefore, it's necessary to use a closure so that everything inside won't be accessible outside. The ability to control access through closures gave birth to the [Revealing Module](https://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript) pattern (by Addy Osmani), which uses an IIFE ([Immediately-Invoked Function Expression](http://benalman.com/news/2010/11/immediately-invoked-function-expression/) — by [Ben Alman](https://www.linkedin.com/in/benalman/)) as its execution engine. When using this pattern, you restrict the variables by default unless required by the parent scope.

{% gist https://gist.github.com/FagnerMartinsBrack/a9e0defecbef69cc623a3e25e5a75418 %}

In JavaScript, [ES2015](http://www.ecma-international.org/ecma-262/6.0/) and beyond, it's possible to use the `const` modifier, which besides being block scoped (like `let`), also restricts the variable binding, similar to Java's `final` modifier.

Again, Mathias Bynens [recommends using `const` by default](https://mathiasbynens.be/notes/es6-const#const-vs-let) due to its strict properties unless there is an additional need for rebinding (like the `punch` variable below on line `6`).

{% gist https://gist.github.com/FagnerMartinsBrack/d1f7a11bdacc9ae629fe4fb86b12351b %}

### Angular

The Strictness Principle doesn't apply only to languages but also to frameworks.

Angular 1 has something called **isolated scope** for directives. By default, all directives will share the parent's scope, but that can cause unintended consequences. If you declare elements in the parent scope, the system will break when you move the directive elsewhere. If the isolated scope is used by default instead, then the directive will create a new scope that will only access the attributes you pass when you use the directive in the HTML template.

The best practice here is: to use an isolated scope for directives by default unless there is a good reason not to do so. Be careful, though; [using by default doesn't mean using it blindly](http://www.bennadel.com/blog/2729-don-t-blindly-isolate-all-the-scopes-in-angularjs-directives.htm).

{% gist https://gist.github.com/FagnerMartinsBrack/fd27579bd733f3c8d221d418e6f2a43e %}

{% gist https://gist.github.com/FagnerMartinsBrack/73970d5a0b85015fe26617d83e442b4e %}

The Strictness Principle is not limited to programming language syntax. You can also apply it to other domains where there is a definition of scope:

* The scope of a project and new features. You restrict the new features within a given area unless there is a good reason to tackle the same problems in other areas.
* Discussions. Restrict discussions to a specific topic unless there is a legitimate need to increase the conversation's scope.
* [Test-Driven Development](https://fagnerbrack.com/the-strictness-principle-9997e483cafb). Restrict the scope of your transformations according to the [Transformation Priority Premise](https://blog.cleancoder.com/uncle-bob/2013/05/27/TheTransformationPriorityPremise.html). Increase the scope of the transformations as the tests drive you to do so.

Avoid building something accessible by many different parts of the system unnecessarily, even if your tool, language, or framework allows that. Try to be as strict as possible to:

* Prevent unintended side effects
* Keep the focus on what is important
* Reduce the cost of change in your software

Strictness is an important principle to control [Software Entropy](https://en.wikipedia.org/wiki/Software_entropy).

Leverage the Strictness, but [don't be blinded by it](https://fagnerbrack.com/the-strictness-principle-9997e483cafb).

----


Thanks for reading. If you have some feedback, reach out to me on [Twitter](https://twitter.com/FagnerBrack), [Facebook](https://www.facebook.com/fagner.brack) or [Github](http://github.com/FagnerMartinsBrack).