📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

Чистый код. Приемы написания красивого и понятного кода (Алексей Аверьянов)

ФТО26:55

Transcription

I am glad to introduce Alexey Averyanov from the automotive company. [Applause]

Hello! Indeed, there was just a little hiccup where I almost got expelled, but everything worked out.

So, for the presentation, should I go first or will you? Traditionally, we’ll start with a small slide.

I’ve been in this field for quite a while, since my last years at the university. During this time, I’ve held various roles, working in different companies, both as a franchisee and in-house, directly within user companies. Currently, I work as a developer at the franchisee company Auto Makam in Moscow. We deal with 1C, meaning we service, implement, and configure 1C for the VkusVill stores. Today, we have around 1,300 stores in Russia and beyond.

As a developer, I work in one of the teams focusing on integrating 1C with external and internal services. I am also a consultant at the Automation company in Omsk, where I live. As I mentioned, I came from Omsk.

Now, regarding my talk, I want to highlight a topic that I believe doesn’t get enough attention in the 1C community: writing clean, understandable code. We will discuss what clean code is, why it’s important to write understandable code, and we’ll look at some techniques that can help us write clearer code than we did yesterday.

For those who want to dive deeper into the topic, I’ll mention two books: "Clean Code" by Robert Martin and "The Pragmatic Programmer" by Andrew Hunt and David Thomas. The first one is simpler, while the second is quite fundamental. Both books are highly regarded and have been recognized multiple times. For those interested, you can explore them further.

Of course, the third source of information is the 1C development standards. It’s essential to adhere to the standards in this industry.

Let’s start with the problem statement.

For whom do we write code? There’s a common misconception that we primarily write code for computers, with the main requirement being that the code works correctly, efficiently, and without errors. However, in a world where systems are developed not by lone enthusiasts but by large groups of people, we write code primarily for other people—other programmers who will work with it later.

These could be our colleagues on the same project, clients for whom we are doing this work, or even ourselves a year later when we revisit our own development and wish we had written it differently.

Let me give you a couple of examples.

For instance, consider how easy it is to work with code written in a clear style. Now, imagine that instead of ten lines, it’s five or six screens of code that you need to work with.

It’s clear that the example is toy-like, but I have encountered such situations in real life. The goal here is to demonstrate that code can be written in a way that is completely unclear.

Now, here’s the same algorithm, but written in a more human-readable style. Statistically, 90% of the time we spend coding is not writing new code but reading and understanding existing algorithms. We try to figure out how they work, look for errors, and modify them.

Intuitively, anyone who programs can distinguish between more understandable code and code that is completely tangled.

Let’s go through some simple criteria for clean code.

As I mentioned, clean code is more understandable and pleasant to read. There are minimal negative emotions when reading it. It effectively solves tasks and decomposes various elements and functions, each of which solves its own task well. It contains minimal duplication, as much as 1C allows, and clearly expresses the architectural concepts laid out by the author.

It’s predictable; for example, if we encounter a function like "getEmployeeList," it returns a list of employees and nothing else. It looks like it has been well thought out, not just something hastily thrown together for production.

Now, let’s move on to the main part and discuss practical techniques for writing more understandable code.

We noted that we write primarily for people, to make it easier for them to work with what we’ve created.

The first block we’ll discuss is how to name variables, procedures, functions, and other named entities, including metadata objects.

Your code should look clear to the person reading it. If your variable names are unclear, even if they consist of meaningful words, they may still appear confusing.

When you introduce a new variable name, take a few seconds or minutes to think about whether it answers the following questions: Why does this variable or function exist? What does it do? What does it contain? How is it used?

Every time you define a new variable, consider how well it answers these questions.

Let’s look at an example. Suppose we have a variable for a table and its cells. From the name, it’s clear that there’s a table with some cells, and it likely contains results from a function that returns some cell placements for products.

You can see the architectural solution here; it’s clear that this returns specific placements.

As we iterate through the table, we take some fields from each row. The variable names reflect what we are writing.

Again, when you introduce a new variable name, spend a few moments thinking about how understandable it will be to someone seeing it for the first time.

If you’re revisiting code you wrote yesterday or a year ago, or even modifying your colleagues’ code, and you find a variable name that doesn’t reflect its meaning, take the effort to change it.

This is one of the first steps to making your code more readable and understandable.

The next principle we’ll discuss is writing more compact procedures and functions.

While 1C and compact procedures/functions come from slightly different worlds, they still share a level of abstraction.

Initially, when programmers began writing in a procedural style, procedures and functions were created to eliminate duplication. If we use some code multiple times, we package it into a separate procedure and reuse it.

Some programmers mistakenly believe that if a piece of code is only used once, there’s no need to extract it into a separate function. However, using procedures and functions significantly enhances the clarity and perception of the code.

Let’s look at a playful example.

Imagine we need to build a house on a plot of land. Instead of writing a massive procedure that describes everything at once, we break it down into simpler steps.

Each step can be further decomposed into even simpler steps.

At the highest level of abstraction, we break our algorithm down into just three simple steps: create a general plan for the plot, build a house according to that plan, and beautify the plot.

We don’t need to detail how we create the plan at this level; what matters is that our algorithm consists of these three steps.

Next, we detail each step, for example, breaking down the house-building process into its own steps.

Now, let’s look at a more practical example.

There’s an HTTP service handler that processes incoming HTTP requests, extracts parameters, checks them, retrieves data from databases and other systems, and packages everything into a response structure.

If we stretch this out into one level of abstraction, it could be 500 to 800 lines of code.

However, this function can be written in such a way that at the top level of abstraction, we only have about 11 lines, three of which are exception handling.

We describe the main algorithm in broad strokes, with three lines extracting parameters and transforming them. Each subsequent procedure or function is broken down into its own steps.

When we work with this code, we can dive deeper where needed, without having to read everything to find what we need.

Next, let’s discuss magic numbers.

You read through the code, and everything seems clear until you reach a line where a procedure is called with some parameters, including a number like 86400. You might wonder what that means.

For someone less experienced, it may not be obvious that this represents the number of seconds in a day (24 hours multiplied by 60 minutes multiplied by 60 seconds).

The problem with magic numbers can be easily solved by declaring and explaining what they are.

If you want to use a specific parameter in your algorithm, explain what it represents in that context.

For example, if you have a parameter for a supplier, declare it clearly so that the reader understands its purpose.

This makes the code much more readable.

Now, let’s talk about comments.

The best comments are those that you don’t write. Comments often arise when the code is so complex that we realize we need to explain it.

These comments are usually a crutch for our inability to write clearer code.

If you feel the need to write a comment, consider whether you can rephrase the code to make it clearer instead.

For example, if you have a complex condition, instead of writing a comment to explain it, you could encapsulate that condition in a separate function.

This way, the code becomes clearer without needing comments.

Of course, we can’t ignore commented-out code.

When reading code, it can be frustrating to see large blocks of commented-out code mixed in.

It’s understandable to want to keep it just in case, but it’s better to remove it.

If you’re working on a project, use version control to keep track of changes.

Now, let’s briefly touch on code formatting.

There’s not much to say here, but poorly formatted code can be quite common.

Just follow the formatting standards used in typical projects, which are usually well-structured.

Finally, how do we write clean, good code?

We’ve discussed various factors to consider, including standards and other aspects.

Personally, I don’t usually write clean code right away. Robert Martin also mentions that he doesn’t write clean code immediately.

The process usually looks like this: we write some code, let’s call it "dirty," to solve a problem. We check that it works, and then we go back and refactor it, improving it iteratively until we’re satisfied with its clarity and structure.

Over time, this skill will develop, and it will become easier to write clean code.

That’s all from me. I hope it wasn’t too boring and maybe even a bit useful. Thank you very much!

Alexey, friends, I remind you that you can ask questions to the speakers in the Telegram channel, and there’s also an opportunity to ask from the audience.

We have Alexander who wants to ask a question.

Thank you for the interesting talk! I appreciate that you reassured us that it doesn’t come easily at first.

My question is: how does your company foster a culture of writing clean code? Knowing and being able to do it are not the same.

I’d say that people write differently. There are some external constraints organized by the company, like automatic configuration checks and tree views. However, these are still quite broad boundaries.

Within those boundaries, you can still write poorly. You can’t create something completely terrible, as the automatic checks will catch it, and reviewers will notice issues.

If you’re motivated and want to write well, you’ll do better than someone who is just going through the motions to meet the requirements.

So, to summarize, the answer is that there’s no strict enforcement, but there are checks in place to ensure quality.

I understand that the company applies automatic configuration checks and tree views, and you strive to improve.

Yes, we could always be more thorough than we currently are, but it’s a matter of internal motivation.

Thank you!

We have another question from Telegram. Grigory Shatrov asks: Alexey, do you use line breaks in single-line functions?

It varies. If I see that it’s becoming cluttered, I’ll break it up.

It’s clear that there might be contradictions between what’s written in "Clean Code" and the standards, as they don’t always align perfectly.

I usually prioritize clarity when reading. If it meets the standards but is still unclear, I’ll simplify it.

Thank you!

I don’t want to give the impression that every piece of code I write is perfect. We always work within constraints, and sometimes time doesn’t allow for it.

There are cases where the task isn’t worth the effort, especially if it’s a temporary solution.

And sometimes, you want to create something lasting, and you put in the extra effort.

Lastly, Alexander Tarasyuk asks: what if you don’t like a colleague’s code in a shared project?

There are two aspects to consider. On one hand, you can influence the overall culture of the company and share best practices.

On the other hand, there’s a principle from Robert Martin called the "Scout Rule." When you enter a module and see poorly written code, if your budget allows, improve it a bit.

Leave the code better than you found it.

If we all adopt this mindset, our codebase will become cleaner over time.

Thank you, Alexey! Let’s give him a round of applause. [Applause]