Communicating at Code

Gugun
13 min readApr 3, 2021

Software Engineering today faces tons of requirements, involving a lot of engineers, various engineering practices and many disciplines only for bringing value to users accessible in a simplest way. The consequences will produce millions lines of code and complexity in production. Sustainability is another challenge. Bringing application live in production safely doesn’t mean a mission is completed. Making sure that application are always alive and ready to serve users is another important job to do. Improvement becomes routine jobs of software engineers to make application better, faster and capable to serve more and more users.

As a Software engineer, we understand that codes have an impact on users, teams and beyond that, impact to sustainability of the company businesses. “Just” running code is not enough, readable codes is needed not only to serve users but also make teams productive and make your application (and also your company) sustain. One day, somebody in your team needs to read code to complete assignment either calling function, fixing bugs or improving features. When the day comes, readable code becomes very important, otherwise it will be a nightmare. Clean and readable code is not talking about running or not running. It’s more. It’s talking about how you give good legacy to your team. Like a novel, you write code not only for yourselves but also sharing knowledge, understanding, approach and solution in your mind to another engineer at code.

While working in a team, communication is always important. A lot of problems could be solved only by improving communication effectively, otherwise problems also could come because of communication failure. In the software engineering world, a software engineer plays a very critical role. Applying effective communication between software engineers is also critical, as critical as the position. In the different world, to make people understand what you have done, you need to create pages of reports or long descriptive documents. Software engineers have different styles of communication. They use their code to communicate with each other. It’s simple but powerful as long as consistently applied, at any single line, at everyone. In this article, I call it Communicating at Code.

While working as a software engineer, I experienced several things that may help software engineers to improve communication with other engineer in team effectively.

Convention

At the very basic step, it’s very important to make everyone at the code base have the same style in writing code. Fortunately, programming languages usually have coding conventions to make coding implementation standardize in terms of style. Java, Python, PHP, Go, JavaScript or many others have it.

Thanks to people who spend a lot of time contributing to this. But Again, it’s more about style instead of syntax. Writing code in non-standard style is not immediately producing errors. The impact in team would be long term, so, it needs maturity and awareness from software engineers to follow by understanding of benefits for others. Senior Engineer, lead or manager should keep reminding the team, and it would be better if it becomes engineering culture in company. Several IDE come with feature auto format or style checking. It’s powerful to remind each software engineer to write code based on style standards.

So far, we talk about standardized coding style. It still doesn’t touch the understanding of logic and knowledge communication at code yet. Unfortunately, writing code in good style is not enough to make other engineers understand what you have done and what they have to do to continue or improve your jobs. We need more.

System Design

While working with many people in a team at the same code base, we need to put everyone at the same track of implementation. System design is critical to define the track. Like a building, system design bring foundation of the building. Everything that build after would be built on top of that. When do we need to define the structure ? like building a house, the best time to build foundation is at the beginning of the process; early days of products or projects. But sometimes, at an early phase of development, not all requirements and complexity are captured. So, improvement on the structure is always open at any phase, but changing the structure while projects or products live in production and using by users always produce another complexity. Right strategy, deep analysis and change management must be considered carefully to mitigate crashes in production.

We’ll see on the simple example. Let’s say, we create a web application, then we will need web pages as a user interface. Users input something in form and submit it to the back-end to be processed. From this very short story, we can see the flow grouped in two “islands” of complexity; the front-end and the back-end. Complexity in front-end considers showing user interface, client based validation, parameters mapping, front-end to back-end communication and many more. On the other side, complexity in the back-end considers business logic implementation, calculation, accessing persistence layer like database or files, logging, batches processing and many more.

Software engineers have so many options to implement logic both in Front-end and Back-end. It may put it in a single point of implementation for each, or merge front-end and back-end in a single point of implementation or separate it into multiple classes. There are pro-cons before we pick one of the options. But, no matter what option is picked, the objective is to avoid spaghetti code and put everyone on the same track by providing common structure.

The discussion usually is started with defining layers that we need to cover all possibilities in implementation. In this stage, we can use our own segregation and definition, adopt Software Design Pattern or combine both of them. In our case about web applications, for example, we may adopt MVC (Model View Controller) Design Pattern as the main structure. While doing an implementation project, we can see that the model at the back-end is a very complex layer to be handled only by one single point of implementation. Business logic, db access, file access, logging, batch process are inside there. We may need a sub layer inside a model like persistence layer to handle db, file and caching and service layer to represent business logic. Otherwise, it may be put in utility classes to support all over layers. After defining layers, the next thing that needs to be clear is how layers communicate with each other; what’s input and what is the return value.

This flow starts with sending parameters from user input (browsers) to controller. Controller will do its jobs to mapping data or doing some check for data validation. Then, the controller will call a service that contains business logic with spec as parameters. Spec is actually a data type containing all from input and may be an additional variable that is needed by business logic implementation. In case of accessing a database or file is needed, service will call a data access layer with data as the parameters. Data is actually an object that represents an accessed table or information inside files. After all logic is completely in service, service will return the result back to the view layer as a standardized object, in this case using JSON. then, the view will render the data to be available for the user in the browser.

MVC is not the only one pattern to help while building the structure. MVC is only talking about communication between logic and serving data to users to segregate responsibility and reduce complexity. But, there are so many problems in main flow that may be common in implementations like Dependency Injection, Object Pool, Proxy or Factory to produce objects based on parameters. All of these can be assembled to have full structure fit with the requirement. By Applying design patterns which are common, we can take advantage while introducing the structure to other software engineers in the team. Design patterns are usually well known in the software engineering world and have many references available to read on the internet, even books discuss it in detail.

The story so far is a discussion about philosophy. How about the implementation ? Luckily, there are so many options available in the market ready to use to implement structures based on design patterns either open source or commercial. It’s called application framework, more specific for web (MVC) is also called web application framework or web frameworks. Pros-cons always happen when there are many options available to choose. But, defining structure and flow is very important to understand our needs, later on, choosing an option could be easier.

Self-Explanatory Name

Logic Implementation consists of a lot of variables, classes and functions, then interaction one class with the others. It will be helpful if it has self-explanatory names. Defining names to be self-explanatory sounds simple but, believe me, it’s really not easy. It requires understanding of system design, technology stack, data, and logic business behind the application. From the system design, we can understand the position in application big picture either business logic implementation, parameters mapping, validation, accessing data, or others. Understanding technology stack produces standard terms and also the context of applied technology. Using RDBMS, we know about insert, update, delete and select terms. It’s different if we store data in files, it may use the term read or write. It’s also different if we use cache, data stream, message queue or others. So, different technology stacks produce different names. Business logic and also data for sure gives important context about what problem is gonna be solved. Like technology stack, business logic also brings several terms that are able to be used in names like register, reports, generates or many more. Data usually represents nouns and business logic represents in verbs. Using these ingredients, we can define self-explanatory names either variable, classes or function then strung it together becomes a complete story at code.

As an example, let’s say the web application that mentioned on the previous part is about COVID-19 vaccine questioner form.

We have one page called questionere.html. In this page, there is a form and button submit. After user fill the form, then press submit button, application will send information inside the form to the controller. do_save method is the one that handle this request. Here, i use do_** convention to handle data submit / post request in the controller, another example like do_delete, do_export_report, etc. The parameters are what user input in form, in this flow called form as parameter do_save. Controller may have several process to do; validation and mapping form request to spec (standard object to call logic layer). Another convention may be applied for another purpose, for example, query no of data with prefix list_**; list_questioners, list_users, etc, or query specific data with prefix view_**: view_user, view_questioners, etc.

Controller will call logic layer with save_questioner as the entry point. The parameters is object spec. From this name, we can understand that the main purpose of this function is to save information that passed from form to database. In logic layer, we can choose naming that represent process in business logic like save, generate, register then combine with specific object / data that has impact like save_questioner, generate_report or register_user.

Logic layer function will call several method in data access layer like select_questioner_by_param for selecting data to check data availability, insert_questioner for inserting new data if data not available yet, and update_questioner for updating data if the data is already exist. The parameter that is passed to data access layer is data. Data is object that represent table in database. In this layer, we can choose term based on technology used in this layer, in this example we assume using RDBMS, we choose term like select, insert, update or delete then combine with the data relate to the process like select_questioner_by_param or select_questioner_by_id, delete_questioner or insert questioner.

After saving process is done, save_questioner return object contains saving information like status or message, and after that, controller will map it into JSON object to return to pages. At the end flow, page html will show the result, in this example through component message dialog.

Comments

Self-explanatory names give brief understanding to software engineers about code, either functions, class or variable. In function, we only see parameters (and also the type), very quick view based on names and return type. But, sometimes we need to explain more to make it clear like parameter purposes, possibilities values, logic explanation and the result. In-Code documentation is helpful to answer that kind of question.

Like we discussed before, class & variable usually is a noun, many of them related with object, data and terminology in the context of business logic. Sometimes, we need to explain more about the terminology. For example health_status has different understanding in the medical world and system monitoring world. In-Code documentation can explain more about it.

In programming language like java, data type is mandatory and explicitly exposed together with variable or parameters. so, it’s easy to read and understand what type should be passed to function. but, several language like python or JavaScript are allowed to define variable without specify data type. to make it clear, we can use In-Code documentation to explain about data type parameters. not only about type, the explanation also can be used to share what possible value to pass as well.

When we publish an API, documentation is very important to communicate with external parties that need to call our API. As we know, it’s always open chances API to update, fixing and also publishing new API. Updating API means updating documentation as well. Creating documentation in word or excel separately produces redundancy (and also boring) jobs. To optimize this process, In-Code documentation could be solution. While you make coding, you update documentation as well. It’s not only for sharing to your pairs but also benefit to confirm your understanding about your function. On the internet, we can find a lot of tools that can help software engineers to generate good format from In-Code documentation like Java Doc, Doxygen, Swagger or many more. Some IDE also have built-in features to handle this.

Sometimes brief description and explanation is not enough, software engineer still needs an example of how to utilize function for solving their case. We can add example to execute the function in the In-Code documentation.

Commit Message

While working in a team, we need a place to collect and consolidate jobs in one place. I usually call it a code repository like git or SVN (subversion). We are working on our workspace, once it is finished, we need to submit it into the code repository so that other software engineers can see or merge with your changes. When submitting a collection of changes, we need to write a message to give context to other engineers what changes about. Commit here is like a checkpoint that contains a summary about the changes. From this, people that read your message can link problems with your changes, and in more detail, then can check what changes are related with. Writing commit messages is not the same with description of changes, it’s more about summary of your changes. In the context of communication, a meaningful commit message can help to understand what changes and the impact to codes.

Clear commit message also can help team to understand the history changes. It’s really helpful while solving problem or bug fixing. Not only about the changes, commit also record when and who make the changes. It’s important when we have to fix something but need to confirm about logic, so we can contact the engineers.

Code Review

So far, the point is talking about you and your code on your laptop. To make sure that what you write can be understood by others, and to mitigate errors delivered to production, code review could be a solution. In this process, you will send your changes to your pair to be reviewed. Actually, the main purpose of this process is to make sure that the code is bug free. But, on the other side, this review also could be an indicator how the other people understand what we have done. By this approach, code review will be wider than only checking running or not running code, but also level of understanding about the code and completeness of documentation. Almost impossible we can define level of understanding about yourself, so we need other engineer to make review and give feedback.

Conversation between reviewer and requester also will store in repository, so later on, we can refer back to this conversation to understand more about code and reviewing process. We can contact the requester or reviewer directly to confirm our understanding, if we have to solve problem relate with their code.

Finally, we are on the last part of the article. Like what I mentioned at the beginning of this article, we are not talking about running or not running. Its talking about readability. So, all of this stuff need consistency and shared awareness. Some tools may help but the most significant key to success is discipline and consistency in team.

Also, all of this stuff needs time and effort to apply. Sometimes we need to be fast to follow the market or fit with timeline project. Of course, the priority is delivering features. These points is like investment, we can feel the benefit in the long run. One your features is delivered, you can back to your code and fill the gap to make your code clear. this is not ideal, but better than you leave the spaghetti code to your team. so, to deliver on this level, commitment and (again) awareness of the engineers play very important roles.

Last but not least, All of this story should be well documented and accessible for everyone. One of the best places to store this information is at README.md in the code repository.

Finally, all of this point is refer to my personal experience while developing application. Any idea or discussion are welcome to enrich my point of view and also this article. So, Enjoy.

--

--

Gugun

Software Engineering | Data Science | Machine Learning | Energy & Petroleum | Coffee