Objects and Data Structures – Data Transfer Objects

The final type of data structure that we will look at is the Data Transfer Object (DTO).

What’s a DTO?

Like the name says, the main purpose of a DTO is to transfer data. In it’s purest form, a DTO is a data structure that has only public properties, and no methods of any kind.

When are DTO’s used?

There are times when different parts of a system, need to communicate. Usually one part needs to ask the other part to do something and get a value in return. This is where DTOs shine. All of the data that is required either to make the request or to give the answer is packaged into a DTO before it’s sent.

One very common example of how DTOs are used is web APIs. When a request is done to a web api, usually the request is put in a DTO that is serialized and sent as JSON to the server, the server’s answer is also sent as JSON and then is deserialized into a DTO on the client side.

Benefits of using DTOs

One benefit of doing this is that it’s explicitly stated that there is a relationship between all the values stored in the DTO, and the name gives a clear indication of what the data is representing.

Another benefit is the encapsulation that DTOs provide. Different layers of a system, or even different systems can be written in totally different programming languages, and as long as they agree on the operations (and DTOs) that they will use, everything should work withouth problems.

Objects and Data Structures – The Law of Demeter

How much information about one object should another object have? Should an object be able to access the inner objects of another one?

The law of Demeter

Simply put, the Law of Demeter says that an object shouldn’t have knowledge of the inner workings of another object.

A method in an object should only have access to:

  • itself
  • the methods parameters
  • objects created inside the method
  • the objects that are directly inside it
  • global variables

The following examples doesn’t follow the Law of Demeter

objectA.ObjectB.Method();

This example follows the Law of Demeter

ObjectA.Method();

Why does this law exist?

It should be clear by now, that one very important goal of writing clean code is to make modifying software easier and less error prone. When objects do a good job of hiding the way they work, changing them is a lot simpler.

 

Objects and Data Structures – Objects vs Data Structures

An Object and a Data Structure are not the same thing.

What’s the difference?

An object hides its data behind abstractions and data objects. When dealing with an object, we know what it can do and can see its public properties, but we don’t really know how the data is stored, or how the object works. Data structures hold data and provide basic operations that essentially allow you to put data in them and get it back.

Although Object Oriented Programming (OOP) is the norm, there can be cases where a procedural approach using data structures is more convenient.

An example using shapes

Think about a program where you want to be able to calculate the area of a shape. If you use a procedural approach, then you would code it this way:

public class Circle{
  public Point Center;
  public double Radius;
}

public class Rectangle{
  public point TopLeft;
  public double Height;
  public double Width;
}

public class Geometry{
  private const double PI = 3.14;
  public double Area(object shape){
    if (shape is Circle)
      return PI * shape.Radius * shape.Radius;
    else if(shape is Rectangle)
      return shape.Height * shape.Width;
  }
}

Using an OOP approach it would be this way:

public class Circle : Shape{
  private const double PI = 3.14;
  public Point Center;
  public double Radius;
  public double Area(){
    return PI * Radius * Radius;
  }
}

public class Rectangle : Shape{
  public point TopLeft;
  public double Height;
  public double Width;
  public double Area(){
    return Height * Width;
  }
}

Handling Changes

In the procedural example, if we want to add new functions, all we have to do is modify the Geometry class. There will be no need to touch any of the shape classes. If we want to add a new shape then we will have to modify the Geometry class as well to account for the new shape.

In the OOP example, if we want to add a new shape, all the other shape classes can stay as they are, but if we want to add a new function, then all of the shapes will have to be updated.

Which approach to use?

It depends on your needs. If the functionality doesn’t change a lot, but shapes change constantly, then OOP is best. If there will be no more shapes added, but the functionality changes constantly, then the procedural approach would be more convenient.

Your requirements will determine the best solution.

 

 

Objects and Data Structures – Data Abstraction

Object Oriented Programming (OOP) is a programming paradigm in which we use real world concepts or objects and create abstractions that will represent them in our software.

Data Abstraction

When we create an abstraction to represent a real world concept or object, we have to decide what that abstraction will expose and what it will hide (private fields, public properties and methods).

Why does the concept of public and private exist in OOP? Because there are things we don’t want our objects to share with other objects. We want our abstractions to expose to other objects the things that they can do or the data they offer, but not tell others how they do them or how that data is stored. Those details are private and should only be known to the object itself.

An example of a good abstraction

Think about a cell phone. Most people have no idea about how their phone works, yet they know very well how to use it. The technical details that actually make the phone work are private and known only by a few people, yet everyone knows that they can store their contacts in it and make phone calls with it.

A good abstraction tells exposes what an object can do, but hides the way that it happens. This makes changing the private aspects of the abstraction invisible to the user of that abstraction.

When a new model of your cell phone comes out, it doesn’t matter if the technology behind it is the same as the one you have or it’s something completely different. As long as the public aspects of it are the same, you can use it just as well as the one you have now.

Good abstractions expose what an object can do, but hide the way it does it.

Formatting – Horizontal Formatting

What is the maximum length for a line of code? A long time ago, monitors were only capable of showing only 80 characters per line so that was the limit. Currently, with widescreen monitors and small fonts you can have lines that are definitely way too long. According to the book clean code, most lines of code tend to be around 40 characters and the maximum lines should be around 100 – 120 characters.

Long lines of code have the same problem that very long sentences have. When sentences run long, it shows that the writer is trying to say too much. Sentences should be short and clear, and so should lines of code.

Horizontal spacing

In a line of code, things that are closely related should be close. Things that are not closely related should have spaces that make the logical separation clear. If you’re writing an assignment operation, putting a space before and after the equal operator, will make it easier to see the components of the operation, and the operation being applied.

firstVariable=secondVariable;

firstVariable = secondVariable;

The second line is cleaner, your can intuitively see that there are two variables and one is being copied to the other. In the first line you have to read the whole chunk of text to see the assignment operator in the middle.

If you use an IDE to code, most modern ones will automatically apply spacing to lines of code when you finish writing them.

Indentation

Books have chapters, chapters have sections, sections may have sub sections and so on. Code has indentation levels. Indentation is used to show the scope of the code. The deeper the level of indentation a block of code has, the smaller the scope. Indentation makes code easier to read, you can stay at a larger scope if you only want to get a general idea of what the code does, and go deeper if you want to know more details.

Tabs or spaces? I won’t go there!

 

Formatting – Vertical Formatting

Continuing our series on formatting we will first address the concept of vertical formatting.

File Size

How many lines of code should a file have? This is a question that people can start a very “interesting” conversation. Some people prefer very short files while others have no problem with files that have more than a thousand lines. My opinion is that shorter is better, with lines of code in the lower hundreds. Some people’s brains have no problem with big files but that isn’t my case. Big files can get overwhelming quickly. Also, if a class starts getting very large that probably means that it’s doing more than one thing and should be split up.

The Newspaper Metaphor

Code should tell a story the same way a newspaper article is written. It should start with a headline that lets you know if it’s something you want to read. The first paragraph tells you the general idea of the story and the rest of the article will give you the details if you decide to keep on reading. A source code file should read the same way. You have the constructor, public fields and methods at the top. The private fields and methods that have all the low level details of how things are actually done are closer to the bottom of the file if you want to look at them.

Use vertical spaces to separate concepts

Lines of code that aren’t logically related should be visually separated. The separation between them should be an empty line. This way the different parts that compose the class will be evident, allowing you to easily identify the parts you want to read.

Keep related code together

The same way that concepts should be separated using blank lines, code that is related should be kept in the same block. Breaking up the code with unnecessary blank lines or comments will make reading more difficult.

  • Variables should be declared as close as possible to the code that actually uses them.
  • Instance Variables should be kept together and put at the beginning of the file.
  • If a function depends on other functions, they should be vertically close if possible, going from the highest level of abstraction to the lowest.

In our next post, we will talk about horizontal formatting.

 

 

Formatting – Why it’s important

Think about visiting a restaurant where the food is excellent, but the kitchen is a mess. Even if you loved the meal, seeing the kitchen will make you think twice about eating there again. Another example that is closer to the computer world is data centers.

Look at the following picture. Which network installation do you think is easier to manage, modify and troubleshoot?

Properly formatted code looks more professional, and that is never a bad thing.

The way you format your code is important. It’s important because code that is well formatted is easier to read. When all source files follow the same format you know where to look for things like fields, public methods, constructors, etc.

In the next post we’ll discuss some guidelines for how to format the code you write.

 

Comments – Bad Comments (Part 2)

In this post, we continue with the examples of bad comments.

Position Markers

Sometimes people put a comment marking an important place in a file, or to separate the sections (variable definitions, methods, etc.) inside the file. This is something that should only be done in special cases, since overuse can just make the comments become background noise.

Closing Brace Comments

Comments beside closing braces is a bad sign, because it means that you have a lot of nested blocks in your code, or your functions have too many lines of code in them. This probably means that the code is doing more than one thing and should be split into separate functions.

Attributions and Bylines

Including comments in your code that say who did what, shouldn’t be necessary any more. This kind of tracking should be the responsibility of your version control software.

Commented-Out Code

Lines of code that have been commented will very quickly pollute your code. Sometimes you want to make a copy of the code that was working before, as a safety measure if any of the changes you make introduce a bug. With version control systems, you should be able to see the old code if you need to.

HTML Comments

Don’t write comments in HTML Format, or other formatting options). Comments are for the code in the file, and they should be easy to read.

Nonlocal Information

Comments have to refer to the code that is near them. Don’t write comments about things that are global, or things that they have no control over, because if they change, the comments probably won’t be updated.

Too much information

Comments should be concise, and just as long as they have to be.  If you want to offer a way to have information that is related, but not necessary, a link to the extra information is a good option.

Inobvious Connection

The relationship a comment has to the code it refers to should be obvious. Give enough information to make sure that anyone that has to maintain the code (and a decent understanding of the system’s domain) will understand the comment.

Function Headers

If you have written your code well, then all functions should have a clear and descriptive name, be fairly short, do one thing, and the parameters names should tell you clearly what they expect. All this details should make it unnecessary to write a comment at the function header explaining what it does.

This brings to a close our discussion about comments.

Constantly challenge yourself to try to write code that doesn’t need comments.

Comments – Bad Comments (Part 1)

In our previous post, we looked at cases where  including comments in your code is a good thing. This time we will look at the cases where comments are a bad thing. The examples that we mention below, are bad, mainly because they are used as a compliment to code that can be cleaner.

The lesson that we all should learn from this section is, that we shouldn’t put effort into commenting code, when the comment can be avoided by writing cleaner code.

Mumbling

Mumbling comments happen when a comment is written without giving enough thought to what is being written. After reading a comment of this kind you haven’t gained any extra knowledge, leaving you no choice other than examining  the code to try and figure out what the comment means.

Redundant Comments

Comments should be written when it’s not possible to express something with code. If the code that you have written is clear about what it does, then writing a comment that says the same thing as the code, is redundant and unnecessary.

// this variable holds the account balance
decimal accountBalance;

Misleading Comments

Sometimes a comment can be misleading. Other times it can simply be a lie. This happens because the comment isn’t precise enough and can be misunderstood. Another way that this can happen is that the code changed after the comment was written, but the comment was never updated.

Mandated Comments

There can be cases when the guidelines of the project you’re working on require you to comment every single function and parameter or class member. This adds a lot of unnecessary text to you code, and can help cause confusion.

Journal Comments

Before source control systems were widely used, it was reasonable to include comments at the beginning of files that kept track of the changes that were being made. Now it’s easy to see the changes that have been made to source files through time, so this type of comment has become obsolete.

Noise Comments

Noise comments can be seen as a type of redundant comment. If a comment doesn’t give you any new information or insight, then it’s just noise, and should be removed.

Scary Noise

Scary noise is the child of misleading comments and noise. When you copy and paste comments for your code, but forget to edit them, you have just created scary code.

// The customer's name
string Name;
// The customer's address
string Address;
//The customer's balance
decimal Balance;
//The customer's name
string Email;

We will continue looking at examples of bad comments in our next post.

Comments – Good Comments

Even though you should generally try to write your code in a way that doesn’t need comments, there are cases where they can be valid. Below are some examples.

Legal Comments

Sometimes your job will require you to put some legal comments at the beginning of your file. Maybe you’re using some open source code and you have to include the license. While these may not necessarily be good comments, they’re necessary.

Informative Comments

Sometimes it’s useful to include certain information in your code that will make it easier to understand. Regular expressions, and special formatting commands for printers are a good example.

// this regular expression matches for valid urls
(http(s)?://)?([\w-]+\.)+[\w-]+[.com]+(/[/?%&=]*)?

Explanation of Intent

There can be times when your code can be clean, but it’s not clear why you chose to do something a certain way. Putting in comments that help understand or justify your reasoning can be of great help.

Clarification

Sometimes, you will have to return or use values that can be confusing, but there is little you can do to change them. Many older libraries or APIs receive and return numbers that are actually codes that represent something else. In cases like these a comment that clarifies the meaning of the number can help the code be easier to understand.

Warning of Consequences

There can be pieces of code that when executed may have consequences that can be correct but unexpected. In cases like this, a warning comment can be helpful.

TODO Comments

TODO comments are very helpful to leave yourself reminders of things that should be done, but are not the current task you’re carrying out. Maybe while you’re modifying a class you think of a more efficient way to implement a certain function. In those cases you can leave yourself a comment reminding you of the idea you had for after you finish your current task and can work on it.

Amplification

Amplification can be used to “highlight” the importance of a piece of code. At first glance it can be seen as trivial or even useless while it is actually very important to the task you’re performing. In those cases a comment can help prevent other people or your future self from thinking it’s “dead code” and deleting it.