I. Introduction
Industrial software-intensive systems are typically not designed and built from scratch for each new customer and order, but rather as increments over an existing product or as a modified version tailored for the needs of a particular customer, market, or region (e.g., in product line engineering). Similarly, for a single product and considering a continuous integration/continuous delivery context with frequent builds and commits, a system gets built incrementally and iteratively. This results in many intermediate builds and versions (e.g., in agile development). At Google, for example, on a typical workday 16,000-24,000 changes are made to the codebase [1]. Such an incremental development approach essentially leads to the emergence of different product versions, whether as intermediate versions or final ones ready for delivery. This means that over time companies end up having a big range of product versions and components that need to be maintained, and analyzed for re-use possibility whenever a new product is to be built. Moreover, each version can have different quality characteristics, for instance, due to addition, removal, or modification of some features or components. This, however, poses important problems in the development of industrial software systems, some of which are highlighted below:
Usually, the process of re-use analysis (to identify what artifacts can be selected and re-used from previous product versions, and what new ones need to be implemented) is still done manually. This is prone to human errors and not scalable.
A manual re-use analysis also means that the process is heavily dependent on the experience and availability of those key engineers who have knowledge of how previous versions were built and why certain design decisions have been taken.
As new customer requirements arrive requesting new features to be added to an existing version of the product, system complexity also grows. This is often at the price of quality, sacrificing key characteristics such as performance and security. This issue can well exacerbate considering the constant pressure on companies to shorten the time-to-market to be able to stay ahead of the competition. In this regard, there are many incidents where, for instance, patching a bug has caused additional issues, at times making the system even crash and become unresponsive (as an example, consider a recent Windows 10 update [2]).
Guaranteeing quality characteristics which are technically referred to as extra-functional or non-functional properties (EFPs or NFPs) is also a huge challenge in itself: EFPs are mostly interdependent and cannot be analyzed and addressed in isolation [3]. For instance, adding more security features such as encryption algorithms and components to a system can impair its performance. Vice versa, optimizing a system for performance may have negative impacts on its security or energy consumption. Therefore, in automating re-use analysis and making design decisions for development of new product versions, it is essential to have solutions for trade-off analysis to assess the impact of different EFPs on each other, and establish a desired level of balance among them.