Applications have a life cycle limited to a few years. Obsolescence, in fact, does not only affect hardware, and the constant evolution of operating systems requires constant maintenance that sometimes becomes impractical and uneconomical.
Updating an entire codebase typically involves a re-engineering phase, similar to that of an application that is written from scratch.
The only real difference is that the functional requirements are largely determined beforehand. However, if the intent is also to implement new features, once again, a careful analysis of the requirements to choose the most suitable technology is required.
For this reason it is advisable not to mistake porting for a mere re-writing work. In fact, there are a number of critical issues that, if not taken into account, can prolong the transition between the old and new version of the codebase overtime, wasting resources that could be devoted to the development of new features otherwise.
Our services include re-engineering for various types of software applications:
- Rewriting or porting of standalone applications and services for desktop systems
- Integration of plugin management systems
- Decomposition of monolithic web applications to microservices architectures
Programming languages and frameworks
Choosing a programming language for a project is not merely a matter of syntax.
The language implicitly defines the reference paradigm used for coding, and although all high-level languages are equipotent, not all are equivalent when it comes to implementing complex and multi-paradigm applications.
In other words, when porting involves a change in the reference programming language, it is necessary to carefully evaluate the semantic implications of each single instruction, relating it to the architecture of the whole program.
Furthermore, sometimes porting is required because the frameworks or libraries used to develop the application are no longer actively supported. In these cases, migration may require to adopt other languages and also implement new design patterns, adding an additional level of complexity.
As designers and developers we have acquired specific skills regarding the main quirks of various programming languages. We also have a thorough understanding of the semantic rules and idioms of many high-level languages.
The languages in which we are particularly fluent are:
Our expertise includes the use of various frameworks and libraries, as well as the in-depth knowledge of the design patterns on which they are based:
- Application framework: Qt/C++ e QML, Microsoft .NET, Node.js, Angular
- Web back-end: Node.js, Laravel
- 3D: OpenGL, DirectX
- Geo positioning: GDAL/OGR, proj4
Simplification, modularity and extensibility
Many applications, especially those poorly engineered, are difficult to maintain due to the high level of interdependence between the various components.
Updating a legacy codebase offers the opportunity to redesign the entire application based on the feedback given by actual users. Pruning unnecessary functionalities and simplifying, at the same time, the user interaction patterns values the new product even if it does not add new features compared to the previous one.
Adopting a modular architecture involves two key advantages:
- Improves code readibility, for easier maintenance
- Makes the integration of new features easier and faster
A modular and extensible design is not possible without an accurate analysis and design phase. Furthermore, pursuing scalability and expandability requires the writing of boilerplate code, as a mandatory part of the core functionalities of the application.
In other words, porting an application can be as complicated as starting a new development project, with the additional risk of biasing the new application with old assumptions, that are no longer valid.