📜 ⬆️ ⬇️

Self-documenting code is (usually) nonsense

Hello!

Anticipating today's translated publication, we immediately note that this text is intended as a follow-up to the recent discussion material " Stop zealous with comments in the code ." We were so impressed by the discussion that took place there and by 189 comments as of 07/19/2019, that we decided to give the floor to another author from the Medium portal (Christopher Lane), who, on almost all matters of principle, contributes to the theses of the first article. Note that in the original this article came out a month later than the previous one (May 16 and June 16), but gathered almost half the applause (706 vs. 1.5K at the time of publication of the translation). Let's see what will be on Habré ...


')
Photo taken from rawpixels.com by Pexels

I carefully read Cindy Cheung 's excellent article on technical documentation and why developers should better explain their own code — and I must say that I fully agree with it.

I’ve been fucking long at this your IT, and my experience suggests that there is such a self-deception in our business that developers and engineers simply cannot resist.
My code is self-documenting - erroneous developer
In theory, the code of a good engineer should be so clear and readable that he simply does not need any documentation.

You know, this is nonsense ... as a rule.

Why is the “self-documenting code” nonsense?


Suppose you write code as coolly as Hemingway wrote prose . Perhaps your super-duper code is clean and straightforward (to another developer). In the end, this code is written by a techie for a techie, and no matter how clean and concise your code may seem, it is still not meant to be read by non-programmers who might grumble: “what the hell is all this mean ?!

Why do I think that self-documenting code is complete nonsense? Let me put it in detail.

Reason 1: The programming is full of all sorts of tricks that are not self-documented.

Just because most people, including developers, are not machines. Yes, most likely I’ll go through your code, understand correctly the names of your methods and classes, even understand exactly what you are doing in each method.

But code is written for machines. They understand much better what to do with it, and it is in order to describe it to them that we have programming languages. With people, you need to communicate in a more human language so that the person can understand what your software does.

There is a very big difference between “I read the code and see what happens in it” and the documentation. In the code, you can write down with all the details what is being done in it, but is it possible in that case to call it “self-documenting”? I think everyone understands that it is impossible.

Consider the following simple C # blob. I read the file, get its contents, and then get the file encoding using StreamReader.

var fileContents = “”; Encoding fileEncoding; using (var reader = new StreamReader(filePath, Encoding.Default, true)) { reader.Peek(); fileEncoding = reader.CurrentEncoding; fileContents = reader.ReadToEnd(); } 

If you abstract from possible ambiguities with StreamReader, otherwise this code is quite simple, right? Then ... have mercy, and what is being done in this line?

 reader.Peek(); 

It turns out that the reader must perform this action to get the file encoding. Tell me, where is the self-documentation? But it is enough to spend some 10 seconds to make the code much clearer.

 reader.Peek(); //     ,    . 

This is just one example, and, damn simple. As your code becomes more complicated, such small details begin to emerge everywhere and gradually litter the once clean code. The person who will read it is becoming increasingly difficult to grasp what is happening in the code.

Reason 2: Complexity is not self-documenting in its essence.

If you have been able to write BASH or BAT files, then you know that the actions outlined in such a file are performed sequentially. One task after another. The file resembles a short story, which is read from the first to the last line.

However, if you are writing a program, and especially a web application, such a consistent history will not be there, except for the code for initial loading and configuration of all web services.

The classes themselves, which constitute a modern web application, are not executed sequentially. In essence, they are a collection of web or API controllers that are called during the interaction of a client with a web application. Each web or API controller can provide execution threads for which new processes are branched off, messages are sent to other services, responses are expected, so that the web hooks of the listeners will work according to their results. Nothing can hardly be described in a “plot” format. From all your “self-documenting code”, a novice or non-programmer will only extract “it seems, I understand what is happening here.” Again, hardly anyone will dare to trust such “documentation”.

The more complex your application, the higher the likelihood that its classes, methods, and the entire framework will not work in sequential mode. Assuming that anyone who encounters such an application easily understands from the code what is happening in it, you are entering an increasingly slippery path.

Reason 3: The syntax of programming languages ​​in principle can not be called readable

Just take a look at this jquery function, the calling endpoint API.

 var myURL="https://some.url/path?access_token=my_token"; $.ajax({ url: myURL+"&callback=?", data: "message="+someOtherData, type: 'POST', success: function (resp) { alert(resp); }, error: function(e) { alert('Error: '+e); } }); 

Phew ...

No, I do not want to say that there is something wrong with the syntax. Everything is perfectly acceptable for calling jquery. But I emphasize that if you look at it through the eyes of a novice or non-programmer programmer, then this listing may well turn out to be no more understandable to him than bytecode. There will be no more meaning in it.

Syntactically, programming languages ​​are designed so that they can actively use the restrictions defined by the language itself, as well as useful shortcuts that help keep the code compact and easily change it as needed. A programming language does not conceive of as a uniquely reliable means of communication, in which everyone will understand. It is designed for professionals who know the language itself, its syntax and shortcuts.

For all others, the programming language is incomprehensible.

What to do?

There are some tricks that you can use to help non-specialists understand your code.

Stage 1: Try to write documentation


Blasphemous sounds, right? Write documentation ?! Nothing funnier you could think of!

Seriously, no one requires you to write "War and Peace." But try to describe in the technical documentation the main actions, validation and error handling - a simple consistent style.


It is hardly difficult to do, but by writing such documentation you will make life easier for someone. If selfish motivation is closer to you, think about it: if every time you are asked for help and explanations, you can simply point them to the documentation and not interpret the same things over and over again.

Stage 2: Draw Schemes


If you write simple documentation for you all the same difficult, then at least try to draw the most necessary schemes, as they often serve as the very “glue” that helps a person from the outside to correlate your code with what is happening in it.
Check out websequencediagrams , where you can write excellent sequence diagrams in a simple text format — and then create them.

Text

 title Service one to service two Service two requester -> Service two http client: Get Contract Service two http client -> Service one REST API: GET /api/contracts/{123} Service one REST API -> Service one app logic: get Contract with id 123 Service one app logic -> Service one REST API: Contract Service one REST API -> Service one REST API: Serialise to JSON / XML / etc. Service one REST API -> Service two http client: Serialised data Service two http client -> Service two http client : Deserialise to Contract Service two http client -> Service two requester: Contract 

The diagram that comes out of it



Handsomely!

The phrase that a picture is worth a thousand words is true, however. Such diagrams and flowcharts will help a non-programmer understand the behavior of your application, and for this he will only need to carefully examine the picture. Colleagues will appreciate it, and from your side it will be a small investment in a common cause.

Step 3: Name your classes and activities in the Unified Language (Ubiquitous Language)


As you know, the Unified Language is a concept from DDD (subject-oriented design), where the team and users are required to develop a language that would describe all classes and their interactions. Such a language is understandable to a non-expert, so customers, testers, instructors and business representatives will be able to read and understand what exactly our program does and how it solves user problems in a given subject area.

Once the Unified Language is consistent, you must ensure that all your classes, their methods, events, and everything else are named as close to the Unified Language as possible.

 /// <summary> ///        /  ,            /// settings /// </summary> public interface ICustomer { Task<AuthenticationResult> Login(string username, EncryptedString password); Task Logout(); Task<CustomerProfileInformation> GetMyProfile(); Task SaveMyProfile(CustomerProfileInformation); Task<CustomerSettings> GetMySettings(); Task SaveMySettings(CustomerSettings); 

Although it is just a code fragment, it is written above it in a simple and commonly understood language what is happening here.

Stage 4: Just Write Comments


If all of the above seems too burdensome to you - just provide your code with informative comments. You may not need them right now (you are now immersed in the code with your head, everything is clear to you), but in the future they may be very useful to you.

Just a few correctly spaced lines with comments, a comment to a class or method will be enough to make the code much clearer. I do not urge you to comment on each line (this only makes the code more complicated). Just comment with comments on the most difficult parts of the code so that the one who will go through it will understand where this code will lead him.

I hope these tips will be useful to you.

Source: https://habr.com/ru/post/460725/


All Articles