Software Engineering vs Coding
Tags: architecture, healthydebate
Published: 2020-05-31 13:30:27

Before taking about the differences, let's first talk about what is coding and what is engineering.

When creating a software, you will have to answer two important questions,
- What to write?
- How do I write it?

To illustrate these questions, let's start with an example. let's assume you are trying to make a calculator app. You want the app to look and behave like an actual simple calculator. You have a clear vision in your mind and you know exactly your objective.

You open up an IDE, start a new empty project, then comes this moment where you ask yourself... what to do now?

This is the **what** part, where you try to figure out an architecture for you application. I have always found this part to be the hardest. This is software engineering, the first and most important step of software development.

Let's say you decided that you are going to make a static class that implements all the sub-tasks of a calculator as follows.
```cs
public static CalculatorLogic
{
   public int Add(int x, int y);
   public int Subtract(int x, int y);
   public int Multiply(int x, int y);
   public int Divide(int x, int y);
}
```
Then you will just create the UI of your calculator that has all the necessary buttons and the UI code will use this static class to fulfill the required functionality. Pretty easy.

Now comes the second part. You have a punch of unimplemented functions and ask yourself... how am I going to implement these ?

The **how** part is the coding part. it generally depends on your coding and problem solving skills as well as your fluency with the programming language that the application is being made with. You know clearly and precisely your inputs, outputs, and what needs to be done, you just think about how to translate your thoughts into code. You can test your code once you are done with it to see if it does what you expect it to.

I always find the **how** part to be the easiest. Coming up with an architecture is always harder and task more energy from me especially when you have a much more complex application with bigger requirements. 

At this point you know clearly understand what is engineering and what is coding. Although at some cases coding may actually be more difficult than engineering, engineering is extremely important and the life of your application deeply depends on a good architecture. but why?

Let's say that the requirements of the calculator app has changed, now you are required to let the user type compound equations and output the answer only when the user presses the equal button; for an example, the user would enter `2+2+(3*4)` the presses the equal button and your application will output `14`.

Let us consider two ways to solve this problem. 
- The first solution is to throw all the old code in the trash and write one single function that processes the string and returns the final result.
- The second solution is to keep all the existing code, and make another class called `StringProcessor` "I am not soo good with names" that looks like this
```cs
public static StringProcessor
{
   public static int Solve(string expression);
   private static ExpressionTree Digest(string expression);
   private static int Evaluate(ExpressionTree tree);
}
``` 
The function `Solve` would take the string and give it to `Digest` which will process the string and create an expression tree of this expression "I will not go through the details of this because it deserves it's own post" then `Solve` will give this tree to the `Evaluate` function. The `Evaluate` function will then go through the tree and every time it needs to do some arithmetic operation "like addition", it will use the functions in `CalculatorLogic` class we created earlier.

The second design is much better than the first because,
- We separated the string processing logic and the arithmetic operations logic to keep the code simple and readable.
- You could tell what is happening here by just looking at the functions without going through their implementations.
- As the functionality is spread across multiple functions, you can easily have a team of developers working concurrently on this project
- You can easily extend this code to support more operations like powers. All you have to do is add a power function in `CalculatorLogic` then do small modifications to the `StringProcessing` functions to accommodate powers.

The first design, however
- Forced all the code in a single giant and complex function
- Only one developer could work on the project. Multiple developers working on the same function will cause soo many problems that it is faster to just let one developer do it.
- Adding functionality to this code means understanding the complex logic of the single function and attempting to insert new logic into it, which will make it even bigger and harder to maintain.
- If you just looked at the classes and functions, you will be completely clueless as to what is happening here, and you will be forced to trace the code or ask the developer to explain it for you.

Bad architecture can kill a project even before it is released. The hardest thing about architecture is that there is no clear indication of right or wrong. Only time will tell you if you took the right decisions or not.

Coding, however, you have clear inputs, clear outputs, and a clear measure of whether or not your code is right or wrong "Unit tests". 

Consider learning about software architecture and design, and always try to come up with the best architecture possible in your project to develop better engineering skills. It is a very important skill that you have to learn when working with large and complex applications.

**Side note**: the architecture of `StringProcessor` has a problem; whenever a new operation needs to be supported, you will have to modify the `Digest` and `Evaluate` functions. As the project grows, these functions will become fairly complex and it will become difficult to add new functionaliy. Can you propose a better architecture that scales better?