Software Development

Basic code refactoring principles

2017-05-05 Code Refactoring, DSP2017, Software Development, TDD, Unit Tests No comments

Introduction

I’ve recently read a book about Test Driven Development by Kent Beck. It’s really good, presents the importance of the TDD and shows how to make a life of the software developer easier. In the TDD we follow red-green-refactor process in which we create a failing unit test, then we fix it and refactor it to make code-base better. There’s no golden rule when to refactor or how to refactor code and each project is different, but there are a few principles we may follow when we want to improve our projects through refactoring.

Finding similarities and duplications

One of the common code smells is duplication. We should search for the following patterns:

  • Two similar loops » try to merge them into one loop
  • Two similar instructions inside conditional statements » try to unify operations and get rid of the “if” statement
  • Two similar methods » try to unify them and remove one of them
  • Two similar classes » try to unify them and remove one of them
  • and so on…

Perform these operations carefully. If something goes wrong, go one step backward. Sometimes it may be impossible to remove all duplications.

Isolating changes

Before we start performing changes, it’s good to isolate a piece of code. We can move it e.g. to separate method, perform changes and then inline our method. That could help us avoid breaking the whole system.

Data migration

If we want to change the meaning of the data, we can temporarily duplicate them, perform changes, update interfaces and then remove original code.

Method extraction

If a method in our class is too big (according to Clean Code, “too big” is longer than 20 lines), we should find code doing specialized mini-task and extract part of it to a separate method. In IntelliJ IDEA we can use Ctrl+Alt+M shortcut or ⌘+Alt+M on Mac for that.

Method inlining

Sometimes, we’re extracting too many pieces of code to separate methods, what may decrease code readability. If the code inside the method is really simple, so it could be written in a single line or optionally in two lines, we may think about inlining this method. To do so, we should remove method and place code directly in the place where it’s called. To perform inlining in IntelliJ, we can use Ctrl+Alt+N shortcut or ⌘+Alt+N on Mac.

Interface extraction

When we want to create additional implementations of the operations, which already exists in our code-base, we may extract these operations into the interface. IntelliJ IDEA also has support for that. I’m not sure if there’s a shortcut, but you can use Ctrl+Shit+A shortcut or ⌘+Shift+A on Mac to open window with operation search and then type “extract interface”. It should work.

Moving method

It may happen, that our class or interface is becoming too big or it has methods, which are not directly related to this class. In such case, we may simply move one method or a few methods to another, more appropriate class or create a separate class or interface for them.

Object-method

We may encounter a situation when a specific method has too many parameters. In such case, we may consider creating Object-method. It’s some kind of data class, which contains attributes the same as method parameters. It will help us to pass data in our system in a more readable way. We can also connect this solution with a Builder software design pattern.

Adding parameter

During the time, the business logic of our system is getting bigger and one of our methods need to be extended. In such case, we can add another parameter to it. We may also consider creating another, similar method with just one more parameter. When we’re providing API or framework for other developers, we have to remember about proper “deprecated” annotations.

Moving parameter from method to the constructor

It may happen that we want to move a parameter from the method to a constructor to simplify the logic of the project. In order to that, we can move local variable to a class variable (in IntelliJ IDEA: Ctrl+Alt+V shortcut or ⌘+Alt+V on Mac) and then create constructor with this variable (Alt+Insert or ⌘+N on Mac).

Summary

As we can see, there are a few principles, which we may apply during code refactoring to make our project better. Moreover, most of them are supported by IntelliJ IDEA, which is great IDE. If you’re programming in another language than Java and want to have refactoring tools, you should check JetBrains products. Nevertheless, there’s no golden rule of refactoring. Sometimes it’s better to leave the code as it is. Especially if code-base is huge, the project is in production and there are no unit tests. If you want to know more about principles from this article, read Test Driven Development book by Kent Beck. Probably there are more principles than these described in this article. We should perform refactoring carefully and we need to remember about tests. Everything depends on the concrete project and our situation.

Handling different Android versions with strategy pattern

2017-03-26 Android, DSP2017, Software Design Patterns No comments

When we’re developing Android apps, we have to remember that different users have different versions of the Android OS. Unfortunately, not all of them has the newest version of the system and some of them have older devices with older systems. Some of these devices may be even unsupported because e.g. Google supports their devices like Nexus and Pixel for only 2 years. When we want to reach as many users as possible and make the app available for almost everyone, we have to handle different Android versions. One of the solutions for that problem is strategy design pattern (it’s also called Policy in Domain-Driven Design).

I’m developing an Android open-source library called ReactiveNetwork, which is used for monitoring connectivity with the network in the system. Network monitoring strategies vary between different versions of Android and I wanted to choose an appropriate strategy for appropriate Android version. To do so, I’ve created NetworkObservingStrategy interface:

This interface can have many implementations like LollipopNetworkObservingStrategy, PreLollipopNetworkObservingStrategy and MarshmallowNetworkObservingStrategy. Morever, more implementations can be added in the future.

After that, we can choose valid strategy for concrete version of the system:

That’s it. Now, we have the separate code working for Android M, L and all devices with system version lower than L.
This approach can also be applied to other areas.

Get past the syntax, the real scare is in the semantics

2015-07-06 Java, Software Development No comments

Dr. Venkat Subramaniam presented an interesting point of view during his talk at Devoxx conference. Programmers, who start learning a new language, often complain about syntax. They focus on using available keywords and constructions instead of trying to understand their meaning and purpose. Programmers also have their own habits. That’s why Java has similar syntax to C and C++. Creators of Java designed new language with syntax, which was familiar to them, with significant improvements. Perception of the world is based on experience and things we get used to. The same rule applies to programming languages. Most software developers are familiar with imperative programming paradigm. They often focus on describing computation in terms of statements and changing program state. This approach leads us to necessity of creating a lot of temporary variables and boilerplate code. Let’s have a look at the following code snippet:

This code prints sum of the square roots of the first ten even numbers starting from zero. It’s not so complicated task, but there is a lot of code, temporary variables, two loops, we have to be careful with operators to avoid ArrayIndexOutOfBoundsException and so on. Moreover, code is quite hard to analyze and we can make a mistake in many places. Let’s see what happens when we use functional programming approach, Java 8 with stream API and lambdas. We can do the same task in the following way:

As we can see, the code is simpler, cleaner and easier to analyze. The only difference is the fact that we changed approach from imperative to the functional one and applied different semantics. In this case, instead of focusing on how to do the task, we focused on the result we want to obtain. Instead of learning only syntax, we should spend more time on learning semantics to understand its purpose. This will allow us to create better and robust solutions in less time.

This article was also published as a part of summary of Devoxx 2015 Conference in Kraków, Poland on technical blog of Future Processing:
http://www.future-processing.pl/blog/devoxx-conference-summary/

The One Hacker Way – a rational alternative to Agile

2015-03-22 Agile, Software Development, Video Talks No comments

Recently, I’ve seen an unusual talk about The One Hacker Way – a rational alternative to Agile by Erik Meijer.
It’s really interesting point of view. I recommend to see it.

One Hacker Way – Erik Meijer from Reaktor on Vimeo.

The Future of Programming

2014-10-12 Software Development, Video Talks No comments

I highly recommend you to watch a short lecture presented by Bret Victor at Dropbox’s DBX conference on July 9, 2013. It really broadens the mind.

Bret Victor – The Future of Programming from Bret Victor on Vimeo.

References: http://worrydream.com/dbx/

Package by feature, not layer

2014-08-31 Java, Software Architectural Patterns, Software Development No comments

The first question in building an application is “How do I divide it up into packages?”. For typical business applications, there seems to be two ways of answering this question.

Good article concerning mentioned topic can be found at: http://www.javapractices.com/topic/TopicAction.do?Id=205.
It’s worth reading, so check this out. Maybe it’s not too late to apply that idea in your project?
Read about more Java practices at: http://www.javapractices.com/.

Issue workflow in agile projects

2014-01-05 Agile, Software Development

In team projects it’s important to prepare issue workflow and, so-called, definition of done in order to be sure, when particular task is actually done. It’s often practiced in agile projects and scrum process. When we take into consideration IT projects and version control system like Git, we can create Git branches with concrete purposes:

  • master branch – latest stable version of the application – for Product Owner and client
  • development branch – latest development version of the application with passed tests and code reviews, but waiting for approval of the Product Owner – for developers
  • many single branches for each issue (task) in the project (e.g. creating part of the GUI, coding specific functionality or fixing a bug)

Besides the Version Control System, we also need to have other essential tools for software developement like issue tracker, etc. in order to realize work well.

The easiest way to present definition of done (issue workflow) is to prepare a diagram. Exemplary diagram of such process introduced in one of the projects I am working in, is presented below (click on the image to enlarge it).

issue_workflow

Introducing such process in a project increases quality of the software, makes it more stable and whole work becomes systematic and well ordered.

Clean Code Cheat Sheet

2013-08-11 Software Development No comments

Recently at BBV Software Services blog I have found very interesting and handy Clean Code Cheat Sheet, which can help you to be better programmer. This document is actually based on famous book Clean Code: A Handbook of Agile Software Craftsmanship by Robert C. Martin.
clean_code_cheat_sheet
Clean-Code-V2.1

5 essential tools for serious software development in a team projects

2013-03-27 Software Development, Tools 1 comment

Introduction

Daily usage of tools mentioned in this post is quite obvious for me right now, but using them wasn’t obvious while I was working alone or when I was involved only in freelance or private projects.
Whilst we don’t work in a group, we don’t have to care about lot of things, but when we work in a team (even small), we have to organize and optimize our work very well in order to obtain its high quality, work efficiently and make life of future developers of our code and co-workers easier.

1. Good IDE or editor

Intellij IDEA
Having good Integrated Development Environment or editor is very important during software development. When we master keyboard shortcuts and useful features of our environment, we can increase speed of work and debugging. Choosing environment depend on the projects and programming languages which we are using on daily basis. Eclipse is a good choice, when we develop code in Java language, but we can use it for creating C/C++ code, PHP and web development. Good alternative for Eclipse is IntelliJ IDEA (only Community Edition for Java developers is free right now). Android developers should strongly consider using Android Studio, which is based on IntelliJ IDEA. JetBrains provided IDE for Python developers as well. It’s called PyCharm and its Community Edition is free. Obvious choice for developers using Microsoft technologies will be MS Visual Studio. Despite IDEs, we can also consider using advanced editors like Sublime Text. After proper configuration, it can be very nice tool for web development and JavaScript development (including node.js). Some Ruby developers use Sublime Text as well. In general, it is worth considering while we write our programs in scripting languages. In addition, it is available on MS Windows, Linux and Mac OS. Sublime Text is just an editor, so it does not have code debugger like Eclipse or MS Visual Studio, but we can add this functionality for JavaScript language by installing Sublime Web Inspector plugin. Some people also use Notepad++. I like this editor, but I wouldn’t use it for software development due to lack of important features. In my opinion it’s good for editing single files or performing some simple operations on text or code. Of course, Linux geeks should not forget about exclusive Vim editor, but use of this software must be learned before using.

2. Source control system

branching-illustration@2x
When we work in a team, we need to have source control system. Uploading code to server by different people or sending code via e-mails is not efficient and unprofessional. That’s why we should use Git, which is distributed version control system. While using such tool, we can be always up to date with our code and we can easily track changes in the project, create branches for several tasks and so on. We can also rollback changes, when something will go wrong. Git clients are available for all popular operating systems. When we are not familiar with command line interface, we can use tools like TortoiseGit. On daily basis, the most important commands are: clone, pull, commit and push. Good practice is to create branch for development version of the application and treat master branch as a release version of the application. In addition, we can create separate branch for each issue we are working on and when we finish our task, we can merge our branch with development branch. It’s very helpful and allows us to increase stability of the project. If we want to know all advanced features of Git and master this environment, we should read “Pro Git” book which is available on-line for free.
Another, older source control system is SVN. Well known GUI client for SVN on MS Windows is TortoiseSVN. SVN is not distributed version control system like Git and does not have such amount of features, but it’s worth to know it, because it is used in some projects today for some reasons. Yet another source control system, which is less famous than SVN and Git, is Mercurial. Like mentioned systems, despite command line interface, it also has client with GUI called TortoiseHG available for Windows OS.

3. Continuous integration tool

ci-diagram

Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily – leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly.

Quote of Martin Fowler.

Continuous Integration is also explained in details on Wikipedia.

jenkins_logo

One of the common tools used for Continuous Integration is Jenkins. In simple words, developers commit changes to the project and afterwards Jenkins download source code from the repository and generates a fresh build of the project (compiled application). Builds can be scheduled and run automatically, but we can also run our builds manually. When something will go wrong, we receive an information that build is broken, unstable or cannot be compiled. In such case, developer who broke the build (pushed changes, which caused such situation) is responsible for repairing the build. We have to take care about the configuration files, because sometimes Jenkins may analyze our source code differently than our local compiler (because of specific settings or different operating system) and it may cause build failure. While using Continuous Integration, we don’t have to send compiled projects via e-mail or in other inconvenient way. We can just run the build. After that operation, Quality Assurance Engineers and Project Leader will always have access to the newest version of our project.
When we don’t want to use Jenkins, we can consider adapting alternative Continuous Integration service called Travis, which is integrated with GitHub. Yet another continous integration and build server is Bamboo from Atlassian.

4. Code review tool

PeerReview

Code review as a systematic examination of the source code plays important role in the quality of the project. Different programmers have different background and point of view. We all make mistakes and it’s easier to fix them when we have good support. There are tools which can help us to make Code Review. One of them is Review Board written in Python, which can be associated with Jenkins. After running Review Board build, we can send e-mails including current revision changes to our team in order to keep everyone up to date. There are also other tools, which we can use. Phabricator can be an interesting tool, but I don’t have any experience with it yet. Nevertheless I know, that it is written in PHP and was developed at Facebook. Gitlab is also worth considering during conducting code reviews. Moreover, we can omit using additional tools and perform code reviews by browsing code and talking with another developer verbally, which is also good practice. To summarize this section, Code Review lets us to know what is going on in all projects of our team and, what is more important, helps us to increase quality, maintainability and robustness of our code and projects, which are used by the final users.

5. Issue tracking system

jiratour_workflow_visualizeworflow

Good Issue Tracking System is also important tool used during the development of the project. It lets you track tasks, bugs and changes in the projects. We can create simple workflow in our project, which will increase quality of the software and also keep you informed about progress of the project. This is important in situations when several people work on the same application, so we can divide and choose tasks wisely in such a way, that people won’t disturb or “interfere” themselves during the work. In addition, project leader will be informed about the progress of the work. There are many issue tracking systems, but one of the best and well known is Jira. In addition, Jira allows you to work with projects in Agile methodology, so you can define backlogs, sprints and create good workflow in the project. Despite of these features it has so called Confluence, which is basically internal project Wiki, where you can create your knowledge base and notes.

Summary

All these five elements can help you to make great applications and projects. It may seem, that using them is a lot of additional work, but in fact, they are really useful and can help you to work faster, better, increase quality of the project, integrate code, identify and track the bugs, track tasks, issues and keep the project up to date for everyone who is involved in it. When we take care of good project organization, the only possibility is awesome outcome.