123
creational

Multiton

Reference Wikipedia ↗
Multiton — class diagram
Plate 123 class diagram

The Multiton pattern is a variation of the Singleton pattern. While a Singleton restricts the instantiation of a class to only one instance, a Multiton allows a limited number of instances. This is useful when multiple instances are needed to represent different, but related, states or configurations without allowing unlimited creation. The Multiton controls the number of instances created and manages access to them.

It differs from a simple factory in that the Multiton remembers the created instances and provides access to them, whereas a factory simply creates and returns new instances each time. This pattern ensures that only a predefined number of instances of a class exist throughout the application lifecycle, improving resource management and potentially simplifying coordination between these instances.

Usage

The Multiton pattern is useful in scenarios where:

  • Limited Resources: You need to control the number of instances of a resource-intensive class to prevent performance issues or resource exhaustion. For example, database connection pools.
  • Configuration Management: You need to manage a small set of configuration objects, each representing a different environment or setting.
  • Load Balancing: You want to distribute work across a fixed number of worker instances.
  • Regional Servers: Managing a limited number of server instances in different geographical regions.

Examples

  1. Database Connection Pool: Many database libraries utilize a Multiton-like approach to manage a pool of database connections. Instead of creating a new connection for every request, the pool maintains a limited number of connections, reusing them to improve performance and reduce overhead. Libraries like HikariCP or Apache DBCP implement this concept.

  2. Log Managers with Multiple Log Files: A logging framework might use a Multiton to manage a fixed number of log files. Each instance of the Multiton represents a different log file (e.g., one for errors, one for warnings, one for information). This allows for organized logging without the overhead of creating a new file handler for every log message. Log4j2 and similar frameworks can be configured to behave in this manner.

Specimens

15 implementations
Specimen 123.01 Dart View specimen ↗

The Multiton pattern ensures that only a limited number of instances of a class can exist. It’s a relaxed version of the Singleton pattern. This is achieved by maintaining a static list or map to store the instances and controlling the instance creation process. The code uses a static, private map to hold the instances, keyed by a string identifier. getInstance() checks if an instance with the given key exists; if not, it creates one and adds it to the map. This implementation is idiomatic Dart as it leverages Dart’s strong typing, private members (_), and the use of maps for flexible instance management, avoiding unnecessary class hierarchies.

class Multiton {
  static final Map<String, Multiton> _instances = <String, Multiton>{};

  final String _key;

  // Private constructor to prevent direct instantiation
  Multiton._(this._key);

  // Public factory method to get an instance
  factory Multiton(String key) {
    if (_instances[key] == null) {
      _instances[key] = Multiton._(key);
    }
    return _instances[key];
  }

  // Example method
  void doSomething() {
    print('Multiton instance with key $_key is doing something.');
  }

  // Optional: Method to get the number of instances
  static int instanceCount() {
    return _instances.length;
  }
}

void main() {
  final instance1 = Multiton('A');
  final instance2 = Multiton('A'); // Returns the same instance as instance1
  final instance3 = Multiton('B');
  final instance4 = Multiton('C');

  instance1.doSomething();
  instance3.doSomething();

  print('Number of instances: ${Multiton.instanceCount()}'); // Output: 3
}