Object-orientation traditionally centers around classes. Objects come into existence through class instantiation.
Alan Kay, however, had a different perspective:
“Object-orientation is not even about classes.”, Alan Kay
As I've demonstrated in my previous articles, object-orientation in its original form — Radical Object-Orientation — primarily concerns functions, especially when implemented with mainstream programming languages. Functions serve as containers for logic and can be connected through unidirectional data flows to realize Alan Kay's fundamental concept: messaging.
This approach bears more resemblance to Functional Programming than to conventional object-orientation.
Nevertheless, classes have their rightful place. More broadly speaking: Modules are essential components in Radical Object-Orientation.
I consider Module a category name. It denotes a container for functions (which themselves contain logic) and data at various levels of granularity, exposing selected elements through an interface while concealing the remainder behind this facade.
Without exploring the detailed rationale behind these granularity levels, here's my perspective on the module hierarchy available in numerous programming languages:
namespace (sometimes equivalent to a file in certain languages)
class
library
package
component
service
These module types can be physically nested: components encompass packages, which contain libraries, which include classes, and so forth.
Unfortunately, the term “module” is frequently used interchangeably with “component”. This creates significant confusion and impedes systematic code design. After careful consideration, I've concluded that “module” should function as the category name, while “component” represents one specific manifestation with distinctive characteristics separating it from other forms like libraries or services.
The purpose of modules
If functions are fundamental in Radical Object-Orientation, why introduce modules? Their purpose is to group parts that share similarities rather than complementary relationships.
Grouping complementary parts into a cohesive whole is known as composition. This is what functions accomplish.
Grouping similar parts into a collective whole is what I define as aggregation.
Both aggregation and composition represent forms of abstraction: they conceal details, thereby elevating the parts to a new conceptual level where they can be comprehended and utilized as a unified entity with its own distinct identity and purpose.
Why aggregate at all? To impose structure on chaos.
Composition enhances convenience. Higher abstractions deliver more accessible services than lower abstractions. Advanced compositions generate higher-level functionality. Compositions improve usability.
Aggregations, by contrast, primarily enhance accessibility. Consider a child's bedroom: socks, pants, t-shirts, toys, shoes, and comic books scattered everywhere. To parents, this appears as complete disorder.
The various items lack immediate accessibility. Though potentially useful once located, finding them proves challenging even for the child who created the disarray.
Enter: Organization. When similar items are aggregated in containers (e.g. boxes, wardrobes), they become easily retrievable when needed. This constitutes order. Pairing matching socks, grouping sock pairs together, arranging pants in one location, collecting t-shirts in a designated box... Even children recognize the superiority of order over chaos when seeking specific items. Naturally, maintaining order requires consistent effort.
Aggregation (modules) makes utility/functionality (functions) accessible.1
This explains why code benefits from order. Organization means creating a structure to support a purpose; here the purpose is accessibility.
Programming languages must provide mechanisms to aggregate valuable code parts. This is the purpose of modules.
Which functions to group in a module?
For now, I'll concentrate on namespaces and classes as primary containers since they specifically group functions. Higher-level modules merely contain lower-level modules and thus incorporate functions only indirectly.
With modules available, the question becomes: Which functions should be grouped together? What constitutes similarity?
Functions exhibit similarity when they share common elements. In my view, these shared elements may include:
shared in-memory state (dependency on data), i.e., reading/writing the same variables
shared data types (dependency on structure), i.e., utilizing the same data compositions2
shared services (dependency on logic), i.e., incorporating identical functions or using the same logic compositions
shared resources, e.g., file access or service connections (dependency on resource)
shared purpose or identical basic responsibility (dependency on decisions derived from requirements, as detailed in the Single Responsibility Principle (SRP).
Functions sharing common elements typically address the same fundamental decisions identified in requirements. Aggregating them thus adheres to the SRP. Functions (or logic) collected within the same modules tend to evolve at similar rates or are frequently used together by clients.
Additionally, since the 1970s, developers have recommended separating concerns into modules (Separation of Concerns (SoC) principle). Typical concerns include user interface, database access, security, logging, domain rules, time and random number generation, and communication with external services.
However, concerns generally operate at a coarse granularity level. Therefore, I recommend following the SRP: identify sufficiently significant decisions in the requirements that justify aggregating relevant functions into modules (and subsequently organizing smaller modules into larger ones).
Don't become fixated on classes, though. Not every module requires instantiation! Static functions remain perfectly valid in Radical Object-Orientation.
for the purpose of understanding, changing, or (re-)using it
Yes, as functions compose logic (or other functions), data structures compose data items (or other data structures). Composition is happening in both aspects of software, behavior and data.







