Takeover of a source code created by someone else is one of the most stressful tasks that a programming team may face. However, such a situation is quite frequent. Company that maintains an application may be changed due to many reasons – financial, operational or strategic (system takeover). If we are informed about the takeover in advance, we should make some preparations already at the stage of agreements and business settlements. The agreements should include provisions about the necessity to document the source code and related to the technical documentation of the project.
All project-related communication should be kept in the reporting system (for instance in Redmine), while the source code itself should be kept in the revision control system (SVN, GIT…) together with a log with comments about the introduced changes. The takeover is much easier if the software development process is appropriately organized. We can and we should demand such an organization at the stage when the creation of the app is commissioned.
Putting the general condition of the project aside, there are at least several methods that may help you to reduce the related risk and to find your feet when starting the work on the application.
Documentation and trainings
The company that hands over the software development process should also provide technical documentation. This is a standard. Without such documentation, our team will have to thoroughly analyze the source codes or introduce changes “blindly”, without any certainty about the ways the modified mechanisms work.
The documentation does not have to be very extensive. If a functional documentation was created at the analytical stage (before implementation), it may serve as a basis for the development of the technical documentation.
If such a situation was not provided for in the implementation agreement, the author may demand additional payment. The documentation development process may take some time, but you should not hesitate to perform it. It would be too risky.
Effective materials should include:
- characteristics of the application architecture – description of the modules, their roles and any possible relations;
- descriptions of non-trivial algorithms – for instance pricing mechanisms, mechanisms used to acquire the data from external systems and all algorithms that work in an unusual way or that were altered or adjusted should be thoroughly explained;
- description of the installation and startup procedures, specifying what and when should be cleaned up in the database, which logs should be rotated, how to create backups – maintenance actions will be required from the very beginning, they should be explained to avoid any system failures;
- description of other actions necessary to keep the application working;
- description of the most important classes and layers – typical programmatic description that would make it easier to find the elements of the code that need to be altered or improved;
- description of the database structure – in the case of complex, relational databases, apart from the tables, the relations need to be described as well. In some situations, a typical ERD (Entity Relationship Diagram) with comments on the roles of each table is enough. Usually, the description of particular columns is not required, their roles are often self-explanatory. Otherwise, it may be a good idea to ask for more details;
- description of the troubleshooting procedures – if there are some typical emergency situations and developed procedures, the documentation should include their detailed description.
The documentation should be received by the team that will maintain the application. The team should be given at least couple of days to analyze the material and to submit any remarks. You need to remember that the development of documentation is not a pleasant task for the programmers and that the results of their work often leave much to be desired. The descriptions are too short or they do not include some key mechanisms.
In an ideal situation, the new team should participate in 3-4 training sessions with the programming team that hands over the application. Organization of such sessions shows the original company in good light.
Exchange of knowledge between the programmers is the quickest and most efficient solution. During such trainings, relevant questions can be asked and answered in a substantive and concise manner. In some cases, such trainings may help in the further development of the system even if the documentation was not provided. Their participants may take notes that may serve as a basis for the documentation. What is most important though – new people can gain the required knowledge straight away.
Interview and introduction to the new system
Taking over a programmatic solution, it is always a good idea to talk with the users/owners about its most problematic elements. We do not want to get into trouble when accepting the challenge to develop the application on our own. Maybe the system has some serious issues that would require a complete reconstruction of the code? If it is possible, we should compose a list of possible complaints and discuss them with the current service provider, trying to recognize their seriousness. We need to know whether we will be able to handle them!
Startup and essential actions
The most elementary actions related to the application need to be mastered first. Startup, creation of backups and database backups and all other actions related e.g. to the removal of the logs or redundant data are essential. If we do not know how to perform them, the application may fail or simply stop working.
You may need to learn by the trial and error method – in such a case, the results of your experiments need to be kept in the system log, in order to record the acquired knowledge.
Source code analysis
Regardless of whether we have the documentation or not, the source code analysis will be required at some stage. The code is written in accordance with the standards and with the use of the design patterns? Not bad. However, if the received app is a spaghetti of the code, views and configuration data, we are in deep trouble.
Usually, the code is analyzed with the use of the top-down method. We analyze the URL that is defective or demands changes and use the IDE tools to trace the location of the element responsible for the given behavior. We scan the front controller, application controllers, models and views.
Such a method may be applied to any application, but sometimes it may turn out to be quite time-consuming. You also need to remember to record your findings – to create the documentation through the reverse engineering.
Review of the revision control system logs may be helpful in the source code analysis as well. If the system was applied in the proper manner, we may use it to find branches and tags indicating particular versions and transparent comments on the given commits, describing the altered elements. In an ideal situation, the comments should be related to the reporting system tasks (and specify which tasks were performed within the given commit).
However, the amount of time needed to analyze the code depends on the code architecture and quality. It is a good idea to assess it before the development works may begin. We may differentiate several primary quality indicators:
- is there a coherent coding convention applied – are the names of classes, functions, methods and variables given in accordance with the same pattern and in the same language? Are the names self-explanatory or are there some magical constants and strange abbreviations used?
- are there any design patterns used – they accelerate the communication (does the given pattern explain the operation and structure of the particular fragment of the application)?
- does the application use proven frameworks and libraries – they significantly improve the development process – known frameworks not only guarantee the proper operation of the system, but also help to avoid the situation where the programmers are surprised with some applied solutions;
- are there any comments in the code – related to methods and classes, describing their roles, rules of algorithms operation and parameter types? It is especially important in the case of script languages and languages without strict standards. Code written in such languages without any comments may cause an improper use of functions in the future;
- is there a unit testing coverage? Such tests prove the diligence in the system development process and constitute a basis for the introduction of further changes (they enable quick detection of any possible problems).
It is always a good idea to analyze the application taking the factors above into consideration, before agreeing to develop the system. Any software that has been developed for quite a long time has more or less defects at the level of the source code. It is normal. However, it may turn out that in the case of high demands of business character, we will not be able to sufficiently refactor the code. Introduction of further changes may occur to be too expensive and time-consuming.
Team for special tasks
The development of a new system should be handled by a team for special tasks. It acts like a SWAT unit, quickly stepping into action and tackling the situation. We need to remember that the first tasks related to the new projects would probably concern bug reports and fixes.
The most experienced programmers will quickly find their feet in the new situation, detect the reasons and propose appropriate solutions. Our rapid response team should be composed of such people.
When taming the project and gathering knowledge about it, the project itself may be developed by other members of the team. However, the best programmers should pave the way.
Unit tests allow us to get to know the unknown. They show how to use the new code that we took over. Calls they include may be treated as a living documentation.
What is more important though, is that they make it possible to check whether the application is still working properly. It is especially important in the case of script languages, when there is no possibility of applying the additional propriety filter – compilation.
Due to the unit tests, we may work in the mode: works-does not work-fix it-works, knowing exact results of the introduced changes. Unfortunately, if we do not know the system thoroughly, the introduced modifications may cause some repercussions in those parts of the app that for us are not logically related to the changes we made.
Nevertheless, it is always a good idea to consider the application of unit tests and to write them before the changes are introduced. Obviously, the coverage will be minimal – but the tests will act like the fall protection equipment. The programmer writes a test for an existing code (which is in fact unknown) in such a way to fulfill given conditions. The code is used as a black box. Then, the required changes are introduced. If the test still works and gives positive results, it means that we did not destroy the original specificity of the system.
Revision control system and change tracking
It does not matter whether the revision control and reporting system were applied or not – they must be used for the deployment of consecutive versions of the system.
Introduced changes are accompanied by great risk. They should be versioned in separate branches, allowing for quick withdrawal and transactional deployment. Changes should be introduced in small amounts and ought to be related to single tasks and code fragments. Such granulation makes the tests easier and reduces the amount of modules that could fail in the case of bugs.
Information about the scope and purpose of the introduced changes should be kept in the logs. We need to apply the references to the ticket system tasks that forced the introduction of changes in the code. For sure, it will turn out that some defects caused by the changes will appear at a later stage. In such a case, such a modification log will be indispensable!
Project log and documentation
Project log is an important tool worth using in the software development process. Log is a convenient way to document the performed works. It may contain important observations related to the code and, most importantly, solutions for the problems detected in the course of works.
New people will not have to reinvent the wheel, they will simply check the log. When learning about the project, the role of logs containing information about the most important changes is hard to overestimate.
In the case of projects taken over from external companies, the system should be audited and analyzed before any actions may be performed. This way, we may reduce the level of the risk. IT systems are not simple and we should never base our evaluation on assurances and declarations. If there is no reliable documentation or if some quality issues are detected during the interview – a detailed audit of the source code may be necessary.
Such actions should not be aimed at proving the fault or incompetence of anybody – they should be treated as a preparation for a responsible takeover.
The development tasks should be approached with much consideration and pragmatism. We need to assume that the new team will introduce changes slowly – more slowly than the original programming team. They will need time to learn about the code and to develop appropriate procedures. Reduction of this time increases the risk of errors and failure of the whole operation.