Repeating yourself? Wait! You could avoid the repetition.

In software development, there is this term Don’t repeat yourself. There are many posts which talk about it and terms like DRY, DRYness, WET, “write everything twice”, “we enjoy typing” or “waste everyone’s time”, and so on.

When you are repeating yourself, it’s a clue, an opportunity for you to do something about this repetition.

I’ll walk you through some of the examples.

As a developer, the first thing I was doing every morning was open the visual studio, get the latest code from TFS, build the dependencies (dependent projects), copy dll’s to the shared folder and build the main web project. I was doing this action daily in the morning. I saw I could have automated the process.

It was a clue! I created a bat file. The bat file was doing the above repetitive actions for me as soon as I start my computer.

In your case, it could be something else. It could get latest code from git, docker up, build containers and so on. Are you repeating yourself?

Whenever you see you are copying and pasting the bunch of HTML and CSS code to display a notification message. Just stop there! think about reusable HTML components, extract it and use it everywhere. Write once and use everywhere.

Whenever you see you are repeating the code to download CSV on multiple pages, then think about extracting it to a class, CsvContentGenerator? CsvDownloader?

Whenever you see you are repeating inline calculation?

 
if((totalStudentInClass - studentPresentInClass)>0){
    var message = "There are {totalStudentInClass - studentPresentInClass} absent students in the class";
}

Consider extracting it to a method or a variable.


var absentStudentsCount = totalStudentInClass - studentPresentInClass; 
if(absentStudentsCount>0){
   var message = "There are {absentStudentsCount} absent students in the class";
}

Whenever you see you are copying an email sending code from one project to another, consider writing a shared library.

Whenever you see you are repeatedly writing the validation messages in translation files. Consider writing the generic message in translation file and fill specific field name at runtime.

Check the support for it in your translation framework.


"EmailIsRequired": "Email is required".
"UsernameIsRequired": "Username is required".
"NameIsRequired": "Name is required".

// Instead of repeating, create generic message and 
// fill template-placeholder %{fieldName} with actual field name.
"FieldIsRequired": "%{fieldName} is required"

Whenever you see you are creating padding and margin styles and your app.css is growing.
Consider writing SCSS helpers, https://gist.github.com/jacurtis/30da4bf9a6c9b9b5cc0aebac512ca7c9.

Whenever you see you are writing repetitive if/switch case to decide and create a specific instance of a class. Consider using abstract factory pattern which decides and create the specific instance of a class for you.

We don’t know everything. It’s okay.

Whenever you see you are repeating something, I want you to stop there, think about it, there will be a clean solution. This could save your future time and code could be more maintainable.

In the software development field, patterns, practices, refactoring techniques and many more other techniques are already there to avoid repetition, use it.

You must be using the combination of key Ctrl+C, Ctrl+V million times a day. Next time when you press this combination, I want you to think about avoiding the repetition and ask yourself. Oh! wait! Can I do something about it? Can I automate this? Can I extract this logic to the method, classes, reusable CSS, js components, library and so on?

Is it time to re-name “Human resources” department?

Few weeks ago, I received an email from a recruiter. The title of the email went like, “Need immediate .NET resources who can join in Blah Blah.. time”. The email kind of triggered many thoughts in my mind. Am I really a “resource”? Is that only what I stand for? If I put in all efforts in my team and company’s success, will I still be a resource for the company? and so on…

We have been hearing this word “Human resources” for a very long time now. One of the companies I worked for hired college students from a campus in huge numbers. Once these graduates would join the company, there was a separate department named “Resource management group” who would look into how to harness these resources for company business. I was one of those graduate resource. For a very long time, I had the kind of feeling which you would have on seeing a huge farm of humans in the movie Matrix. In this movie, the machines would harness these humans for their survival.

It’s a common term in traditional program management to address, people, computers, cubicles everything as resources.  “Is the project delayed? Ok, no problem, put 10 more resources and complete it quickly.” We may have heard or even been a part of such conversations.

But, are we really resources? I’m not. I’m not a machine or a chair or a white board. I’m human. I have feelings, thoughts, ideas, knowledge. I get motivated, I get happy, I get sad, I have ups and I have downs. I don’t just type code. I create things, that help others, makes their life easy, things that make difference.

A company is not made by how fascinating offices they have, or how many computers they have. The most important asset for a company is its people, without it’s people, there would be nothing. Many successful companies originated in someone’s basement.

Google has moved away from the word “Human resources”. They call it “People operations”. And we all know the efforts Google takes in taking care of it’s people. And we also know the care it’s people take in keeping Google such a successful company.

I believe people in any company deserve more respect, not just for the work they do, but also because we’re humans. The culture of mutual respect, drives ownership and belongingness. These values can drive any company to great heights.

Introduce explaining variable

While doing pair programming with developers, I have experienced that some of them are hesitant to introduce the explaining variable. They worry more about other devs thinking about that extra variable.

Will it be redundant to have an extra variable? Well, let’s see:

Before

In the above code snippet (…even though it’s a simple one), checking file size against an arbitrary number does not convey any business rule clearly. You can’t predict easily about the meaning of ‘10000000’ or size whether it is in Bits, Byte, KB, MB or something else. One who visits this snippet needs to spend some time to figure out the intent.

Well, let’s introduce explaining variable and see if it helps.

Better way:

I know, I have increased the line of code here. However, don’t you think the introduction of explaining variable made it expressive and understandable?

Now it reads like:

When file size exceeds maximum allowed size (10000000 Bytes!), then just exit!

Another example:

Before

PHP code doing some matching on phone.

It’s really difficult for me when I read it the first time.

Better way:

Divided into multiple parts so that it could express itself very easily.

Now at least, you know that there is a regular expression for valid phone number pattern. It is used to determine if the phone number is valid or not and take appropriate action.

Introduce the explaining variable to convey your intent. This is one of the ways to express yourself via code.


What is “Google time”?

Software engineering and product development are different from other streams of business (manufacturing, for instance). Things are more predictable in manufacturing, specifically in the execution phase. But it is no so at any stage in product development, where you get to know the next challenge only once you solve the current one.

What has this to do with “Google time”? Many of us might be aware that employers give some time every week to their employees to work on anything they like. Most of the employees during this time spend time on their own learning or working on their own side projects. Many of the in-house tools and even products are born out of this activity.

But the main intention behind giving such “do-Whatever-you-Wanna-do” time to the employees in my opinion is not to churn out such side projects. The main reason and science of this lies in the “Queuing theory”. Less.works explain in great detail how the utilization levels affect the flow of value through the system. I will attempt to summarize it and put it in a context.

Imagine you have a highway and the vehicles are moving through with ease. Let’s say the traffic increases, vehicles gradually start taking more time to get through.

Each new vehicle coming on the highway gets added to the “Queue” and the time to get that vehicle through then is, can you guess?? As may predict it is linear, but it is not. It grows exponentially, until a certain point when you cant get anything out of the system, which means the response time goes to “Infinity” (mathematically). Such a curve is called M/M/1/∞ curve.

So the thumb rule is, when your size of inputs to the queue are random and when the time taken to process each input is random, then the system response can never be linear, it follows the curve we just described. This theory applies to many scenarios including server utilization for production systems and…… yes, you guessed it right, it applies to a developer’s day to day life as well.

How? as we know that in software development, we can never accurately predict the time it will take us to complete a task. We can only guess based on our experience. Each task gets done one after the other, in variable amount of time.

So let’s say that you, as a developer, is given a task each day of the week. There are 5 tasks you need to complete in this week.

On Monday, you are excited and start working on task A. However, it takes some more time in the end to test and deploy the functionality. You therefore, utilize some of the time on Tuesday to finish task A.

But wait, you already need to complete task B by Tuesday day end. Without wasting any time you get to work on Task B. Task B turns out to be tough one to crack, after you start working on it, you realize that you need some more technical help within the team to proceed. It turns out that you finish Task B on Wednesday.

On Thursday, you already have 2 tasks (C and D) in your plate. You start to feel the pressure now, and you are already thinking about multiple things at a time. On Thursday, your manager calls for a team meeting to discuss teams performance in last quarter, you lose half a day in the meeting (not to mention the context switch that comes along with it). You work on Task C, by sitting late in office and try to complete it.

When you arrive on Friday, you already have 3 tasks assigned to you which you need to complete by EOD. You realize that it is unrealistic for you to achieve it. This is exactly the breaking point, mentioned in the “Queuing theory”. Beyond this point of time, no matter how many tasks you keeping adding to “Your Queue”, they will take (mathematically) infinite amount of time to process.

I’m sure this has happened with most of us at some point of time in our careers. Linearity calculations do not work in software development. So how do we solve this problem? Well, that is precisely why good companies give their employees, some time to take control of their queues. Moving fast, compromises quality and increases technical debt. Most of the time, good employee’s, will utilize this Google time to either finish their pending work or to reduce the technical debt they introduced, when they had to finish things quickly.

There may be times when developers finish work quickly than estimated and may spend this time, learning or work on something else. Either way, it benefits the company, but as we just saw, these are the extra benefits. The main intention from management’s perspective is to induce the “Flow”, so that value get’s out of the system at a consistent pace.

Writing test for translation files

In the past, I had worked on different websites and app that support localization.  The user on these sites can work with the language of their choice and translations were provided on UI elements for selected languages.

When working with translation files for multiple languages, I found that there were instances when developers added translation text for English but forget to add translation text for languages other than English. That was a problem when a user chooses to work with a language other than English (He/she was provided with misleading text).

Secondly, there were issues due to duplicate translation keys provided by developers. It leads to incorrect translation due to overwriting (Misleading!).

I learned that adding the test for verifying these rules will help developers to identify the problems before pushing changes to production.

The simple react application is hosted on github: https://github.com/way2datta/translation-demo.

This sample app has support for English and Hindi language. The app has tests for verifying the translation files.

When the translation keys are present in the all translation files. The test runner display everything is well.

When I add translations in one language file and forgot to add it to another language file, tests start yelling at me.

Thus, the tests for translation files can help the developer to identify the issues related to translation files in development phase itself.

https://blog.beingcraftsman.com/datta/

Encapsulation


Encapsulation is the process of putting data and code (that operates on data) together in a single unit, which, acts as a protective wrapper for data and code. Access to the data is provided via controlled access (public interface).

Consider an example of a simple wristwatch.

Abstraction means to provide the simplest view of a complex concept (showing only the necessary part). So, in this case, it displays only time.

Encapsulation means not only provide the simplest view of complex concept (Abstraction!) but also hide and protect internal implementation. The end user cannot see how time is being calculated; what gives energy to the wristwatch; how the internal circuits are structured and so on…

The glass and plastic body forms a protective wrapper (Encapsulation) which hides the internal implementation details (hiding the complexity) and shows the current time (…only relevant part, Abstraction!).

Encapsulation gives access to modify the data via the controlled public interface. In this case, it’s a push button which is used to change/set the time.

From this example, it is clear that the two concepts are related. Without proper encapsulation, there would be no abstraction. Encapsulation not only helps a code achieve abstraction (shows only relevant functionality) but goes one step further and hides everything else, which is irrelevant to the user.

In essence, Encapsulation picks up where abstraction leaves off. In code, you will either have both abstraction and encapsulation, or you will have neither.

https://blog.beingcraftsman.com/datta/

Why giving meaningful names to things in programming is important

Everything in this world has meaningful names. It helps our brain to understand and remember the things very easily. It means less mental mapping.

Let us take real-world examples of meaningful names given to things like hand wash (of course, you don’t use it to wash your face), face wash, shaving cream, aftershave and so on.

Similarly, in the programming, everything needs to have a meaningful name because we as a developer spend our most of the time reading the code than we do writing it.

As a developer, our daily job is to give a solution to the problem at hand.

To solve the problem at hand, we sometimes create a project, an assembly, a namespace,  directories, class files, classes, fields, methods, other members, UI elements, their translation files, translation keys and so on.

All of these things should have the meaningful name so that they convey their intent and you realize what they are doing by just looking at their name.

Perhaps they answer all the big questions that you or future maintenance developers would have.

Let’s go through the following code snippet. It is written in js.

  downld(recs){ 
        const cols = ['Name', 'Age', 'Gender'];
        let d = `data:text/csv;charset=utf-8,${cols.join(',')}rn`;
        recs.each((r) => {
            const row = [
                r.get('name'),
                r.get('age'),
                r.get('gender')
            ].join(",");

            d += `${row}rn`;
        });
        const u = encodeURI(d);
        const lnk = document.createElement("a");
        lnk.setAttribute("href", u);
        lnk.setAttribute("download", "users.csv");
        document.body.appendChild(lnk);
        lnk.click();
  }

I hope you understood what it is doing.

The above example shows that a simple code snippet could be difficult to understand when meaningful names are NOT given to variables, functions and so on.

Now think about a project that has 100+ classes and thousands of lines.

Don’t you think it will be painful for the maintenance developer as well as an original developer to read it again in the future?

This could have been easy to understand when good names would have been given.

Let us try to give the meaningful name in the code snippet.

  downloadAsCsv(users){ 
        const columnNames = ['Name', 'Age', 'Gender'];
        const csvHeader = `data:text/csv;charset=utf-8,${columnNames.join(',')}rn`;
        let csvDataRows = "";
        const newlineAndCarriageReturn = `rn`;
        users.each((user) => {
            const currentRow = [
                user.get('name'),
                user.get('age'),
                user.get('gender')
            ].join(",");

            csvDataRows += currentRow + newlineAndCarriageReturn;
        });

        const csvFileContent = csvHeader + csvDataRows;
        const encodedUri = encodeURI(csvFileContent);
        const newlink = document.createElement("a");
        newlink.setAttribute("href", encodedUri);
        newlink.setAttribute("download", "users.csv");
        document.body.appendChild(newlink);
        newlink.click();
  }

Now, do you think it’s a little better than the previous version?

The good names encourage you to write clean and good code. You can go one step ahead and split above function.

    downloadAsCsv(users){
        const csvFileContent = this.generateCsvContent(users);
        const encodedUri = encodeURI(csvFileContent);
        const newlink = document.createElement("a");
        newlink.setAttribute("href", encodedUri);
        newlink.setAttribute("download", "users.csv");
        document.body.appendChild(newlink);
        newlink.click();
    }

    generateCsvContent(users) {
        const columnNames = ['Name', 'Age', 'Gender'];
        const csvHeader = `data:text/csv;charset=utf-8,${columnNames.join(',')}rn`;
        let csvDataRows = "";
        const newlineAndCarriageReturn = `rn`;
        users.each((user) => {
            const currentRow = [
                user.get('name'),
                user.get('age'),
                user.get('gender')
            ].join(",");

            csvDataRows += currentRow + newlineAndCarriageReturn;
        });

        return csvHeader + csvDataRows;
    }

I hope you agree with me that meaningful names will make everyone (including you) more than happy after reading it.

In case of methods, when you failed to give a name to a method, you may realize it’s doing more than one thing. It is really helping you.

Even when you are able to give a meaningful name to a method, you may realize that the method doesn’t belong to this class.

I often realized that this practice of giving meaningful names helped me a lot about understanding the solutions, separations of concerns and even responsibility of the classes, methods, assembiles and so on.

Suppose your boss comes to you and asks you to fix value against gender column in generated CSV (from above example) on priority. Instead of debugging and finding the location of the code, just ask IDE to show you “generateCsvContent” routine.

Thus, help your IDE to help you by giving meaningful names to everything in programming so that you can figure out everything very easily.

Consequently, giving meaningful names will help you in some way or other.

When you revisit your code after 4 hours or 4 weeks, or 4 years, and you think you could give more meaningful names now then

DO NOT hesitate to rename it if it’s not breaking anything and has less impact on other features.

REMEMBER!

https://blog.beingcraftsman.com/datta/

Abstraction

Abstraction is the ability to work with the concept/idea while safely ignoring some of its details. Rather, handle different details at different levels.

Take an example of a simple fan regulator. As a consumer of it, I can focus only on regulating the speed. Here, changing the speed via the interface (knob) is the concept while I will ignore other details like an internal electronic circuit that consists of a diode, capacitor, resistors, DIAC, TRIAC and so on..

Internal of the fan regulator.

Thus, Abstraction is the process of showing only the relevant details with which consumer can safely work with.


Real-life analogy

When we consider a laptop as aggregate, it is an abstraction of its various parts, like a keypad, touchpad, screen, motherboard, hard-disk, processor, etc.

Similarly, A keypad as a whole, in turn, is an abstraction of a particular arrangement of keys and internal wirings.

This way, abstraction allows you to take a simpler view of a complex concept.


Similarly, in software development, abstraction should manage the complexity of the software design at a different level. A good abstraction should lead to a good (less complex) software design.

In languages like C++, Java, C#, we can achieve abstractions via abstract class and interface.

Good programmers create abstractions at the method level, class level, interface level, namespace level, and assembly level —in other words, motherboard level, keypad level, and laptop level—and that supports faster and safer programming.

As programmers, we need to provide the right level of abstraction in accordance with the need of the end consumer.

Method cohesion

Image credit: https://www.slideshare.net/agileee/lightening-talk-software-craftsmanship

The Method exhibits high cohesion when a method performs one and only one operation and do what their names say they do.

If they do anything else, they are less cohesive and poorly named.

Examples of highly cohesive methods:

  • GetProductName()
  • PrintBarcode()
  • ToLower()
  • CalculateAge()
  • CreateUser().

Cohesion – the action or fact of forming a united whole.

Cohesion in the object-oriented programming tells you whether the members (states and behavior) of the class works towards a common goal or fulfills the central purpose of the class.

See the class shown below.


class Program
{
 
public string GetData(string fileName)
 {
    // Read file content
 }

 public void PersistDocument(string documentText, string targetFileName)
 {
    // persist document into given file
 }

 public Document ParseInput(string input)
 {

    // implementation goes here.

 }

 public void View(BankAccountStatement accountStatement)

 {

    // implementation goes here.

 }

 public void DownloadAsPdf(BankAccountStatement accountStatement)

 {

    // implementation goes here.

 }

 public void DownloadAsCSV(BankAccountStatement accountStatement)

 {

    // implementation goes here.

 }

Now, look at the methods in the Program class. They are clearly doing the unrelated job. I did not see any connection between the file read, file writes, parse Input and view account statement, download bank account statement as CSV or pdf. Well, I did not see the class has a central purpose.

The program class is violating the single responsibility principle. The program class looks like a utility class that contains miscellaneous (unrelated) methods. It’s like a silver bullet for every problem.

These methods should be reorganized into more-focused classes and should work towards the central purpose and should extract them to classes that should do

  • File read and write.
  • Parse document
  • View and download bank account statement.

Hence we need to create separate classes so that they work towards one and only one purpose. The program class can be divided as shown below.


class FileDocumentStorage
{
  public string GetData(string fileName)
  {
     // implementation goes here.
  }

  public void PersistDocument(string documentText, string targetFileName)
  {
     // implementation goes here.
  }
}

The FileDocumentStorage class reads data from given file and stores the document-text into the target file. It has only one purpose (single responsibility) that is file manipulation. The methods are more related to each other.


class InputParser
{
  public Document ParseInput(string input)
  {
    // implementation goes here.
  }
}

Similarly, class InputParser parses the input string and converts it into the document object.

class BankAccountStatementForm
{
 public void View(BankAccountStatement accountStatement)
 {
    // implementation goes here.
 }

 public void DownloadAsPdf(BankAccountStatement accountStatement)
 {
    // implementation goes here.
 }

 public void DownloadAsCSV(BankAccountStatement accountStatement)
 {
    // implementation goes here.
 }
}

Lastly, BankAccountStatementForm class views the bank account statement, downloads the bank account statement as PDF or CSV. It fulfills the central purpose of Viewing the Bank account statements.

Now the refactored classes` methods are working towards the central goal and look related.

You can see your brain can easily remember or understand everything the code does.

High/Strong cohesion is always preferred it reduces the complexity of the code by designing easy to understandable classes that obey the single responsibility principle.

Eventually,

Cohesion means that the state and behavior of the class should support a central purpose.