Reusability is a clear principle in software development. However, systematic reuse of software elements is not common in most organizations. Application programmers rarely design and create software elements for possible future reuse. In many agile software development processes, the project teams believe that the development of reusable software elements can slow down the project. This can be a misconception. This chapter examines various ways to reuse software. Three approaches to developing reusable software artifacts from 15 years of experience in the agile development process are presented. The first approach is to create generic programs or configurable frameworks that support similar solutions for a variety of use cases and environments. The reuse of patterns is the second approach presented. Another effective way is to use a model-driven approach with model patterns. These approaches help to speed deployment software. The final product is flexible and can easily be adapted to changes. This is one of the main goals of an agile approach.
An experienced programmer would reuse his / her code written for another project whenever a similar function is needed. In fact, people always use the same solution for similar problems. That is why experience can be very valuable. When implementing a new module, a veteran programmer, after years of observation by the author, often cuts out code fragments from old modules that he / she has written and inserts them into the new module. He / she is usually more efficient and productive as he / she already has experience solving similar problems. Transforming this experience into a set of reusable elements that anyone can use would bring great benefits to overall software development. That's what software reuse is all about.
With advances of software technologies, there are many packages and libraries containing reusable software elements available commercially or open sources. Different business or system units from large organizations usually provide business domain specific or infrastructure related software components and functions (e.g. a function to retrieve customer data, etc.) for application development. Using these software elements in application development forms the common practice of reuse. With decades of experience working for many large organizations, the author finds that it is not a common practice for application programmers to design and build software elements for possible future. When developers have to meet deadlines and provide functionality, building software elements that can be reused is never a priority. In fact, often one can find programs with hard coded values and algorithm that prevent them from being reused in different context without code changes.
In recent years, the agile software development process has become very popular in the software industry (Ambler, 2010; Larman, 2003). In this approach, the emphasis is on providing working software with the highest business values as a measure of the progress of a software project. It prefers functioning software over documentation and customer collaboration over contract negotiation. As a result, so many developers are simply write ad hoc-style code, even though the agile approach does not exclude the value of analysis and design. For many agile development teams, designing and building reusable software elements are out of the question.
Although agile development practice has great advantages in software development, many projects are still failing (Harlow, 2014; Ismail, 2017). When a software element has high reuse potential through configuration and extension, it is flexible and easily adapt to changes. This actually fulfil the motivation of agile software approach that the end system should be flexible and easy to change. The purpose of this chapter to describe the techniques to design and build reusable software artefacts and demonstrate that they bring many benefits. The development process to provide working software can be speeded up. The end product is flexible and easily adaptable to changes, which is one of the main goals in using an agile approach.
The chapter gives a brief survey of software reuse. It presents the general reusable software artefacts with their motivation, implementation concept, consequences and applicability. Specific approaches to develop reusable software artefacts that evolved out of 15 years of experience of agile development practice are described. The approaches include those for “generic programming and configurable framework”, “pattern based reuse” and “model driven approach”. The chapter is organized with a first section on the background of agile software development and reusing software. It is followed by a section on reusable software elements. The three approaches mentioned before will be described in three different sections. The chapter ends with sections on the vision for the future and a final conclusion.
In the background, the first subsection deals with the history of software development and the agile approach. Following is a subsection on reuse based software engineering.
History of Software Development and Agile Approach
In the early days of software history, programmers tended to develop their programs without documentation in an ad-hoc style. As software systems evolved with features over the years, they were no longer serviceable (Software Crisis, 2010). Software engineers argued that software development should not just be coding. Analysis and design with the right documentation are as important as writing code (Software Engineering, 2010). It has gone the extra mile that much effort has been put into requirements specification and design work, resulting in a tremendous amount of documentation. The author has experienced that a number of projects did not survive the requirement specification analysis phase before the budget was exhausted and no single working software was created.
In 2001, a number of prominent software engineers joined forces to create a Manifesto for Agile Software Development (Agile Manifesto Group, 2001). They were not satisfied with the usual software development practices, especially with the extensive documents nobody would read. They came up with 12 principles. Four main principles related to the context of this chapter are:
The agile approach to software development is widespread in the software community. Many agile development methods have been introduced. The most popular are Scrum, Kanban and extreme programming (Stellman & Greene, 2015). In particular, these methods divide the product development work into small increments that minimize the planning and design effort. Iterations are short periods, which usually take one to four weeks. Work software is the primary measure of progress. Program elements from each iteration should be continuously integrated into the system.
The Agile Software Development Manifesto provides only principles for software development. There is no framework for how the development should be done. An agile development method like Scrum provides the blue print of a software development process. However, there is no suggestion on the mechanism how program elements should be developed in each iteration and how they can be continuously integrated into the system.
The 2015 CHAOS report (Hastie & Wojewoda2015) shows that the statistical success rate in agile software development is three times higher than traditional approaches. However, the report also shows that the overall success rate of an agile approach project is only 39%. Despite using the agile approach many projects still fail. This chapter proposes techniques for improving the situation.
Reuse Based Software Engineering
Reuse is a distinct field of study in software engineering. It started with the concept of reusable software components. Early developments in reuse research include the idea of program families and domain analysis concepts (Biggerstaff & Perlis, 1989). Other areas of reuse research include function libraries, methods and tools for domain engineering, design patterns, domain-specific software architecture, components, generators, measurements and experiments, and business and finance (Soora, 2014; Jacobson, et al., 1997). There are also areas of computer science research that are central to reuse: abstract data types and object-oriented methods, programming language theory, software architectures, compilers, models for software development processes, metrics and experiments, and organization theory (Krueger, 1992; Frakes & Kang, 2005; 2015). Reuse can also be applied in the different phases of the software lifecycle, e.g., requirements analysis and specification, software design, implementation, testing and deployment, and product maintenance (Leach, 2011).
There are many approaches to the software reuse concept. In order to organize and place different concepts and models of reuse, a set of conceptual frameworks for the reuse of software has been proposed. Biggerstaff and Richter (1989) propose a framework that divides available reusability technologies into two main groups: composition technologies and generation technologies. Krueger (1992) proposed a framework with four taxonomies for reusable artifacts. The four taxonomies are abstraction, selection, specialization and integration. Another framework developed by Freeman (1987) asked questions such as “what is reused?”, “How should it be reused?” and “What is required to enable a successful reuse?”. His framework defines five levels of reusable information code fragments, logical structure, functional architecture, external knowledge (e.g. knowledge of application domains and software development), and environmental knowledge related to organizational and psychological issues. Other frameworks are based on forms of reuse such as data, code, and design (Horowitz & Munson, 1984; Jones, 1984). Reusable software artifacts include application systems, subsystems or frameworks, components, modules, objects and functions or procedures.
Reusability is a key principle of software engineering. However, as mentioned earlier, application programmers rarely create their programs considering reuse. For reusable software artifacts to be widely reusable, they must be properly documented so that the software project members can use these software artifacts during development. This type of task rarely has priority in the development process. In an agile approach to software development, such a task does not seem to have business value. The project team could assume that reuse would slow down the deployment of working software. As shown in this chapter, it's a mistake to make reusable software artifacts slow down project progress. Rather, it can accelerate. The final product would be flexible and easy to adapt to changes.
Nobody would start a software project from scratch these days. Reuse happens all the time, though the development team may not even notice it. Business concepts, architectures and experiences are used repeatedly. Reusable software elements include application systems, subsystems or frameworks, components, modules, objects and functions or procedures (Sommerville, 2015, Leach, 2011). This section explains how to reuse these reusable elements in the following subsections. Each subsection would contain description, motivation, implementation approach, consequence and applicability of the various reusable elements.
Function and Object Libraries
The simplest reusable software items are libraries that contain callable functions or procedures. Throughout software development history, there are many libraries that provide system-related issues such as input and output (IO), scientific and mathematical calculations, and more.
With the development of object-oriented programming we have libraries with application interfaces (API). When we code with Java, the SDK provides the most basic classes for many functions. The functions are constantly being improved and expanded. For legacy programming languages like COBOL, system vendors like IBM would provide a variety of features for their infrastructure, such as security, communications, and database.
Apart from the libraries provided by vendors or open sources, it is always advisable to develop features that are used repeatedly within an organization. A good example is a Java function that is constantly used to read a file within the project class paths with a specific filename. It was noted that there were a dozen implementations in a financial institution to resolve and validate an International Bank Account Number (IBAN). The same functions but different approaches have been found in different programs. The functions are usually hard-coded within the module that needs them. For a developer to implement such a feature, he / she must first understand the structure and validation algorithm of IBAN. This usually takes longer than coding the function. Functions like these examples should be placed in reusable function libraries.
In general, a function in libraries performs exactly one function and requires one or more input parameters. Normally only one output is provided. Such a function is relatively easy to implement. Most programming languages, such as Javascript, support the development of callable functions. In Java, a class can contain a list of static methods. Each of these methods would perform a single function. In COBOL, a function would be a callable module. Reusable libraries in COBOL are basically a collection of modules. A callable COBOL module can contain COBOL structures for its input and output. Libraries in object-oriented languages usually contain object classes. Each object (instant of a class) would represent a distinct entity, and it would contain methods for operating its properties. For example, a list object has list properties and methods to handle list items. For programmers to use functions or objects from a reusable library, documentation must be provided. The minimum documentation for a function contains a description of the operation and a description of the input and output parameters. Descriptions of the object and all its public methods are required for a class.
In an agile development approach, creating reusable object or function libraries does not contribute to immediate business value. Such an activity appears to burden the project and not bring the benefit of enterprise-wide software development. Often this is a mistake. Similar functions and objects can be used repeatedly in an application. The multiple development of the same function or object, especially from different developers, would require much more effort than documenting and storing in a reusable library. The document would also help the QA team to test the object or feature. A QA team can test a function, object, or module as a black box. It helps to improve the quality of the software system.
System and Application
Objects and functions are small reusable elements. Systems and applications can be reused to a greater extent. For example, an achieving system can be integrated when documents are needed to be achieved in an application.
The development of a new system may involve the reuse of a number of applications. For example, the integration of an Enterprise Resource Planning (ERP) system, a Management Information System (MIS), a Customer Relationship Management (CRM) system, and financial applications can be a new general-purpose system for a business. Thus, users do not have to enter the same data for each application. It is also more user-friendly to have a unique system than a number of independent applications.
Such integration would require changes and extensions to individual applications. Independent applications usually have their own data structure and database. In an integrated environment, data such as that for customers, sales, bookings, etc. must be exchanged or shared between applications. An author's suggested approach is to provide APIs to transfer shared data to and from each application. It should be avoided to extend an application so that it can access data from another application. An agent can be used for this purpose. The agent can provide a communication channel between applications. In addition, a new GUI may need to be developed to ensure a consistent style and navigation for the various applications. Again, the front-end GUI can communicate with the agent, which sends the requests to the applications and sends the output of the applications back to the front-end GUI.
For more examples such as Software Product Lines, Commercial Off-the-shelf (COTS), and ERP systems, see Sommerville's (2015) book. Many systems and applications are available commercially or in open source. There are also companies that develop their own systems.
Component
In most organizations, there is a development team that is responsible for the software of a particular business domain. The team usually provides a set of software components that can be invoked by any application as needed. Components are reusable elements. They have a higher granularity than functions or objects in a function library and are sometimes considered as subsystems. Typically, they provide a set of services or interfaces through which they can be activated. They would perform most if not all activities related to their business domain. A business architecture typically includes a component model. This model shows the components available from various business units with the services or interfaces they provide. The technical architecture provides mechanisms for calling business components.
All classes of a Java programmed component are usually packaged in a JAR, WAR, or EAR file. In a legacy environment with COBOL, modules of a component are packaged together. In a service-oriented system, components can provide services to consumers. This allows components to work together in a cross-platform environment in an application.
Architecture and Framework
Any working software has an architecture, although it may not have been designed by the development team. When we create a simple website, we use the HTML framework with the HTTP protocol. Designing architectures is not an issue for many agile development teams, especially when building web applications using frameworks like Node.js, Lavavel, Vue.js or CMS frameworks like Drupal and Wordpress. All of these frameworks have a solid architecture. Developers must follow the style, structure, and mechanism that the architectures of these frameworks dictate for the integration of their program elements.
Architecture is very important for a corporate IT system. The architecture must set standards and mechanisms for executing specific actions in an application. Logging and exception handling are a good example. Imagine, with a sales order something goes awry and it has been processed by different components in different systems. It would be a nightmare if customer support helpdesk staff had to investigate the problem based on the different types of logs from different systems.
One big mistake that a project can make is that application programmers need to have a deep understanding of the technical infrastructure. Application programmers should focus on business logic that brings business benefits. A set of reusable infrastructure components should be developed separately. They are usually programmed by system programmers. If application programmers can focus only on business logic without having to worry about the infrastructure, they are much more efficient, ultimately increasing the agility to make changes to the final application.
Software architectures are generally associated with frameworks. A software framework is an abstraction in which software that provides generic functions can be selectively changed by additional user-written code, thereby providing application-specific software. It is a standard method of creating and deploying applications and is a universal, reusable software environment that provides certain functionality as part of a larger software platform to facilitate the development of software applications, products and solutions. Software frameworks may include support programs, compilers, code libraries, tool sets, and Application Programming Interfaces (APIs) that merge all the different components to enable the development of a project or system.
Following an agile development practice, application programmers should be able to create individual program elements and integrate them into the system in small, time-limited iterations. Therefore, the architecture or framework would have to provide a plug-and-play mechanism for integrating program elements. When the application programmers finish a module, the module must be integrated into the business process. This must be possible without having to modify existing modules to forward data and invoke the new module. In fact, without a plug-and-play architecture framework, it is very difficult to perform the agile incremental and iterative development process.
An example of a plug-and-play architecture was presented by Pang (2016) for a legacy IT system with COBOL programs. A Java implementation of an architecture framework is presented in the next section.
GENERIC PROGRAMMING AND CONFIGURABLE FRAMEWORK
The original concept of generic programming is the implementation of an algorithm with elements that have more than one interpretation, depending on parameters that represent types (Meyer, 1988). In the Cambridge dictionary, generic is defined as “relating to a whole group of similar things, not a specific thing.” Generic programming deals with the using abstract representations of efficient algorithms, data structures and other software concepts as well as their systematic organization. The goal of generic programming is to express algorithms and data structures in a broad, interoperable form that allows their direct use in software construction.
Generic programming can be applied to all reusable software elements (Kramer & Finkelstein, 1991; Jazayeri et al., 1998). We can have generic systems, applications, architectures and frameworks, services and components, down to generic functions and procedures. In this chapter, generic programming is considered a flexible, monolithic solution that can be used in a variety of applications and environments. It improves extensibility, reusability and compatibility. An in-depth discussion of the full spectrum of generic programming would go beyond the scope of this chapter. This section introduces some general programming techniques that are suitable for agile development. Topics covered are configurable algorithm and framework as well as scripting languages and generic database schema.
Configurable Algorithm and Framework
Generic programming was first supported in programming languages such as ADA. For a function like swapping two elements you can have the following function declaration:
generic type Element_T is private; -- Generic formal type parameter
procedure Swap (X, Y: in out Element_T);
This function can be applied to elements of all kinds. The type is defined dynamically at runtime when the function is used. The generic type is also supported in Java, as shown below for an ArrayList class:
public class ArrayList<E>;
Generic programming is not limited to what a programming language supports in application development. It is also not limited to primitive functions like swap or base class like a list. You can develop an algorithm for one or more activities that require multiple elements and components to work together. The involved elements or components can be configured in a context.
As discussed in the previous section, an agile development process requires a plug-and-play architecture framework. The example presented here is a framework that is based on a finite-state machine in the form of a Java-programmed process control. The steps and processes of the process controller are configured externally. The implementation of such a process controller is shown in the code segment in Figure 1.
The finite-state machine (i.e. the process controller) calls an object based on the actual state and event. An object must provide an event for the transition after completing its task. This event usually depends on the result of the process. If everything is ok, the default event is an “OK” event. This event, along with the status of the process, is used by process control to determine the next object to invoke. This implementation uses the Spring framework. The configuration of the process controller is specified in a text file in JSON (see Figure 2).
Figure 1. Implementation of generic process controller using finite state pattern |
---|
Figure 2. Process descriptor in JSON |
---|
For an object to perform its task, input data is always required. The process controller should be generic and not responsible for transferring data to the objects. A data transfer mechanism can be achieved using a data object container. Each object retrieves data objects that provide the input from that container and fills the output data with the output objects that are eventually stored in the container. The application context of Spring framework can be used as a data object container. Figure 3 shows an example of the Java implementation of an object and the retrieval of data objects from the Application Context of the Spring framework.
Figure 3. Example of data object and its retrieval from spring framework application context |
---|
After implementing an object for a step in the business process in an iteration, the object can be inserted into the configuration of the process controller in the process descriptor file. The design of the business process must ensure that the required data objects are available at runtime when the object is activated by the process controller.
The example above shows the power of generic programming. It shows how a continuous integration of iteratively developed program elements can be achieved. The implementation of the process controller can be used in any business process in any application.
Script Language and Generic Database Schema
In an agile development process, application programmers develop program elements iteratively. Each iteration has a short timeframe and therefore the program elements should be kept rather small. It may happen that the functionality of a program element is small, but the development of the required infrastructure is rather a big task, e.g., designing a database to store persistent data. An application programmer may feel that designing a well-structured database has no business value. Therefore, he / she would save the data in some files without a suitable format. In this case, it would be a nightmare for the other developer who needs to create a search engine for the data.
Most applications require a proper database design. This task would require a detailed analysis of the affected persistent data and the required search mechanisms. Many modules to be developed in later iterations depend on this design. Therefore, the project requires a pre-defined detail design task that does not conform to the concept of an agile development process. One possible solution is a generic database schema.
In a normal database schema, a table is created for each data structure, whose columns are mapped to the fields of the data structure. This would not work for a generic database schema because it has to process different data structures. One solution to this problem is to use a scripting language such as XML or JSON. Instead of storing each field in a separate column, each entry stores a single text in XML or JSON that contains the entire data structure. In other words, the table-based database effectively becomes a document-based database. Document-based databases are a feature of NoSQL. However, most organizations prefer to use mature and stable relational SQL databases, such as IBM DB2, Oracle, MySQL, etc. instead of NoSQL.
The most common SQL relational databases support the storage and indexing of documents. IBM DB2 provides support for XML and JSON documents. MySQL offers Document Store with X DevAPI for JSON documents. They also support transaction processing for documents. It is possible to create a generic module to handle both basic CRUD operations and transactions for various data structures.
An example with Java is worked out here. This example uses simple old Java objects (POJO) to represent data structures. The persistent data processing capabilities provided by the generic Java object are shown in Figure 4. The basic mechanism includes the following. The data structure represented by the POJO is resolved using Java Reflection. Depending on the requested function, a corresponding JSON document is generated using the data structure as well as the data of the POJO. The metadata such as the name of the data structure and the indexed fields are needed to create a new data structure. The function search allows search criteria written in a script such as “age <30 and gender = m”. Other features shown in Figure 4 are quite transparent.
Figure 4. Generic Java persistent object interface |
---|
The use of a document-based database has advantages and disadvantages compared to a table-based database. There are a considerable number of articles that explain the two types of database styles (Chan, 2019; Shiff & Rowe, 2018). The main advantage of the document-based database is that the data schema can be flexibly changed without having to change existing data. With the implementation of a generic module (see Figure 4), application programmers do not need to create individual schemas for their data structures. Programmers do not have to worry about database connection and writing SQL statements to their program elements. It is more suitable for agile development processes.
We live in a world full of patterns. Our habits are nothing more than repeatedly following a series of behavioral patterns. Since the publication of the book by Gamma et al. (1995), software developers have been made aware of patterns that we are constantly using and should be used in software development. A pattern is defined as the solution to a problem in a particular context. A pattern-driven approach would be to identify the problem to be solved and look up the pattern that provides the solution to the problem in the given context.
In software development, there are patterns for the development process, patterns for architectural, structural and behavioral designs, as well as code patterns for implementation and so on. Usage patterns provide a general overview of the use of applications. They help identify the information a business component should deliver and the expected interactions with other components. The pattern-driven approach complements the agile approach to software development in a way that accelerates developmental iterations by avoiding reinventing the wheel at every stage of development.
Patterns can accelerate the development process by providing proven and proven development paradigms. They should be stored in a repository and published so that every developer in the enterprise can access them. This section explains various types of patterns for analysis and business process, architecture and design, and usage and code in the subsections.
Analysis and Business Patterns
In his classic book, Martin Fowler defines a pattern as an “idea that was useful in one practical context and is likely to be useful in others” (Fowler, 1996). He also discusses the analysis paradigm that reflects “conceptual structures of business processes, not actual software implementations.” Analysis patterns are conceptual models that capture an abstraction of a typical situation in modeling. They focus on the organizational, social and economic aspects of a system, as these aspects are central to the requirements analysis and the acceptability and usability of the final system (Geyer-Schulz & Hahsler, 2001).
In addition to business processes, under certain circumstances there may be patterns for conducting analysis. An example is the pattern described by Wake (Wake, 2018) for writing and sharing user stories. The Scrum model can also be viewed as a model for an agile software development process.
Identifying reusable patterns in an IT system can be of great value. Business processes, rules, algorithms and data structures are generally refined and proven over the years. They can be very useful for the future development and improvement of applications. They also provide documentation of the system in operation and materials for training business analysts and developers. In fact, the way companies do business always follows certain patterns. They rarely change, though there may be variations in the details. For example, the business process of a customer business order always includes the following four processes, regardless of the product type for the business:
There are also standard patterns for dealing with errors and exceptions when the validation fails or the time for an offer has expired, etc. The trade validation process also includes standard checks for entitlement, availability, credit and amount limits, and so on. When developing a customer order application for a new product, business analysts can follow these patterns to identify the detail requirements of business process steps and include them as tasks in the product backlog in the Scrum development process.
Architectural and Design Patterns
The concept of the design pattern in software development was first described by Gamma et al. al. (Gamma, 1995). It focuses on finding a reusable solution to a common problem in a particular software design context. It is not intended as a ready-made design that application programmers convert directly to source code. It is more a description of how to solve a problem that can be used in many different situations. Developers still have to adapt the design to their specific requirements.
In the classic book by Gamma et al. there are a number of examples of categories such as creation patterns, texture patterns, and patterns of behavior. The use of delegation, aggregation and consultation concepts is well described. In general, you cannot simply pick up one of these examples with source code and use it as it is. For example, consider a design pattern for facet and decor type enhancements presented by Pang (Pang, 2001). In the example he tries to solve the problem that a university member can be a student or an employee. The member can also be both a student and an employee. Depending on the client's use of the college member object, it may be a student or a co-worker. The exact problem does not occur in most business cases. However, presenting a business partner who is both a customer and a supplier is a similar problem. The solution and much of the featured base code can be used after the solution has been tailored to the problem of each business partner.
Patterns presented in the literature are usually for general purposes. In a corporation for a particular business, there are many design patterns that can be reused in multiple applications. They are domain-specific patterns. An example of a domain-specific pattern is a series of activities involved in the booking process of an order (see below):
Design patterns can also be applied in the software architecture. In fact, there are many well-structured architectural patterns. Some of the most popular are client / server, layer architecture, component-based architecture, event-driven architecture, model-view-controller (MVC), service-oriented architecture (SOA), etc. (Richards 2015). In his book, Fowler presented many patterns for enterprise application architecture (Fowler, 2006). Patterns include object relational mapping, web presentation, concurrency, session state, etc. To design an architecture for an enterprise IT system, it is usually necessary to identify the combination of architectural patterns that meet the requirements (Pang, 2015; Pang, 2016).
Developers should be encouraged to use patterns. They should also be trained to identify the theme and variations of their design and implementation in order to derive patterns that developers can reuse for other applications with similar problems.
Code Patterns and Template
A pattern is usually associated with templates in the form of models or snippets of code. Developers can complete the design or implementation with context-specific elements based on these templates. Note the domain-specific pattern of activities involved in the posting process of a purchase order example in the previous subsection. We can have a code segment as shown in Figure 5.
Figure 5. Code pattern of booking process |
---|
The code segment in Figure 5 uses the symbols $ {xxx} as wildcards. With this code segment, developers can replace all placeholders with correct variable names. With available code segments and reusable templates, developers can finish the code with little effort.
REUSE IN MODEL DRIVEN APPROACH
Software development usually starts with modeling. Models provide abstractions of high-level design concepts and enable communication between software users that code alone cannot. These models are drawn on a flipchart or graphically displayed in a CASE tool. After all, these models become programs in one way or another.
The Object Management Group (OMG) attempts to standardize modeling techniques in software development in a Model Driven Architecture (MDA) (MDA, 2010; Mellor, 2004). MDA is seen as a way to organize and manage enterprise architectures that are supported by automated tools and services to both define the models and facilitate the transformation between different model types. MDA should provide a blueprint for rapid software development. The focus is on rigorous software modeling and code generation from models.
In this section, the first subsection introduces an approach that combines agile practice and model-driven software development. This is followed by a subsection on reusable model patterns. As demonstrated later in this section, the model-driven approach to rapidly deploying workable software is very effective. The final product is flexible and can easily be adapted to changes. This is exactly the goal of an agile development process.
Agile and Model Driven Approach to Software Development
In a recent article titled “no developers required: Why this company chose no-code over software devs” (Clark, 2019), Clark reported:
Agile development process Scrum does not really define how analysis and development should be done. Scrum promoters generally recommend a Product Backlog with a list of all requirements in the form of user stories (Rehkopf, 2019). User stories are selected according to their business value priorities and programmed in consecutive sprint iterations. The question now is how to ensure that user stories can capture all the needs of a complex application, especially if they are small enough to be implemented in a sprint. The second question is how to get a complete overview of business workflow and processes from user stories. User stories are not detailed requirements specifications. Therefore, many negotiations between customers, business analysts and developers are expected to be required. Interestingly enough, many models are being eradicated during these negotiations. Converting the scratched models into formal models that can be converted into codes would be a very effective and fast way to build working software. Converting models to code requires more detailed information and possibly some code segments. This approach has proven to be very successful (Pang, 2016).
Unfortunately, there are only a few modeling tools that can do a complete model code transformation. However, the meta-information of the models can be extracted from most models. In addition to code templates and patterns, domain-specific code generators can be easily created (Pang, 2016). Experience has shown that many application programmers write spaghetti code. Code verification is a tedious and time-consuming task. With a short sprint time frame and an urgent delivery of program elements, this task is often omitted. As a result, the program may be of poor quality and difficult to maintain. On the other hand, you can create spaghetti code, but it would be difficult to create a spaghetti model. Model are easy to change and improve. They are perfect for the documentation. Generated code usually has the same structure and pattern, so it's easy to follow. The construction of code generators initially seems to bring no business benefits. However, measured against the experience of graphical and model-driven approaches, this can bring enormous economic benefits in the long term.
Reusable Model Patterns
Patterns can be abstracted in models. Frequently, code patterns and templates are assigned to the patterns. The domain-specific pattern example shows a number of activities involved in the booking process of an order. An action with parameters symbol can be used to represent this pattern. In a UML activity diagram, an action that should use this pattern may have a link to the pattern icon with constraints indicating the association of the program variables with the parameters. Figure 6 shows the action link to the pattern. The link is also associated with a UML constraint that provides the mapping information of program variables for the placeholders of the example code segment shown in Figure 5.
Figure 6 shows the model of a simple order process. Most of the code is actually provided by the patterns. There is only one action with the stereotype << code >>, which contains a small piece of code. The {thrown exception} constraint for the process indicates that the generated code for the OrderBooking class involves throwing an exception. Based on the model, a complete code for the OrderBooking class can be generated.
Figure 6. Order booking process model |
---|
Business Process Pattern
Patterns can be fine-grained and cover only the design and / or implementation of a particular data or architectural structure, algorithms such as account verification or error logging, or the use of certain elements of software components. It can also cover the entire process of a business process. Take the example of a model for the order validation process in a financial institution. The model can represent an abstraction applied to various order validation such as foreign exchange orders, payment orders, security orders, etc. with some differences. The collaborative business components in the process flow, such as customer information, employee information, product, contract, financial instrument, pricing engine, etc., are similar in different order types. In this way, reusable patterns in the form of models, templates and code snippets can be created, which can be parameterized. Once these patterns exist for a business process, repeating the implementation for another business case can be greatly simplified.
A model for the order validation process is shown in figure 7. From this model, the JSON process descriptor shown in figure 2 can be generated. For the program to work, the implementation of each step of the process flow must follow a specific pattern. For example, it must retrieve input data from the context container and place output data in the context container, as previously described. It must return an event after completion. If an error occurs, an error object must be placed in the context container for the error handler to retrieve it.
As shown in figure 7, the model is pretty simple. Adding new process steps or removing existing process steps is a simple task. It provides a plug-and-play mechanism for continuously integrating new process steps that are developed iteratively.
Figure 7. Order validation process flow model |
---|
Consequences and Project Experience
Creating generic programs and code generators requires development effort. They have no business benefit. However, experience has shown that projects that focus on architecture and reuse are typically completed successfully and quickly (Pang, 2015; Pang, 2016). The code generators and generic programs described in this chapter are actually quite simple to create. They do not require a sophisticated mechanism. In fact, in one of the first projects where the modeling approach was used, the code was created manually in the same way that a code generator should. This step has shown that the approach is feasible when applied to real projects. The first experience with this approach was a project that initially started with a normal programming approach. After one and three-quarter years of development, progress was too slow and there was no sign of completion. Modeling and generic programming approach were introduced to rebuild the project from scratch. It only took four months to complete the project with some primitive code generators installed. When completed, there were 800 change requests. All of them were easy to integrate into the application. Since then, many new applications have been created using the same approach for 15 years. They were all completed on time and within budget.
Many programmers would say that they can write modules and JSON scripts just as fast as modeling and code generation. One key difference is that you can present a model in a meeting with users, business analysts, and stakeholders, and change it immediately. This is not possible with a code. Models are also great for documentation. They give an overview of how the application works. Code written by one programmer is rarely reused by another programmer. Model patterns optimize reuse. In terms of development speed, it should be noted that most of the time when developing a module is not writing the code. Rather, a lot of time is spent figuring out how things should work. With patterns and generic programs, this effort can be reduced enormously.
Code segments of patterns are usually stable after writing, testing and deploying. The reuse of these code segments provides better quality every time to rewrite similar code from scratch. Models are much easier to change than code. It is much easier to see the impact of the model changes than the code. Often, changing the code in one place has unexpected effects on the others. This is usually not the case for models. If you need to set a new business rule for all applications in this pattern, all programs that use this pattern can be easily identified using the CASE tool. On the other hand, it is quite difficult to find all the code in different applications where such a change should be made.
Low-code or no-code development platforms have begun to enter the software community trend. They hold many promises. However, many software developers still believe that they are not suitable for applications with complex, enterprise-specific logic and infrastructure requirements. Large organizations have the most basic logic and business logic and engineering infrastructure components. If they can be identified together with generic programs as reusable elements in the form of model patterns, a low-code or no-code development platform can be developed for an enterprise. This requires further research.
Other important advances in software technologies in recent years have been artificial intelligence, natural language processing and pattern recognition. These technologies can be applied to software development. A future vision is the ability to analyze user requirements, create new business rules, identify program patterns, and then automate application development using these technologies. Research in this area is paying off.
Do not get stuck by reinventing the wheel, but go ahead and build on what has been done. If something has already been done, try reusing it as often as possible. Reuse is an important topic in software development. Because design patterns have been introduced, reuse is not limited to code. It has been extended to analysis and design concepts as well as the way things are to be done.
Despite the benefits of reuse in application development, it is not common for application programmers to develop classes or modules that are reusable. Reuse is always restricted to developers who reuse their own previous works. The popularity of the agile software development approach does not really encourage building reusable software elements. More emphasis has been put on the rapid coding and development of program elements that seem to have the highest business value for end users. Systematic reuse requires engineering and support tools. It has no obvious business value and therefore is not even be considered. This chapter has shown that this is a mistake. The systematic reuse of software elements can improve the software development process, enabling fast delivery of high quality software and easy adaptation to changes.
The main reusable software elements including application systems, subsystems or frameworks, components, modules, objects, and functions or procedures with their motivation, implementation concept, consequences and applicability in agile development process are described in this chapter. Three approaches to develop reusable software artefacts that evolved out of 15 years of experience in agile development process are presented. The first approach is to create generic programs or configurable frameworks that support similar solutions for a variety of use cases and environments. Reuse of pattern is the second approach presented. Another effective way, not just for reuse but for general software development, is to use a model-driven approach with model patterns. These approaches can pave the way for a corporation to have a low-code development platform.
This chapter describes the key reusable software elements, including application systems, subsystems or frameworks, components, modules, objects, and functions or procedures, with their motivation, implementation concept, consequences, and applicability in the agile development process. Three approaches to the development of reusable software artifacts, resulting from 15 years of experience in the agile development process, are presented. The first approach is to create generic programs or configurable frameworks that support similar solutions for a variety of use cases and environments. The reuse of patterns is the second approach presented. Another effective way, not just for reuse but for general software development, is to use a model-driven approach with model patterns. These approaches can pave the way for a corporation to develop a low-code development platform.
To encourage reuse, the development teams must build a culture. It does not come automatically. Development teams need to recognize and enforce the benefits. By training the development team, providing tools and infrastructure for reusable libraries, creating configurable frameworks, adapting the model-driven approach to code generation, and so on, the reuse culture of the development team can evolve.
Agile Manifesto Group. (2001). Manifesto for Agile Software Development. Agile Manifesto. Retrieved July 26, 2010, from http://agilemanifesto.org
Ambler, S. W. (2010). Agile Modeling. Ambysoft. Retrieved July 26, 2010, from http://www.agilemodeling.com/
Biggerstaff, T. J., & Perlis, A. J. (1989). Frontier Series: Software Reusability (Vols. 1-2). New York, N.Y.: ACM Press.
Biggerstaff, T. J., & Richter, C. (1989). Reusability Framework, Assessment, and Directions. Frontier Series: Software Reusability: Vol. I. Concepts and Models . ACM Press.
Chan, M. (2019). SQL vs. NoSQL – what’s the best option for your database needs? Thorn Technologies. Retrieved July 19, 2019, from https://www.thorntech.com/2019/03/sql-vs-nosql
Clark, L. (2019). No developers required: Why this company chose no-code over software devs. ZDNet. Retrieved June 26, 2019, from https://www.zdnet.com/google-amp/article/no-developers-required-why-this-company-chose-no-code-over-software-devs/
Fowler, M. (1996). Analysis Patterns: Reusable Object Models . Boston, MA: Addison-Wesley.
Fowler, M. (2006). Patterns of Enterprise Application Architecture . Boston, MA: Addison-Wesley.
Frakes, W. B., & Kang, K. (2005). Software Reuse Research: Status and Future. IEEE Transactions on Software Engineering , 13(7), 529–536. doi:10.1109/TSE.2005.85
Freeman, P. (1987). Tutorial: Software Reusability . Los Alamitos, CA: IEEE Computer Society Press.
Gamma, E., Helm, R., Johnson, R., & Vlissides, L. (1995). Design Patterns: Elements of Reusable Object-Oriented Software . Reading, MA: Addison-Wesley.
Geyer-Schulz, A., & Hahsler, M. (2001). Software Engineering with Analysis Patterns. CiteSeerX. Retrieved May 26, 2019, from http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.70.8415
Harlow, M. (2014). Coconut Headphones: Why Agile Has Failed. Code Rant. Retrieved December 11, 2014, from http://mikehadlow.blogspot.ch/2014/03/coconut-headphones-why-agile-has-failed.html
Hastie, S., & Wojewoda, S. (2015). Standish Group 2015 Chaos Report - Q&A with Jennifer Lynch. InfoQ. Retrieved from May 26, 2019, from https://www.infoq.com/articles/standish-chaos-2015
Horowitz, E., & Munson, J. B. (1984, September). An Expansive View of Reusable Software. IEEE Transaction on Software Engineering SE , 10(5), 477–487. doi:10.1109/TSE.1984.5010270
Ismail, N. (2017). UK wasting 37 billion a year on failed agile IT projects. Information Age. Retrieved May 26, 2019, from https://www.information-age.com/uk-wasting-37-billion-year-failed-agile-it-projects-123466089/
Jacobson, I., Griss, M., & Jonsson, P. (1997). Software Reuse. Architecture, Process and Organization for Business Success . Reading, MA: Addison Wesley.
Jazayeri, M., Loos, R. G. K., & Musser, D. R. (1998). Generic Programming. In International Seminar on Generic Programming Dagstuhl Castle, Germany. Berlin, Germany: Springer.
Jones, C. (1984). Reusability in programming: A survey of the state of the art. IEEE Transactions on Software Engineering , 10(5), 488–494. doi:10.1109/TSE.1984.5010271
Kramer, J., & Finkelstein, A. (1991). A Configurable Framework for Method and Tool Integration. European Symposium on Software Development Environments and CASE Technology. Retrieved May 26, 2019, from http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.129.7971&rep=rep1&type=pdf
Krueger, C. W. (1992). Software Reuse. ACM Computing Surveys , 24(2), 131–183. doi:10.1145/130844.130856
Larman, C. (2003). Agile and Iterative Development: A Manager’s Guide . Reading, MA: Addison-Wesley.
Leach, R. J. (2011). Software Reuse: Methods, Models, and Costs. Retrieved May 26, 2019, from https://pdfs.semanticscholar.org/700b/83bc8d4a2e4c1d1f4395a4c8fb78462c9f5a.pdf
MDA. (2010). MDA – The Architecture of Choice for a Changing World. OMG. Retrieved July 12, 2017, from https://www.omg.org/mda/
Mellor, S. J., Scott, K., Uhl, A., & Weise, D. (2004). MDA Distilled: Principles of Model-Driven Architecture . Reading, MA: Addison-Wesley.
Meyer, B. (1988). Genericity Versus Inheritance. Journal of Pascal, Ada, & Modula-2, 7(2), 13-30.
Pang, C. Y. (2001). A Design Pattern Type Extension with Facets and Decorators . Journal of Object-Oriented Programming , 13(13), 14–18.
Pang, C. Y. (2015). Ten Years of Experience with Agile and Model Driven Software Development in a Legacy Platform . In Singh, A. (Ed.), Emerging Innovations in Agile Software Development . Hershey, PA: IGI Global.
Pang, C. Y. (2016). An Agile Architecture for a Legacy Enterprise IT System. International Journal of Organizational and Collective Intelligence , 6(4), 65–97. doi:10.4018/IJOCI.2016100104
Rehkopf, M. (2019). User Stories. Atlassian Agile Guide. Retrieved May 22, 2019, from https://www.atlassian.com/agile/project-management/user-stories
Richards, M. (2015). Software Architecture Patterns . Sebastopol, CA: O’Reilly.
Shiff, L., & Rowe, W. (2018). NoSQL vs SQL: Examining the Differences and Deciding Which to Choose. Bmc. Retrieved July 11, 2019, from https://www.bmc.com/blogs/sql-vs-nosql
Software Crisis. (2010). Software Crisis. Wikipedia. Retrieved July 26, 2010, from http://en.wikipedia.org/wiki/Software_crisis
Software Engineering. (2010). Software Engineering. Wikipedia. Retrieved July 26, 2010, from http://en.wikipedia.org/wiki/Software_engineering
Sommerville, I. (2015). Software Engineering (10th ed.). Essex, UK: Pearson Education Limited.
Soora, S. K. (2014). A Framework for Software Reuse and Research Challenges. International Journal of Advanced Research in Computer Science and Software Engineering , 4(8), 441–448.
Stellman, A., & Greene, J. (2015). Learning Agile: Understand SCRUM, XP, Lean, and Kanban . Sebastopol, CA: O'Reilly.
Wake, B. (2018). Back to basics: Writing and splitting user stories. Medium.com. Retrieved May 25, 2019, from https://medium.com/agile-outside-the-box/back-to-basics-writing-and-splitting-user-stories-8903a931499c
Agile Software Development Process, & the Agile Manifesto Group. (2001). Manifesto for Agile Software Development. Agile Manifesto. http://agilemanifesto.org
Ambler, S. W. (2010). Agile Modeling. Ambysoft. Retrieved July 26, 2010, from http://www.agilemodeling.com/
Bass, L., Clements, P., & Kazman, R. (2003). Software Architecture in Practice (2nd ed.). Reading, MA: Addison-Wesley.
Erl, T. (2009). SOA Design Patterns . Upper Saddle River, NJ: Prentice Hall PTR.
Ezran, M., Morisio, M., & Tully, C. (2002). Practical Software Reuse . London, UK: Springer. doi:10.1007/978-1-4471-0141-3
Fowler, M. (1997). Analysis Patterns: Reusable Object Models . Reading, MA: Addison-Wesley.
Fowler, M. (2006). Patterns of Enterprise Application Architecture . Reading, MA: Addison-Wesley.
Gamma, E., Helm, R., Johnson, R., & Vlissides, L. (1995). Design Patterns: Elements of Reusable Object-Oriented Software . Reading, MA: Addison-Wesley.
Garland, J., & Anthony, R. (2003). Large-Scale Software Architecture: A Practical Guide using UML . West Sussex, UK: John Wiley & Son.
Geetha, C., Subramanian, C., & Dutt, S. (2015). Software Engineering . Delhi, India: Pearson Education India.
Hohpe, G., & Woolfe, B. (2004). Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions . Reading, MA: Addison-Wesley.
Hunt, J. (2006). Agile Software Construct . London, UK: Springer.
Larman, C. (2003). Agile and Iterative Development: A Manager’s Guide . Reading, MA: Addison-Wesley.
McGovern, J., Ambler, S. W., Stevens, M. E., Linn, J., Sharan, V., & Jo, E. K. (2003). A Practical Guide To Enterprise Architecture . Upper Saddle River, NJ: Prentice Hall PTR.
Mellor, S. J., Scott, K., Uhl, A., & Weise, D. (2004). MDA Distilled: Principles of Model-Driven Architecture . Reading, MA: Addison-Wesley.
Model-Driven Approach to Software Development. Arlow, J. & Neustadt, I. (2004). Enterprise Patterns and MDA: Building Better Software with Archetype Patterns and UML. Reading, MA: Addison-Wesley.
Shamil, F. R. (2019). Software reuse and software reuse oriented software engineering. T4 Tutorials. Retrieved July 11, 2019, from https://t4tutorials.com/software-reuse-and-software-reuse-oriented-software-engineering/
Sommerville, I. (2015). Software Engineering (10th ed.). Essex, UK: Pearson Education Limited.
Agile Software Development Process: An evolutionary and iterative approach to software development with focuses on adaptation to changes.
COBOL: The programming language designed for commercial business data processing used for applications that often form the backbone of the IT structure in many corporations since 1960.
CRUD (Create, Read, Update, and Delete): Basic functions of a computer database.
Design Pattern: A reusable solution to a common problem in a particular software design context.
Document-Oriented Database: A database designed for storing, retrieving and managing document-oriented information, also known as semi-structured data.
Generic Programming: An implementation of an algorithm with elements that have more than one interpretation, depending on parameters representing types.
JSON (JavaScript Object Notation): An open-standard file format that uses human-readable text to transmit data objects consisting of attribute–value pairs and array data type.
MDA (Model-Driven Architecture): An approach to structuring software specifications that are expressed as models for software design, development, and implementation.
Model-Driven Approach to Software Development: A model centric rather than a code centric approach to software development with code generated from models.
NoSQL: A non-SQL database that provides a mechanism for storage and retrieval of data that is modeled in means other than the tabular relations used in relational databases.
Plain Old Java Object (POJO): An ordinary Java object, not bound by any special restriction and not requiring any class path.
Service-Oriented Architecture (SOA): A technical software architecture that allows client applications to request services from service provider type applications in a host system.
Software Component: A software unit of functionality that manages a single abstraction.
Software Engineering: The application of engineering to the development of software in a systematic method.
Software Reuse: The process of creating software systems from predefined software components.
Spring Framework: An application framework and inversion of control container for the Java platform.
UML (Unified Modeling Language): A general-purpose, developmental, modeling language in the field of software engineering that is intended to provide a standard way to visualize the design of a system.
XML (Extensible Markup Language): A markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable.