Factory and Clarification of the Multiton Pattern
Factory
If you ask an ABAP developer to name design patterns, the first answer is almost always Singleton. The second one is usually Factory. After that, you might hear Facade, Strategy, or maybe Template Method. But Singleton and Factory tend to dominate interviews and discussions because they touch the core of object-oriented thinking: controlled instantiation and separation of responsibilities.

The Factory pattern focuses on one specific problem that appears surprisingly often in ABAP systems: who is responsible for creating objects? At first glance, object creation seems trivial. You write CREATE OBJECT or NEW, and you move on. In real enterprise systems, however, creation logic is rarely that simple. It depends on customizing entries, system client, document type, user role, feature switches, or even complex environment rules. When this decision logic is scattered across reports and classes, the system becomes fragile and difficult to extend.

Imagine a large ABAP application that processes business documents such as invoices, credit memos, and debit notes. In a poorly structured solution, every report or service contains a CASE statement deciding which processor class to instantiate. That same decision block is duplicated in multiple places. If tomorrow the selection logic changes because a new customizing table determines the processor dynamically, every single occurrence must be updated. Adding a new document type forces you to modify all consumers. This directly violates the Open-Closed Principle and creates tight coupling between callers and concrete class names.

The typical structure looks like this: a client calls a factory, the factory returns an implementation of a shared interface, and the client executes business logic through that interface. The decision logic is centralized and protected inside the factory.
This centralization reduces duplication and enforces architectural clarity. It also simplifies testing. Instead of mocking concrete classes everywhere, you can replace the factory or inject test implementations through it. The business flow stays clean because it does not carry environment-dependent decision logic.
There are several variations of the pattern.

The Factory Method - the method inside particular class that returns the instance/s ( used a lot with Singleton and Multiton).
The Factory - separate class that is in charge of instances of other classes creation.
The Abstract Factory pattern introduces an additional abstraction level, effectively becoming a factory of factories. It provides an interface for creating families of related objects without specifying their concrete classes.

To illustrate the Factory pattern in a simple and transparent way, the example implementation consists of three main building blocks: a common interface, two concrete calculation classes, and one factory class responsible for instantiation
At the core lies the interface zif_calc_logic. It defines the contract that all calculation implementations must follow. In this case, the contract contains a single method responsible for calculating a result based on an input amount. The client never works with concrete classes directly. It only depends on this interface, which keeps the design loosely coupled and extensible.

The first concrete implementation, zcl_tax_calculator, represents tax calculation logic. It implements the shared interface and provides its own calculation rule, multiplying the input amount by a tax factor. The second implementation, zcl_discount_calculator, follows the same structure but applies a discount rule instead. Both classes are independent from the client and from each other. They share behavior only through the interface.

The central element of the pattern is zcl_calc_factory. This class encapsulates the decision logic for object creation. Its constructor is private, which prevents direct instantiation and enforces access exclusively through the static factory method get_calculator. The method receives a calculation type as input and returns a reference to the interface. Internally, it decides which concrete class to instantiate. If the type is unknown, it raises a domain-specific exception.

The full code of the example classes you can check here: https://github.com/JuliaBerteneva/Factory.git
"Usage
DATA(lo_calc) = zcl_calc_factory=>get_calculator( 'TAX' ).
DATA(lv_final_price) = lo_calc->calculate( 100 ).
Multiton
The Multiton pattern is a creational pattern that ensures controlled instantiation of a class by allowing exactly one instance per unique key. Instead of enforcing a single global instance, as in the case of Singleton, it maintains a registry of instances, each associated with a specific identifier. When a client requests an object for a given key, the class checks whether an instance for that key already exists. If it does, the existing reference is returned. If not, a new instance is created, stored in the registry, and then returned. In ABAP, this is typically implemented using a static internal table of object references indexed by the key, with access provided through a static method such as get_instance.

The purpose of Multiton is not to decide which subclass to instantiate, but to guarantee controlled uniqueness within the same class. It addresses scenarios where multiple logical contexts exist, yet each context must be represented by exactly one shared object. The pattern centralizes lifecycle management and prevents uncontrolled object creation while still allowing multiple instances in a structured and predictable way.

The Multiton pattern ensures that exactly one instance exists for each unique identifier or category. It provides a global access point to a map of named instances. In ABAP, this usually means a static internal table inside a class that stores object references indexed by a key.

Example of classes implementation can be checked here: https://github.com/JuliaBerteneva/Multiton.git
"Usage
DATA(lo_sales)   = zcl_module_logger=>get_instance( 'SALES' ).
DATA(lo_finance) = zcl_module_logger=>get_instance( 'FINANCE' ).

lo_sales->info(  'Sales order created: 4711' ).
lo_sales->warn(  'Pricing condition missing, fallback applied' ).

lo_finance->info( 'FI document posted: 1900001234' ).
lo_finance->error( 'Tax code not allowed for company code 1000' ).

"Same instance returned again for the same key:
DATA(lo_sales2) = zcl_module_logger=>get_instance( 'sales' ).
ASSERT lo_sales2 = lo_sales.

"Buffers are separate:
lo_sales->flush_to_list( ).
lo_finance->flush_to_list( ).
So why is it also mentioned here in the context of the Factory pattern?
Multiton is often mentioned in the same discussions as the Factory pattern because of its structural similarities. The access point is usually implemented as a static factory method, and this has led to alternative names such as “Singleton Factory” or “Object Pool.” These terms, however, are not entirely accurate. They tend to blur the conceptual boundaries between patterns. The fact that a Multiton internally uses a factory method for controlled instantiation does not transform it into a Factory pattern. The naming overlap is historical and practical, but it should not obscure the actual intent of the pattern.

The distinction becomes clearer when responsibilities are compared. A Factory pattern focuses on object creation logic. Its goal is to encapsulate the instantiation process and decide which implementation to return. It does not necessarily enforce uniqueness. A Singleton ensures that exactly one instance of a class exists in a given context. A Multiton, in contrast, ensures that exactly one instance exists per key within the same class. It does not manage different subclasses, but rather multiple controlled instances of itself.

In practice, these patterns are often combined. A Multiton may internally rely on a factory method. A Factory may return Singleton instances. Real-world design rarely follows textbook isolation of patterns. The primary objective is always clarity of structure and clean code. Patterns serve as a vocabulary that helps describe architectural decisions.

However, patterns also function as a compact way of describing your design decisions. They become a shared vocabulary for communicating how your solution is structured. In that context, precise naming matters. When you say that you created a Singleton Factory, the natural expectation is that you implemented a factory class responsible for returning a unique instance per class it manages. When you say that you implemented a Multiton with a factory method, the expectation is different: it implies a single class that exposes something like a get_instance method and internally stores and returns unique instances of itself per key.

The implementation details may look similar on the surface, especially since a Multiton typically uses a static factory method internally. But the architectural meaning is not the same. If patterns are used to represent and explain your project, or to describe how your implementation works, accurate terminology becomes essential. It directly affects how others understand your design and the responsibilities assigned within your architecture.
Made on
Tilda