diff --git a/docs/providers/factory.rst b/docs/providers/factory.rst index 9b7f3904..693ec35a 100644 --- a/docs/providers/factory.rst +++ b/docs/providers/factory.rst @@ -147,4 +147,38 @@ Listing of ``example.py``: :language: python :linenos: +Factory aggregate providers +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:py:class:`FactoryAggregate` provider is a special type of provider that +aggregates other :py:class:`Factory` providers. + +.. note:: + + :py:class:`FactoryAggregate` is not overridable. Calling of + :py:meth:`FactoryAggregate.override` will result in raising of an + expection. + +Next prototype might be the best demonstration of +:py:class:`FactoryAggregate` features: + +.. literalinclude:: ../../examples/providers/factory_aggregate/prototype.py + :language: python + :linenos: + +Example below shows one of the :py:class:`FactoryAggregate` use cases, when +concrete implementation (game) must be selected based on dynamic input (CLI). + +Listing of ``games.py``: + +.. literalinclude:: ../../examples/providers/factory_aggregate/games.py + :language: python + :linenos: + +Listing of ``example.py``: + +.. literalinclude:: ../../examples/providers/factory_aggregate/example.py + :language: python + :linenos: + .. disqus:: diff --git a/examples/providers/factory_aggregate/example.py b/examples/providers/factory_aggregate/example.py index 2c57e62c..53fe69eb 100644 --- a/examples/providers/factory_aggregate/example.py +++ b/examples/providers/factory_aggregate/example.py @@ -13,15 +13,17 @@ game_factory = providers.FactoryAggregate(chess=providers.Factory(Chess), if __name__ == '__main__': game_type = sys.argv[1].lower() + player1 = sys.argv[2].capitalize() + player2 = sys.argv[3].capitalize() - selected_game = game_factory.create(game_type) + selected_game = game_factory(game_type, player1, player2) selected_game.play() - # $ python example.py chess - # Playing chess - - # $ python example.py checkers - # Playing checkers - - # $ python example.py ludo - # Playing ludo + # $ python example.py chess John Jane + # John and Jane are playing chess + # + # $ python example.py checkers John Jane + # John and Jane are playing checkers + # + # $ python example.py ludo John Jane + # John and Jane are playing ludo diff --git a/examples/providers/factory_aggregate/games.py b/examples/providers/factory_aggregate/games.py index c9662b74..f7627496 100644 --- a/examples/providers/factory_aggregate/games.py +++ b/examples/providers/factory_aggregate/games.py @@ -1,12 +1,18 @@ -"""Example module.""" +"""Example games module.""" class Game(object): """Base game class.""" + def __init__(self, player1, player2): + """Initializer.""" + self.player1 = player1 + self.player2 = player2 + def play(self): """Play game.""" - print('Playing {0}'.format(self.__class__.__name__.lower())) + print('{0} and {1} are playing {2}'.format( + self.player1, self.player2, self.__class__.__name__.lower())) class Chess(Game): diff --git a/examples/providers/factory_aggregate/prototype.py b/examples/providers/factory_aggregate/prototype.py index 2de72c3c..08ebed3d 100644 --- a/examples/providers/factory_aggregate/prototype.py +++ b/examples/providers/factory_aggregate/prototype.py @@ -6,19 +6,12 @@ class FactoryAggregate(object): def __init__(self, **factories): """Initializer.""" - self._factories = factories + self.factories = factories + + def __call__(self, factory_name, *args, **kwargs): + """Create object.""" + return self.factories[factory_name](*args, **kwargs) def __getattr__(self, factory_name): - """Return factory.""" - if factory_name not in self._factories: - raise AttributeError('There is no such factory') - return self._factories[factory_name] - - def create(self, factory_name, *args, **kwargs): - """Create object.""" - if factory_name not in self._factories: - raise AttributeError('There is no such factory') - - factory = self._factories[factory_name] - - return factory(*args, **kwargs) + """Return factory with specified name.""" + return self.factories[factory_name]