Single responsibility principle

The responsibility of the Single Responsibility Principle (SRP) is defined as “cause of change”. If we have two incentives to rewrite a method, then the method has two responsibilities. If a method takes on too much responsibility, it is more likely that the method will need to be rewritten as requirements change.

Thus, the SRP principle is: an object (method) does only one thing.

SRP principles are widely used in many design patterns, such as the proxy pattern, the iterator pattern, the singleton pattern, and the decorator pattern. For specific examples, see the previous several articles: [youth Camp] – Common design patterns in JavaScript (part 1), [youth Camp] – Common design patterns in JavaScript (part 2).

In proxy mode, we put the responsibility of preloading images into proxy objects by adding virtual proxies, while the ontology only takes care of adding img tags to the page.

    var myImage = (function () {
      var imgNode = document.createElement('img');
      document.body.appendChild(imgNode);
      return {
        setSrc: function (src) { imgNode.src = src; }}}) ();var proxyImage = (function () {
      var img = new Image;
      img.onload = function () {
        myImage.setSrc(this.src);
      }
      return {
        setSrc: function (src) {
          myImage.setSrc('./loading.gif'); img.src = src; }}}) (); proxyImage.setSrc('http://xxxxx.jpg');

Copy the code

So how do you separate responsibilities? To be clear, not all responsibilities should be separated. If there are two responsibilities that always change at the same time as requirements change, there is no need to separate them, and it makes sense if and only if they are certain to change.

In addition, we do not have to adhere to the principles at all times, as SRP violations are not uncommon for a variety of reasons. Methods such as attr in jQuery are responsible for both assignment and value. There is a trade-off between convenience and stability.

The SRP principle has the advantage of reducing the complexity of a single class or object, which facilitates code reuse and unit testing. However, the SRP principle has some disadvantages, most notably the increased complexity of writing code. When we break objects down into smaller granularity by responsibility, we actually make it harder for them to relate to each other.

Least knowledge principle

The least knowledge principle (LKP) states that a software entity should interact with as few other entities as possible. The software entity here is a broad concept, including not only objects, but also systems, classes, modules, functions, variables, etc.

The single responsibility principle guides us to divide objects into smaller granularity, which improves object reusability. But more and more objects can be intertwined. The least knowledge principle requires that we should minimize the interaction between objects when designing programs. If two objects do not have to communicate directly with each other, then they should not interact directly with each other. A common practice is to introduce a third party object to assume the role of communication between these objects.

The least knowledge principle is most commonly reflected in design patterns in the mediator pattern and appearance pattern.

While following the principle of minimum knowledge reduces the dependency between objects, it may also increase the number of third party objects that are too large to maintain. As with the single responsibility principle, choosing to conform to the least knowledge principle in actual development depends on the context.

Open – close principle

The open-closed principle was first proposed by Bertrand Meyer, the designer of Eiffel language, in his work Object-oriented Software Construction. It is defined as follows:

Software entities (classes, modules, functions), etc., should be extensible but not modifiable.

The idea behind the open-closed principle is that when it is necessary to change the functionality of a program or to add new functionality to the program, the code can be added, but the source code cannot be changed.

They are found in patterns such as publish-subscribe, template method, policy, broker, and chain of responsibility.

In chain-of-responsibility code, you might wonder: the open-closed principle requires that you extend the functionality of your program only by adding source code, not by modifying it. So when we add a new $100 order function node to the responsibility chain, don’t we also have to change the code that sets the chain?

order500yuan.setNextSuccessor( order200yuan ).setNextSuccessor( orderNormal );
Copy the code

into

order500yuan.setNextSuccessor( order200yuan ).setNextSuccessor( order100yuan ).setNextSuccessor( orderNormal );
Copy the code

In fact, it’s not easy to keep a program completely closed. And the price of conforming to the open-closed principle is the introduction of more levels of abstraction, which can increase code complexity. Moreover, some code is not completely closed by any means.

So there are two things we need to do with the open-closed principle.

  • Pick out the places where change is most likely to occur, and then construct abstractions to seal off those changes.
  • When changes inevitably occur, try to make changes that are relatively easy to make.

The resources

“JavaScript Design Patterns and Development Practices” “Object-oriented Software Construction”