On the criteria to be used in decomposing Information Systems

The core activity and skill of an Information Systems architect is to decompose the whole system into subsystems and draw relevant boundaries between them. By subsystem here I mean a software with its own lifecycle, built and run by a team and providing functions to a set of users. The decomposition activity we talk about here should not be confounded with the decomposition of a subsystem into modules, as their objects are different (System of applications vs An application as a system built with modules containing data/classes and operations considered in isolation) even if they share some identical criterias.

The core activity and skill of an Information Systems architect is to decompose the whole system into subsystems and draw relevant boundaries between them. By subsystem here I mean a software with its own lifecycle, built and run by a team and providing functions to a set of users. The decomposition activity we talk about here should not be confounded with the decomposition of a subsystem into modules, as their objects are different (System of applications vs An application as a system built with modules containing data/classes and operations considered in isolation) even if they share some identical criterias.

The goal is to decompose “something” into more manageable chuncks (systems, modules, services, you call it like you want) considering different criteria that are lised in the following sections.

Criterias of decomposition

Responsibility

The different functions provided by the system should be separated and each one should ideally have a single responsibility or purpose. The definition of responsibility is reason for change.

Rate of change

I think it’s mandatory to start an article about Software Decomposition by talking about D.L. Parnas’ seminal paper, “On the Criteria To Be Used in Decomposing Systems into Modules,” which was first published in 1972. Parnas’s paper is a classic in the field of software engineering. In it, Parnas presents a novel design approach at that time, sometimes called “Information Hiding” or “Modular Design”, in which he selects the modules in a way that each module hides a certain design decision which is known to be likely to change. The criterion here is the encapsulation of and control over access to some design decisions.

Language

One of the biggest innovation in IS design in the last years is DDD and its bounded context concept. For an introduction to DDD and bounded context see: TODO

System interface

If we decompose, it means we have to compose those sub-systems or modules into the whole system. How do we compose? what’s the best way to compose parts together? The concept of interface comes into play.
The several systems into an information systems and it brings the concept of interface at playscript inbound and outbound C/Q/E How do we structure and express interface?

Design smells of bad decomposition

Too much responsibilities

Too many entities in a system. I argue that a typical system must have no more that ten entities, very often modelized entities are not really needed and would be better represented as values.

Case study

ChatGPT

Decomposing an information system refers to breaking down the system into its smallest components, such as modules, interfaces, and data, to understand, analyze, modify, and improve the system. Here are some criteria or factors to consider when decomposing an information system:

  1. Functionality: The different functionalities or features provided by the system should be separated. Each function or module should ideally have a single responsibility or purpose, according to the principle of Single Responsibility in software engineering.

  2. Complexity: Components that are complex can often be decomposed further into simpler, smaller components. This aids in better understanding and managing the system.

  3. Coupling and Cohesion: Systems should be decomposed in such a way that there is low coupling (dependence) between different components, and high cohesion (components are closely related and focus on a single task) within each component. This improves maintainability and flexibility of the system.

  4. Consistency: Similar functionalities should be grouped together, and should work in a consistent manner. Consistency across the system makes it easier to understand and use.

  5. Commonality: Parts of the system that are common to multiple functionalities or components can be separated into a shared component. This reduces redundancy and improves maintainability.

  6. Data: Data that is used by the system can be considered as a separate component, which helps in handling data consistently across the system, and in maintaining data integrity.

  7. Scalability: The system should be decomposed in a way that allows for easy scaling up or down as required. For example, if certain components need to handle high loads, those components can be designed so that they can be scaled independently of the rest of the system.

  8. Interfacing: The interactions between different components should be clearly defined. This includes both internal interfaces (between different components of the system) and external interfaces (between the system and its environment).

  9. Technology or Framework Constraints: Depending on the technology or framework used, there might be certain constraints on how the system can be decomposed.

  10. Security: Sensitive parts of the system might be separated from the rest, to improve security. For example, components handling sensitive data could be isolated to minimize the risk of data breaches.

Remember, the ultimate goal of decomposing an information system is to improve understandability, maintainability, scalability, and reliability, while reducing complexity.

DDD Bounded Context

Domain-Driven Design (DDD) is a software development approach that centers the development on core domain logic, domain experts, and domain language, rather than the technical concerns of the system. It provides a structure of practices and terminology for making design decisions to tackle complexity in the heart of software. One key concept in DDD is the Bounded Context.

Bounded Context is a central pattern in Domain-Driven Design, and it serves as the focal point of the strategic design section of DDD. A Bounded Context is a defined part or boundary within the software system where a specific model is implemented and strictly applies. It’s essentially a boundary within which a particular model is defined and applicable.

In a large software system, different teams may use the same word with different meanings. For example, in a retail business, the word ‘order’ might have different meanings for the sales team, the shipping team, and the customer service team. To handle this, DDD proposes that the software system should be divided into different Bounded Contexts, each having their own ubiquitous language, a language structured around the domain model and used by all team members to connect all the activities of the team with the software.

Within each Bounded Context, names and definitions have specific meanings, and the model within the context is consistent and coherent. Interactions between Bounded Contexts are explicit and carefully controlled.

Understanding and defining the Bounded Contexts in your system is a vital step in designing a system using Domain-Driven Design. It helps manage complexity, creates a shared language for the team, and guides the organization of code and database schemas.

abstraction

The entire history of software engineering is one of raising levels of abstraction.