August 27, 2020

Things I wish I knew when I began programming

I wish I knew this when I began programming

Any experienced programmer has their agenda of “I wish I knew this”.
I want to share with you my agenda.

Version control

That’s the first thing that pops into my head.
I’ve read code that I wrote before 2010 - as a kid and a totally amatuer - I had all kind of files/folders lying around with “Ver1”, “ver2”, etc…
As a beginner i’d definitely advise myself to learn a version control tool.

A common tool in practice is GIT. Find it here!

You can upgrade your knowledge even more with Github - The most common soure for repositories in the world!

Team work

You can’t learn team work by working by yourself silly…
Today, the collaboration opportunities are everywhere!
Multiple platforms allow you to find and collaborate on open source and inner source projects - Github, Discord, Slack, etc…
Pick a project - speak up, ask questions, show yourself to the world.

Learning to collaborate with people and work on the same code is meaningful and will make you better as a programmer
And a better team member!

“If you want to go fast, go alone. If you want to go far, go together.”

Single responsibility

From the SOLID principles - I think the most important is the ``Single Responsibility`.
The reason:

It forces you to split the logic into samller logical units and maintain one responsibility at a time.

This is beneficial when solving bugs.
When you are bug hunting inside files that are 6000-15000 lines long, you’ll probably won’t have any fun.
The alternative is to split the unit into smaller files - so if a code has a bug, you know where it is and what unit is related to faulty code.

Coupling and Cohesion

Coupling- The degree an entity is connected to another component.
Cohesion - The degree an entity is correlated to another component.

A good API - Low on coupling and high on cohesion.

High coupling

1
2
3
4
5
6
7
8
9
public class FruitSlicer
{

}

public class B
{
private FruitSlicer mSlicer;
}

Low coupling

1
2
3
4
5
6
7
8
9
public interface ISlicer
{

}

public class B
{
private ISlicer mSlicer;
}

High coupling means that B is composed of the details - a fruit slicer (class FruitSlicer).
If we need another kind of slicer we’ll need to manually add it, cast it or replace it which activly introduces changes into the class.
Most of the times I see code like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

public class B
{
private FruitSlicer mSlicer;
private MeatSlicer mMeatSlicer;

public void Slice<TFood>(Type t, TFood food)
{
if(t == Type.Fruit)
{
mSlicer.Slice((Fruit)food);
}
else if(t == Type.Meat)
{
mMeatSlicer.Slice((Meat)food);
}
}
}

THIS IS BAD CODE.
How to fix this?
Interfaces are abstract, easier to implement and construct - if we implement a FruitSlicer, MeatSlicer or anything else, it’s easier to replace.
Thus comes into the agenda one more guidelines:

Program to abstract interfaces, not classes.

High Cohesion

1
2
3
4
5
6
public interface ILogger
{
void Info(string message);
void Debug(string message);
void Error(string message):
}

The API defines strict methods of writing different levels of logging - thus the high cohesion between them.
They all responsible on the level of the log message.

Low cohesion

1
2
3
4
5
6
public interface ILogManager
{
void Info(string message);
void SaveToFile(string path);
void SendTo(string ip);
}

Managers are sort of an anti-pattern and should be used with caution.
Here we have 3 responsibilities: Writing logs, save the log into a file and sending it to an IP.
Maybe they are all corellate to Logging but the responsibility is split into 3 - file IO, networking IO AND logging managment.

If you describe a class with “AND” in its description - “That does X and Y and Z”.
It means you need to split it.

True meaning of “Oriented programming”

All tutorials and guides I read about object oriented programming usually focus on the practical level - How to write classes, how to do inheritance, how to encapsulate and how to use polymorphism.
They never mention the true meaning of orientency.

Oritentency means that our basic building block is X.

Function oriented programming has its basic building block defined as Functions!
Object oriented programming has its basic building block defined as Objects!
How about data oriented programming? Of course, it’s Data!
You get the pattern here.

What’s the meaning?

Let’s design a small alram system for a house because it’s easy to imagine the physical components as objects.
If we design it with OOP in mind, we use an object as a basic building block.

What is an object? An entity with state and behavior.
Some objects may only have data - we call them models.
Some objects may only have behavior - we call them services.

Let’s start with composing an alarm controller:

1
2
3
4
5
6
7
8
9
10
11
public interface IAlarmController
{
public void TurnOn();
public void TurnOn(IEnumerable<Location> locations);
public void TurnOf();
public void TurnOf(IEnumerable<Location> locations);

// ... Variation may apply on what exactly we need.

public event Action<Room,TimeStamp> Alarmed;
}

A controller usually has a control panel and holds information, so entities like:

A location is a physical place where we have sensors for detecting anomalies.

1
2
3
4
5
6
7
public class Location
{
private IList<ISensor> mSensors;

public string Name {get; set;}
public GUID Id {get;set;}
}

A sensor is a physical device that can generate a report,
If we look at what kind of sensors we would want:

I hope this simple example illustrates the concept that objects are schemes for entities.
Behavior and Data work together but sometimes they are apart as well.

Modeling objects is a necessary skill for an excellent OOP design.

Don’t be a code ninja

❌ Don’t:

1
var stringified = (isFlag? mResults["Yes"].Active? "The result is active" : "The result is not active" : mResults["No"].Active? "Active result is denied" : "Request denied");

✅ Do:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var result = isFlag ? mResults["Yes"] : mResults["No"];
var isActie = mResults.Active;
if(isFlag && isActive)
{
return "The result is active";
}
else if(isFlag && !isActive)
{
return "The result is not active";
}
else if(!isFlag && isActive)
{
return "Active result is denied";
}
else
{
return "Request denied";
}

After I’ve written my first example It took me some time to grasp what I was trying to achieve.
Sometimes - even code we write like ninjas is hard for us to understand so simplify it even though it looks more dull.

Measure twice, cut once

It’s easier to erase a class from a sheet of paper than to reconstruct the code

I was teaching this guy how to start a software project from scratch.
I asked him to use Word or any other tool to design the software first and then open visual studio and write the code.
Of course he wasn’t able to do it,
After some time he just told me “I can’t, I need the Visual Studio”.
So I allowed him to write some code.

The lesson to learn - junior developers are so caught up with details they forgot to think first on what they need to craft.

Sometimes it’s not their fault - they don’t know the API or what types the code use.
For this purpose I have a solution with 30 different projects that most of them are labeled “TestX” , “ConsolpeApp”, etc…
If you aren’t sure of the API it’s ok to use a simple project to test few lines of code -
But never use it to write the whole code just to test it.
POCs (proof of concept) are ok.

Always design your code before you construct it, it saves you a lot of time later on.


Proper software construction and practices isn’t something you’ll learn by yourself.
The industry always comes up with new practices - keep and open mind and always learn.

Thanks for reading!

על הפוסט

הפוסט נכתב על ידי Ilya, רישיון על ידי CC BY-NC-ND 4.0.

שתפו את הפוסט

Email Facebook Linkedin Print

קנו לי קפה

#Software#Beginner#Programmer