Catalogue¶
This module provides a Catalogue class, which serves as a versatile registry for different types of items. It’s akin to a factory in the sense that it allows for the creation and management of various objects. However, unlike a standard factory pattern that encapsulates object creation, Catalogue focuses more on object registration and retrieval, aligning with the strategy pattern where it helps in maintaining a collection of strategies (or items) for dynamic usage.
The Catalogue class differs from a standard factory by enabling registration and de-registration of items at runtime, thus offering more flexibility. This feature is particularly useful in scenarios where the behavior of a system needs to be extended or modified without altering the existing code structure.
This utility class ensures consistent, factory/strategy-like behavior across multiple parts of the codebase, facilitating easier management and scalability of the system.
Simple Usage Examples (Doctest):¶
>>> from pumas.architecture.catalogue import Catalogue
>>> class MyItem:
... pass
>>> # Registering am instance of a class
>>> catalogue = Catalogue(MyItem)
>>> catalogue.register("item1", MyItem())
>>> "item1" in catalogue.list_items()
True
>>> # Using the decorator for registration
>>> @catalogue.register_decorator("decorated_item")
... class DecoratedItem(MyItem):
... pass
>>> "decorated_item" in catalogue.list_items()
True
>>> # Registering a callable (function) as an item
>>> from typing import Callable
>>> def my_function():
... return "Functionality"
>>> catalogue_callable = Catalogue(Callable)
>>> catalogue_callable.register("my_function", my_function)
>>> callable(catalogue_callable.get("my_function"))
True
>>> catalogue_callable.get("my_function")()
'Functionality'
>>> # Registering a concrete class of an abstract base class
>>> from abc import ABC, abstractmethod
>>> class AbstractItem(ABC):
... @abstractmethod
... def do_something(self):
... pass
>>> class ConcreteItem(AbstractItem):
... def do_something(self):
... return "Done"
>>> catalogue_abc = Catalogue(AbstractItem)
>>> concrete_item = ConcreteItem()
>>> catalogue_abc.register("concrete_item", concrete_item)
>>> catalogue_abc.get("concrete_item").do_something()
'Done'