Decision-making in small companies is not an easy task, especially when the product being developed needs to be on the market as soon as possible in order to start generate revenues. In most cases the financial and technical limitations forces them to release a buggy work-in-progress product that doesn't meet the client expectation.
Usually a prototype is developed highlighting the main functionalities of the final product, but what often happens is that the prototype end up becoming the final product, including all kinds of deficiencies and technical debts made to meet specific and temporal needs.
The core system that served as the foundation undergoes many changes, and as the product evolves, new systems are built on top of the old one, involving modification which in most cases are hacks to allow the coexistence of different systems and ensure that they continue to work despite the changes. When a project is still at an early stage and the working team is small, quality if often neglected, no workflow is maintained nor a control is made over the code.
As the project progresses, the consequences start to show-up, the code base becomes complex and heterogeneous, which leads to a "spaghetti code" style that includes temporary fixes, dependencies between features, etc. Also information about the different features become inconsistent due to decision that changes over and over again without a flow for approval, or tractability.
Some common factors leading to this result would be:
No control is made over the written code, each programmer will write with his own style, creating inconsistency and disparity in the code base.
The created features are never or rarely documented, leaving black boxes when it comes to improve or modify them, especially when the person who developed the logic is no longer part of the company.
Creation of dependencies between modules, minor modification on a given module would sometime impact the behavior of another module
Duplication and code-redundancy when creating new functionalities caused by a lack of communication and knowledge sharing
A company that falls into this mode of operation will not withstand a long time before the product starts to deteriorate and meet technical limitations urging the team to make drastic decisions which in most cases would lead to the collapse of the product.
So let's explore what would be the best practices to adopt and implement in order to avoid such scenarios and so that the project can adapt to changes while maintaining a good rate of evolution.
In order to illustrate what follows, let's assume that we'd like to build a house, in computer science it can represent any type of project from website creation to desktop applications.
To build a great house in which it is good to live, we first need to choose the right environment and for that we need to answer a couple of questions such as : Is the ground in which the house will be built is suitable for construction? Does the sun cover the whole surface ? Is water accessible ? Are the amenities nearby ? Is a car needed ? etc.
Likewise when it comes to starting a project, we must ask ourselves the right questions, make a detailed and clear analysis about the expected requirements and list the major functionalities that would define the base of the product.
Choosing the right technology
The first thing to consider before undertaking anything is none other than the type of technology that should be used, success, evolution and budgeting are linked to the choices of the technology.
The technological choices are based on several factors such as:
Accessibility of tools and services
Community, documentation and support related to the technology
The cost of specialists
Maintenance and support costs
Ease of communication with third-party technologies
Another important aspect is the programming language to be adopted, usually the choice of programming languages can be based on 3 factors depending on the needs and scope of the project:
A pure programming language: it offers the possibility to develop your own solution from scratch. It allows you to create and structure everything according to your needs. This choice is often avoided by small businesses due to the high resources costs
Frameworks: these are tools developed by tiers offering various functionalities that can be manipulated in accordance to certain rules and can accelerate the development process. However, they also have certain disadvantages, which are often related to technical constraints
CMS: these are out of the box solutions based on a set of modules offering many functionalities, it is a very widespread approach in web development, it allows you to create a clean website in few clicks. Your only job would be to connect a set of functionalities together to make a clean website, but as long as you go beyond the scope of the exposed functionalities, it is quite difficult to add new ones, if not impossible in some cases.
Making the right choice is not always an easy task, considering all the trends and changes taking place in the IT environment. However, the most important thing in this phase is to identify the environment in which you would like to evolve and to maximize your chances of success. This will require identifying the advantages and disadvantages of each point, investigating whether products similar to yours are already on the market, seeking expert advice and do not hesitate to prototype with various technologies to gain a better insight of the practical results.
Once the environment has been analysed and we know that it's ideal for construction, we now have to choose the right tools for the task. For a house to stand the test of time and hold solidly through the ages, it requires a strong foundation, its pillars must be placed in a specific and well-established location in order to support the entire structure to be built on it. It also requires that the building materials meet certain quality standards and that there is coordination between the various craftsmen to ensure a clean and efficient work. The same goes for an IT project, once the technologies have been properly selected and one is ready to go in production, it is essential to set up a common workflow between the different departments and ensure that everyone has an appropriate role in accordance with their skills.
Among the best practices to be established are the following:
In order to generate harmony in the code base, makes it easy to read, to understand and to maintain, a code standards, on which the developers agreed, should be established and adopted.
As the project evolves and team grows, a lot of effort and energy can be wasted due to disagreement about how the code should be written and the form it should have, also understanding the logic of a given code become harder, sometimes the same code will be written over and over again to satisfy each developer preference which will create an inconsistency since every code bloc will be written in a different way.
While coding standard is a practice that every company should consider in their workflow, it's often neglected and most companies don't bother to adopt one.
Establishing coding standards alone doesn't guarantee that it will be adopted and respected. In This is where the role of code review became mandatory. It allows peers to verify each other code, newly written or modified ones. It creates a collaboration atmosphere between developers, allowing them to share their knowledge and explain the steps they’ve taken to reach the expected result. It guarantees that the code respects the established conventions within the team and avoid additional new bugs due to bad design or code poorly written.
There are mainly two types of code review:
Shoulder review :
The idea of the shoulder review is that the author of a specific code will guide one of his teammates through the different changes by explaining the reasons for doing such and such, it’s a detailed review and the reviewer also become responsible for the code if there’s any issue that would arise from within. Usually this kind of review is done when it is a minor correction, or when changes are made on a system that belongs to someone else.
Collaborator review :
The collaborator review consists in putting the code on a platform that offers features to compare code from one version to another, allowing reviewers to have an overview about the changes. It also gives the possibility to choose the people to involve in the review and offers a friendly environment to facilitate the reviews such as choosing the type of error, write comments on specific lines, the possibility to approve or not changes, etc.
Unlike the shoulder review, collaborator review involves more than a person in the review process. Reviewers have the possibility to review the code at their own pace and also make it easy to keep track of the different changes.
Combining both worlds
It's something common in large projects, that both review methods are combined. The shoulder review would allow the developer to submit his code as a first pass and thus avoid blocking others if the functionality needs to be tested as soon as possible or if it's a major feature.
Once submitted, the code is sent to the collaborator review so other developers can give their feedback to improve it and to have a certain visibility about the changes.
One last practice that would be mandatory to put in place is a continuous integration system (CIS), in simple words a test environment that would guarantee that the project will continue to work properly despite all the introduced changes and also gives the ability to revert to previous version of the product in case of emergency or for testing purpose.
CIS is a kind of a police officer to the project, it raises warnings when something wrong is happening with the product. It will verify every committed change and make sure that it doesn’t alter the current state of the project. When an error occurs, the CIS will notify the person who introduced it, and would send a detailed report to help understand it.
A CIS is based on a set of tests designed to validate the basic functionalities of the product. As a general rule, tests are created by programmers that contains a set of acceptance criteria to determine the success or failure of a given logic.
Such a system allows to:
Perform immediate tests on any new modifications
Alert the entire team in case of incompatible or missing code
Problems are detected and repaired on an ongoing basis, avoiding last-minute problems
One of the essential points of continuous integration is that it always keeps versions of the product available for testing, demonstrations and distribution.
All the concepts described throughout this article may seem obvious, even essential to get a project off to a good start, yet few companies take them seriously or even bother to think about them. Usually those concepts are neglected due to a lack of interest or resources to implement them. I often heard ’we are only four developers in the team’ but we forget to think about the long-term run, to take into consideration that team members can leave the project with all their knowledge, or when recruiting juniors or interns, we cannot always have a follow-up of everything they do, due to time constraints.
Good practices are essential for the sustainability of a project, regardless of the number or type of projects, implementing such practices can only benefit the project and would help to better manage and control it.