Component-Based Software Engineering over traditional approaches in large-scale software development

Introduction.

With the growth of the software size and complexity, the traditional approach of building software from scratch, becomes more and more inefficient in terms of productivity and cost. The quality assurance of the produced software becomes almost infeasible, discouraging introduction of the new technologies.

In order to meet the requirements of quality, modern large-scale software, new development paradigms have been introduced that facilitate the creation of evolvable, flexible, reliable and reusable systems.

One of such paradigms is called a Component Based Software Development (CBSD) and it relies on the concept of building an application components that are meant to be the independent, reusable pieces of code.

In this post I will present the component based  approach for large-scale software development, discuss its advantages and argue its superiority over traditional approaches in modern large-scale software.

What is Component-Based Software Engineering?

Component Based Software Engineering aims at reducing the cost of software production and improving the quality of a system by building it using selected components and integrating it together into one piece employing well-defined software architecture.

The components can be heterogeneous in terms of programming language and can be developed by different programmers that significantly improves the communication within a team and thus facilitates productivity. They should be easy to assemble by simply checking it out of repository and integrating into the final software system.

Each of the component should have some clearly defined functionality and be independent of the whole system.

Moreover, they should be assembled in context of well-defined architecture and communicate with each other using interfaces.

The development of Component Based Systems can be divided into the following phases:

1. Component Requirement Analysis

In this phase, it is crucial to gather, understand and manage requirements relating to to the particular component. At this point the decision has to be made regarding the choice of platform, programming language and design of interfaces that will allow inter-component communication.

2. Component Development

At this stage, the implementation of specified requirements plays crucial role. The resulting component should be of high quality and well-functional, providing a clear way of communication in terms of interfaces.

3. Component Certification

At this point the components are outsourced and selected candidate components are tested and verified if they satisfy the system requirements with high reliability.

4. Component Customization

In order for the component to work correctly with the whole system, it has to be adjusted in terms of specific system requirements, platform, performance and interfaces. This process is called customization of a component and the resulting product should be ready for integration.

5. System Design Architecture

This phase requires gathering the requirements of the whole system, defining suitable architecture and appropriate implementation details. The result of this phase should consist of suitable documentation for integration and system requirement for the testing and maintenance phase.

6.  System Integration

The purpose of this phase is integration of the components into one system. It involves component integration and system testing. Sometimes a component has to be adjusted to the whole system and thus requiring the reintegration of all of the components. The resulting system is the final version of the integrated software.

7. System Maintenance

After the system is delivered, it has to be maintained and support for the end-user needs to be provided. This involves for instance, the continuous process of improving system’s performance and correcting faults.

The advantages of component-based software development approach

For the component-base systems to be advantageous over traditional building from scratch paradigm, all of the components should be designed and implemented with the following principles in mind:

  • Reusibility:

The components should be designed in a way that enables them to be used in different applications and different scenarios. This saves a lot of cost and is much more productive since time has to be spent only on customizing an already existing component.

  • Replacability:

Each component should be able to be replaced by a similar one, thus if slightly different functionality is required or the current component is obsolete or no longer suitable, it can be quickly substituted.

  • Lack of context specification

The components need to be designed to be integrated into different environments and contexts.

  • Extensibility:

Each of the components can be further adjusted to provide additional functionality.

  • Encapsulation:

The components can interact using only their interfaces, therefore hiding the local details such as state, processes or variables.

  • Independence:

The components should be appropriate for deployment into any suitable environments, thus they should possess minimal dependencies related to other components. This ensures that the deployment of a particular component do not affect the whole system in any way.

By following above principles, we gain many practical advantages over the traditional approach of building the system from the scratch.

One of the most important ones is the increased productivity and decreased cost of development. This is because the components can be reused by adjusting them to a particular scenario what saves a substantial amount of time and financial resources.

It is also worth noticing that the development of components can be spread over multiple projects that have separate funds, what spreads the development costs as well.

Moreover, the deployment of components is much more efficient, because if the small change is needed, only the affected component will have to be changed and deployed back. In the case of very large systems this can save a lot of time and effort.

Furthermore, the component based paradigm makes the development process much easier. Since the components are isolated, the programmers can work on it independently or in small teams, keeping the level of efficient communication.

The components are much smaller than the size of the whole system, therefore the building process takes much less time increasing the productivity.

Additional advantage is that the components can be written using different languages, hence developers can choose most suitable language for the component’s functionality, again increasing the productivity.

It might be the case that some of the components might require developers with specific business or technical knowledge, and thus they can be assigned specific roles more efficiently, isolating them from unrelated tasks and allowing them to focus on tasks that they are experts with.

Finally, because  the system is split up into independent smaller parts, the complexity is significantly decreased and the testing is made much more easy what positively influences the system’s quality.

Conclusion

In this post, I described the component-based software development paradigm and discussed its advantages in relation to the large scale software development.

The presented paradigm, in contrast with building from scratch approach, allows to reduce both complexity of the software and cost of development while increasing the developers’ productivity and software’s quality.

References:

1. Cai Xia, Michael R. Lyu, Kam-fai Wong, Ada Fu, ”Component-Based Software Engineering: Technologies, Quality Assurance Schemes”

2. Microsoft Developer Network, “Chapter 3: Architectural Patterns and Styles”

Design Patterns from a Junior Developer perspective

Introduction

Almost every software developer will be challenged with designing a software system at some point during their professional career. After designing many of them it becomes obvious that despite different problem domains, many of these systems have something in common – it is easy to observe that they have similar structure and objectives and thus can be designed in a similar way.

Suppose you find yourself in a position of leading the implementation of a large project. How would you deal with designing it? Given that there have been countless systems implemented in the past, it is almost certain that somebody has already solved this problem for you (at least partially).

The first time I heard about design patterns was at workshops organized by Google. During my year in industry in a financial company, I was encouraged by senior developers to practice design patterns while designing a small-scale system. So, I bought myself the “Design Patterns Essentials” book and with both huge excitement and “now I am going to be professional” attitude, tried to fit the patterns into every possible design problem encountered. To my disappointment, after some time, I realized that some of the functionalities were so abstracted that no longer easy to understand, contradicting the widely known “make it simple” principle and leaving me baffled with a “I must have done something wrong in here…” thought.

In this post I would like to use the opportunity to share my experience with design patterns and discuss the way a junior developer can learn how to use them appropriately.

 

What are Design Patterns?

 

Design Patterns are generic, reusable solutions to the frequently occurring software design problems. They are usually categorized into various groups such as creational, structural or behavioural patterns, making it easier to choose the appropriate one for a particular problem. The most simple example is a singleton pattern that ensures the creation of only a single object of a class, providing a single point of access to it.

Suppose you have to implement a message based, sequential communication system between two nodes. In order to be able to follow the order of messages, each of them need to generate a unique sequence number by adding 1 to the previous one. Assuming that there is a sequence generator class, it is essential to make sure that there is only one object of that class, otherwise there is a risk of having multiple numbering sequences. So, in order to prevent this behaviour the constructor of the sequence generator class can be made private and the instantiation of the single object can be done within a static method of that class, managing the creation and access point to that object.

 

When to use design patterns?

 

I think apart from knowing when a particular design pattern can be used, it is crucial to be able to tell whether it should be used at all. It is very hard for junior developers to resist the temptation of using the patterns in every possible situation, ending up with a bunch of complex pattern classes instead of simple, straightforward code. This in fact, is not only a messy code, but the chaos at the structural level – much harder to correct. Even design pattern books, despite their aim to encourage people to use patterns, state, that developers should strive to keep the code simple and not to try to find a pattern to solve a design problem, when a clear and simpler solution can be used. The “You aren’t going to need it” principle of Extreme Programming can be applied to design patterns in the sense, that an additional feature should not be added just for the sake of applying a design pattern. Design Patterns are just another indispensable tool that can be used, but its the developer’s responsibility to use it appropriately.

The perfect example of when the use of pattern might be beneficial is refactoring. It provides an opportunity to analyse the existing code and provide the pattern that improves the structure of the code.

How to learn when to use (appropriate) design patterns?

 

Most junior developers will most possibly go for “code, code, code, make a mess, break something, feel the pain, fix it” approach. Learning on your own mistakes is great, however not very applicable for large-scale, long-term projects, as the misuse of patterns might cause many problems not only for the developer who used the pattern inappropriately, but for other team members as well. While working on the large-scale project it is best to ask a more senior developer for an advice, before applying the pattern.

 

Conclusion

 

In this post I presented my experience with design patterns and described the general problems that might arise while starting to work with them. I think it is very important for junior developers (like myself) to remember that being a professional developer does not mean using fancy tools whenever possible, rather choosing the best tool for the problem, which is called ‘simplicity’ in most cases.

 

 

References:

 

Tony Bevis, “Java Design Pattern Essentials”, Abilityfirst, 2010

Elisabeth Robson, Bert Bates, Kathy Sierra, “Head First Design Patterns”,O’Reilly Media, 2004