Write better code

Recently I began to read a good book about code quality and how to avoid the so-called “spaghetti code”. I still haven’t finished the book but I’m half way there and my code writing improved a lot since I started reading it. The book is called Code Complete – Second edition and I definitely recommend it.

Here i would like to add some of the things I’ve  read in the book and share it with everyone. Let’s not waste any more time.

Get started.


Software construction.

Software construction is often ignored. People like to get working on an idea right away without spending time to think about the design of the application they are writing. This often leads to spending more time at production state (when you write the code). The reason is simple – people often haven’t thought about application specifics, or library specifics or something of that kind which leads to rewriting the code.

Trust me – you are a better programmer if you waste a day to build up a strong architecture of the code and save the time of ten people, instead of diving into coding some cool feature that may get rewritten in the future.

Comparing program to real life objects.

A good way to start making an architecture for your code is to think about objects in real life. There is nothing better than a good metaphor to understand the specific of a task. However don’t think that a good metaphor will tell you how to find your answer. It will tell you where to find the answer, rather than telling you what the answer is. The latter is specified by algorithms. An algorithm tells you what the answer is directly – a heuristic (this is what a metaphor in this context is) guides you to how to find the solution yourself or at least where to start looking.

The metaphor you probably use every day is – “writing code”. This suggests that code should be written like a good book and so it should be read like a good book. It is a developers job to make this to happen. Of course a book is most likely written by a single person. Software is most likely written by many people.

Consider that writing software is like building a house. If you are building a dog house you would go to the store and buy some wood and nails. In a day you will be ready with the house and if you forgot to leave a door for your dog – don’t worry – you only wasted a day. This is appropriate for small projects – if you write 1000 lines of code they are easy to refactor.

However if you were building a house is a bit more complicated and your approach would most likely be different. You would take the time to think what house you want to build. Then you and an architect will make a design and get it approved. Think about what you will need for the house and go buy the already made things and so one. Those principles are 100% accurate for software development.

Setting up prerequisites.

It is a good idea to think about several things and discuss them with your team before you start working.

1. Agree on what convention you would use in your project. 

– Aside from the language specific convention decide if your class variables will be named with “m” prefix for example. Or where and how to write comments in your code. Or what formatting you will use. The last is specially useful when using version control to avoid unnecessary conflicts.

2. Discuss the best coding practices.

– How you will handle error cases (maybe use a loger or an assert if your language allows it).

3. Always discuss the steps needed for an actual commit.

– It is a good idea to make code reviews before committing to the master repository. Maybe the most experienced programmers can check the code of the more unexperienced programmers for quality and logical errors before they make a commit. This will help both the unexperienced programmers to learn how to write better code and the whole team to avoid pulling broken code.

4. Consider the version control tool you will be using and sync each other versions.

– Consider if you are going to use git, svn or something else before starting to code. Consider your repository. Avoid transferring code through text documents or patches.

Designing Goals

  1. ” Does the design adequately address issues that were identified and deferred at the architectural level?
  2.  Is the design stratified into layers?
  3.  Are you satisfied with the way the program has been decomposed into subsystems, packages, and classes?
  4.  Are you satisfied with the way the classes have been decomposed into routines?
  5.  Are classes designed for minimal interaction with each other?
  6.  Are classes and subsystems designed so that you can use them in other systems?
  7.  Will the program be easy to maintain?
  8. Is the design lean? Are all of its parts strictly necessary?
  9.  Does the design use standard techniques and avoid exotic, hard-to understand elements?
  10. Overall, does the design help minimize both accidental and essential complexity? “

Straight from the book as those are excellent questions.

RaxusPrimeTicTacToe

After the brief introduction about Java it is time to write some code and explain some basic Java coding.
I will start with my teamwork project from SoftUni – a graphical TicTacToe game developed using  Java Swing.

Lets get started


RaxusPrime TicTacToe

The most important thing before starting a new project is taking the time to think about the architecture of the classes. Which things should be in a separate class? Which things should be made abstract or made an interface?

The cool thing about Java is that it enables packages. This helps you visually make the difference between the classes (if structured correctly). In our game we’ve made a lot of packages – this will help us maintain the code easier in the future.

TicTacToe hierachy

Raxus TicTacToe package hierarchy

This is what our project structure looked like. The convention for naming the packages is com.organizationname.projectname.specific.

Because this project was made as an assignment from the SoftwareUniversity and our team was called Raxus Prime, we chose com.softuni.raxus as a name for the packages.

As you can see there are a lot of *Screen classes. This led us to think that we can reuse some of the code instead of writing it every time. We decided to use an Abstract class that holds the common functionality of all the screens and let the more concrete classes extend it.

AbstractScreen class

Our AbstractScreen class extended JFrame which let us create a graphical frame. This frame can hold other components which we’ll talk about later. We also implemented an interface in this class. That way we could abuse the power of polymorphism in our click listeners.

public abstract class AbstractScreen extends JFrame implements IScreen

 

private void initializeScreen() {
   setTitle(title);
   setDefaultCloseOperation(EXIT_ON_CLOSE);
   setLayout(new BorderLayout());
   setSize(800, 800);

   // Every child will override this method for specific implementation.
   Component component = createSpecificComponents();
   if (component != null) {
      add(component, BorderLayout.CENTER);
   }

   setLocationRelativeTo(null);
   setVisible(true);
}

What the above code does is it initialize a screen (as the name of the method says). It sets the title of the screen, sets the default close operation or what happens when the user clicks the X button at the top right corner, sets a size of the frame, sets visibility and the main thing is the createSpecificComponents() method.

This is an abstract method which every child needs to implement. In this method the child classes add components (buttons, text views etc.) that are layed out in the frame.

Child class implementation of the abstract method. createSpecificComponents();

 

@Override
protected Component createSpecificComponents() {
   JApplet verticalButtons = initButtons();
   return verticalButtons;
}
private JApplet initButtons() {
   List buttonsList = new ArrayList();
   buttonsList.add(createPlayButton());
   buttonsList.add(createOptionsButton());
   buttonsList.add(createAboutButton());
   buttonsList.add(createExitButton());


   VerticalLayout verticalLayout = new VerticalLayout(buttonsList);
   return verticalLayout;
}

And the result is the MainScreen:

The Java Virtual Machine

 

The JVM

Java virtual machine (JVM) is a process virtual machine that can execute Java bytecode. It is the code execution component of the Java platform. Sun Microsystems has stated that there are over 5.5 billion JVM-enabled devices. Java virtual machine (JVM) interprets compiled Java binary code (called bytecode) for a computer’s processor (or “hardware platform”) so that it can perform a Java program’s instructions. Java was designed to allow application programs to be built that could be run on any platform without having to be rewritten or recompiled by the programmer for each separate platform. A Java virtual machine makes this possible because it is aware of the specific instruction lengths and other particularities of the platform.

Java introduction

What is Java

Java is a computer programming language that is concurrent, class-based, object-oriented, and specifically designed to have as few implementation dependencies as possible. It is intended to let application developers “write once, run anywhere” (WORA), meaning that code that runs on one platform does not need to be recompiled to run on another. Java applications are typically compiled to bytecode (class file) that can run on any Java virtual machine (JVM) regardless of computer architecture.