Hone logo
Hone
Problems

Implementing Singleton Pattern Types in TypeScript

The Singleton pattern is a creational design pattern that restricts the instantiation of a class to a single object. This pattern is useful when you need to ensure that only one instance of a class exists throughout your application, such as managing a database connection or a configuration manager. This challenge asks you to implement different variations of the Singleton pattern using TypeScript's type system to ensure type safety and clarity.

Problem Description

You are tasked with implementing three different variations of the Singleton pattern in TypeScript:

  1. Classic Singleton: A traditional implementation using a private static instance and a getter method to access the single instance.
  2. Singleton with Static Factory: Similar to the classic approach, but uses a static factory method to create and return the single instance. This allows for more control over the instantiation process.
  3. Singleton with Type Safety (using a type alias): This variation focuses on leveraging TypeScript's type system to ensure type safety when working with the Singleton instance. It uses a type alias to represent the Singleton class and its properties.

For each variation, you must:

  • Define a class (or use a type alias) representing the Singleton.
  • Ensure that only one instance of the class can be created.
  • Provide a way to access the single instance (e.g., a static getter or factory method).
  • Include at least one property and one method within the Singleton class.
  • Demonstrate the usage of each Singleton implementation with a simple example.

Examples

Example 1: Classic Singleton

Input:  None (demonstration of usage)
Output:  A single instance of the `Logger` class with a message logged.
Explanation: The `Logger.getInstance().logMessage('Hello, Singleton!')` call returns the same instance of `Logger` regardless of how many times it's called. The message is logged to the console.

Example 2: Singleton with Static Factory

Input: None (demonstration of usage)
Output: A single instance of the `ConfigManager` class with a configuration value retrieved.
Explanation: The `ConfigManager.getConfig().getSetting('apiKey')` call returns the same instance of `ConfigManager`. The `apiKey` setting is retrieved and printed.

Example 3: Singleton with Type Safety

Input: None (demonstration of usage)
Output: A single instance of the `DatabaseConnection` class with a query executed.
Explanation: The `DatabaseConnection.getInstance().executeQuery('SELECT * FROM users;')` call returns the same instance of `DatabaseConnection`. The query is executed (simulated with a console log).

Constraints

  • All implementations must be in TypeScript.
  • Each Singleton variation must be implemented in a separate file or module for clarity.
  • The Singleton class must have at least one property and one method.
  • The code should be well-documented and easy to understand.
  • The type safety implementation must effectively utilize TypeScript's type system to prevent incorrect usage of the Singleton instance.
  • No external libraries are allowed.

Notes

  • Consider using private static variables and getter/factory methods to control instance creation.
  • Think about how to handle potential race conditions if the Singleton is accessed from multiple threads (although this is less of a concern in a typical TypeScript environment).
  • The type safety implementation is the most important part of this challenge. Focus on using TypeScript's features to ensure that the Singleton instance is used correctly and that its properties and methods are accessed with the correct types.
  • The "execution" of the methods (e.g., executeQuery) can be simulated with console logs for simplicity. The focus is on the Singleton pattern implementation itself.
Loading editor...
typescript