Refactor into discrete services pattern

Refactor elements of an IBM Z® application into discrete services.

Refactor into discrete services pattern

← Back to Application modernization patterns

Valuable software applications can provide core business capabilities for many years. Any application that exists for a long period likely has been modified by dozens of developers. Over time, new features are added and problems are fixed, often with varying degrees of planning, testing, and code modularity. Without proper care, this combination of factors can lead to application code that is valuable but challenging to maintain and reuse.

Many organizations rely on applications on IBM Z to run business-critical workloads. These applications remain important to the business, but specific functions or features might require ongoing enhancements while the remainder of the application can be left unchanged and continue to provide value.

Introducing a more modular architecture can allow for rapid change and increased business agility. Refactoring the functions of an application into reuseable components facilitates agile development and enables sharing by both existing and new applications.

Solution and pattern for IBM Z®

IBM Z provides a cloud-native developer experience that is consistent and familiar to all developers. It supports mixed-language environments so that you can use the best language for the purpose and can use open standards-based languages and tools to refactor pieces of applications. For example, you can refactor applications as microservices by using container technology. Where required, refactored services can be deployed in the same runtime environment and run under your existing transaction scopes. IBM Z enables enterprise DevOps with transferable skills.

The “Refactor into discrete services” pattern shows the process and components that are involved to refactor functions into reuseable components so that they can be used by both existing and new applications.

Refactoring is a process of replacing hard-to-maintain code with new code in a stepwise way. It is possible, and often desirable, to refactor so that processing remains on the platform and within the same unit of work. With the mixed-language support in IBM Z, the refactored code can use the same programming language or another language that is better suited to the development team’s skills and the characteristics of the function that is being provided.

The figure shows a schematic of two elements within an application on IBM® z/OS® that were refactored into separate services. In this case, both elements are still hosted on z/OS. One of the new modules is now used both as part of the original application and to provide a service to a new application that is running on IBM Cloud®.

As an example, a bank identified a piece of business logic within a COBOL application that provided calculation results. They refactored this logic into a discrete component. The component was then rewritten in Node.js and the calculation services was improved and made accessible by more applications.

With the “Refactor into discrete services” pattern, you can discover and analyze relationships between application components, data, and jobs to refactor in a safe and efficient manner and target the investment where it provides the most value. The use of thorough, automated testing at each stage can ensure no loss in function. Refactoring can create individual functional services that are easier to maintain, test, and reuse so that you can quickly adapt to changing business requirements.

Advantages

A key business benefit of this pattern is that enterprises can continue to gain value from investment in core applications on IBM Z, which over the years achieved high levels of efficiency and resilience. By focusing the refactoring effort on the aspects of the application that require change and enhancement, enterprises can gain confidence in their ability to evolve the applications in response to rapidly changing business needs.

The ability to refactor into reusable components provides several advantages:

  • Introduce a more modular architecture, enabling rapid change and increased business agility.
  • Use open-standards-based languages and tools; for example, to refactor pieces of applications as microservices by using container technology.
  • Introduce the adoption of a cloud-native developer experience that is consistent and familiar to all developers alongside a modern DevOps approach.
  • Create discrete components that can be accessible to more applications.
  • Gain more benefits depending on language choice. For example, you might have more skills in languages such as Java® or Node.js or offload to IBM® z Integrated Information Processor (zIIP).

What to consider before you refactor

A good starting point for a refactoring project is to identify the functions that give the greatest benefit from refactoring. Consider areas of the application that caused issues, perhaps because newer patterns of business revealed limitations or inefficiencies. Consider also where enhancements are required to satisfy new business opportunities or meet regulatory requirements. Use IBM Application Discovery and Delivery Intelligence (ADDI) to determine where to find those functions and to understand their interactions with the rest of the application.

After you identify a good candidate for refactoring, decide the programming language to use and whether to refactor into a service that remains within the same unit of work scope. For the former consideration, IBM Z runtimes such as CICS® Transaction Server for z/OS and IBM® IMS Transaction Manager support a range of languages. You can choose the language that is best suited for the job and to the skills of your developers. For the latter consideration, weigh the advantages of a more loosely coupled integration with the new service against the advantages of a close integration, where any recoverable changes are committed or rolled back with the rest of the application.

As an example, a financial organization wanted to process new workloads that were driven by web services. The organization refactored a COBOL application to enable it for new workloads that were driven by web services. By using a component that was written in Java, they parsed the incoming web service requests and used the support that was provided by IBM Z for integration with COBOL to drive the COBOL processing. As a result, they benefited from easier handling of the web service requests and economic efficiencies that were enabled by zIIP offload. The portability of Java skills was a key enabler for this project. An alternative approach was to evolve to use OpenAPI-based integration.

IBM Z runtimes such as CICS Transaction Server for z/OS and IMS Transaction Manager provide tight language integration and the ability to be transactional. You can refactor parts of an application into discrete services but still retain the transactional scope of the overall application so that recoverable changes can be committed or rolled back together, maintaining data integrity. This can be the case even where the refactored code uses a different programming language. The original application might already use a mix of languages, choosing the most suitable for the processing involved.

One decision point is to use cloud-native and agile development practices and to incorporate the refactoring development into a DevOps pipeline. IBM Z supports transferrable skills with an integrated DevOps experience and provides solutions for developers that provide a cloud-native developer experience. Such solutions include IBM® Developer for z/OS and IBM® Wazi Developer for Red Hat® CodeReady Workspaces. These integrated development environments provide tools that assist with automated code refactoring. You can use them to clean up code, which increases maintainability, and to promote code reuse by creating callable programs from logic that is selected in an existing program.

As you introduce each refactoring change, use the IBM Z Testing portfolio. It includes IBM Z Virtual Test Platform with Galasa to build, develop, and automate test suites that can run before and after you refactor to ensure that the changes don’t affect the behavior of the application. At the first stage of refactoring, the behavior and function of the application should be the same as before.

What's next

Contributors

Catherine Moxey
IBM STSM for CICS Developer Experience & DevOps

William Alexander
Lead Architect of the IBM Z Dev & Pipeline ART, Lead Architect for Z DevOps initiatives with GBS