Adding docs for factories delegation

This commit is contained in:
Roman Mogilatov 2015-07-20 18:46:45 +03:00
parent 311c15d389
commit 2690d9b9d4
11 changed files with 170 additions and 195 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -1,76 +0,0 @@
Providers delegation
--------------------
Example:
.. code-block:: python
"""Providers delegation example."""
from objects.providers import Factory
from objects.providers import Singleton
from objects.providers import Delegate
from objects.injections import KwArg
class User(object):
"""Example class User."""
def __init__(self, id, name):
"""Initializer.
:param id: int
:param name: str
:return:
"""
self.id = id
self.name = name
class UserService(object):
"""Example class UserService.
UserService has dependency on users factory.
"""
def __init__(self, users_factory):
"""Initializer.
:param users_factory: (objects.providers.Factory) -> User
:return:
"""
self.users_factory = users_factory
def get_by_id(self, id):
"""Return user info by user id."""
return self.users_factory(id=id, name=self._get_name_from_db(id))
def _get_name_from_db(self, id):
"""Return user's name from database by his id.
Main purpose of this method is just to show the fact of retrieving
some user's data from database, so, actually, it simulates work
with database just by merging constant string with provided user's id.
"""
return ''.join(('user', str(id)))
# Users factory and UserService provider:
users_factory = Factory(User)
users_service = Singleton(UserService,
KwArg('users_factory', Delegate(users_factory)))
# Creating several User objects:
user1 = users_service().get_by_id(1)
user2 = users_service().get_by_id(2)
# Making some asserts:
assert user1.id == 1
assert user1.name == 'user1'
assert user2.id == 2
assert user2.name == 'user2'

View File

@ -20,7 +20,6 @@ Nothing could be better than brief example:
"""Example class User."""
# Factory provider creates new instance of specified class on every call.
users_factory = Factory(User)
@ -98,7 +97,6 @@ provided by another factories:
"""Example class Photo."""
# User and Photo factories:
photos_factory = Factory(Photo)
users_factory = Factory(User,
@ -118,7 +116,6 @@ provided by another factories:
assert user1 is not user2
assert user1.main_photo is not user2.main_photo
Next example shows how ``Factory`` provider deals with positional and keyword
``__init__`` context arguments. In few words, ``Factory`` provider fully
passes positional context arguments to class's ``__init__`` method, but
@ -172,7 +169,6 @@ So, please, follow the example below:
"""Example class CreditCard."""
# User, Photo and CreditCard factories:
credit_cards_factory = Factory(CreditCard)
photos_factory = Factory(Photo)
@ -181,10 +177,12 @@ So, please, follow the example below:
KwArg('credit_card', credit_cards_factory))
# Creating several User objects:
user1 = users_factory(1) # Same as: user1 = User(1,
user1 = users_factory(1)
# Same as: user1 = User(1,
# main_photo=Photo(),
# credit_card=CreditCard())
user2 = users_factory(2) # Same as: user2 = User(2,
user2 = users_factory(2)
# Same as: user2 = User(2,
# main_photo=Photo(),
# credit_card=CreditCard())
@ -211,7 +209,6 @@ So, please, follow the example below:
assert user3.main_photo is main_photo_mock
assert user3.credit_card is credit_card_mock
Factory providers and attribute injections
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -250,7 +247,6 @@ Example:
"""Example class CreditCard."""
# User, Photo and CreditCard factories:
credit_cards_factory = Factory(CreditCard)
photos_factory = Factory(Photo)
@ -259,10 +255,12 @@ Example:
Attribute('credit_card', credit_cards_factory))
# Creating several User objects:
user1 = users_factory() # Same as: user1 = User()
user1 = users_factory()
# Same as: user1 = User()
# user1.main_photo = Photo()
# user1.credit_card = CreditCard()
user2 = users_factory() # Same as: user2 = User()
user2 = users_factory()
# Same as: user2 = User()
# user2.main_photo = Photo()
# user2.credit_card = CreditCard()
@ -278,7 +276,6 @@ Example:
assert user1.main_photo is not user2.main_photo
assert user1.credit_card is not user2.credit_card
Factory providers and method injections
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -330,7 +327,6 @@ Example:
"""Example class CreditCard."""
# User, Photo and CreditCard factories:
credit_cards_factory = Factory(CreditCard)
photos_factory = Factory(Photo)
@ -339,10 +335,12 @@ Example:
Method('set_credit_card', credit_cards_factory))
# Creating several User objects:
user1 = users_factory() # Same as: user1 = User()
user1 = users_factory()
# Same as: user1 = User()
# user1.set_main_photo(Photo())
# user1.set_credit_card(CreditCard())
user2 = users_factory() # Same as: user2 = User()
user2 = users_factory()
# Same as: user2 = User()
# user2.set_main_photo(Photo())
# user2.set_credit_card(CreditCard())
@ -358,3 +356,75 @@ Example:
assert user1.main_photo is not user2.main_photo
assert user1.credit_card is not user2.credit_card
Factory providers delegation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``Factory`` provider could be delegated to any other provider via any kind of
injection. Saying in other words, delegation of factories - is a way to inject
factories themselves, instead of results of their calls.
As it was mentioned earlier, ``Injection`` calls ``Factory`` if ``Factory`` is
injectable value. ``Factory`` delegation is performed by wrapping delegated
``Factory`` into special provider type - ``Delegate``, that just returns
``Factory`` itself.
Another one, more *convenient*, method of creating ``Delegate`` for ``Factory``
is just calling ``Factory.delegate()`` method that returns delegate for current
factory.
Example:
.. image:: /images/factory_delegation.png
.. code-block:: python
"""`Factory` providers delegation example."""
from objects.providers import Factory
from objects.injections import KwArg
class User(object):
"""Example class User."""
def __init__(self, photos_factory):
"""Initializer.
:param photos_factory: objects.providers.Factory
:return:
"""
self.photos_factory = photos_factory
self._main_photo = None
super(User, self).__init__()
@property
def main_photo(self):
"""Return user's main photo."""
if not self._main_photo:
self._main_photo = self.photos_factory()
return self._main_photo
class Photo(object):
"""Example class Photo."""
# User and Photo factories:
photos_factory = Factory(Photo)
users_factory = Factory(User,
KwArg('photos_factory', photos_factory.delegate()))
# Creating several User objects:
user1 = users_factory()
user2 = users_factory()
# Making some asserts:
assert isinstance(user1, User)
assert isinstance(user1.main_photo, Photo)
assert isinstance(user2, User)
assert isinstance(user2.main_photo, Photo)
assert user1 is not user2
assert user1.main_photo is not user2.main_photo

View File

@ -13,5 +13,4 @@ All providers are callable. They describe how particular objects are provided.
static
callable
external_dependency
delegation
extending

View File

@ -1,69 +0,0 @@
"""Providers delegation example."""
from objects.providers import Factory
from objects.providers import Singleton
from objects.providers import Delegate
from objects.injections import KwArg
class User(object):
"""Example class User."""
def __init__(self, id, name):
"""Initializer.
:param id: int
:param name: str
:return:
"""
self.id = id
self.name = name
class UserService(object):
"""Example class UserService.
UserService has dependency on users factory.
"""
def __init__(self, users_factory):
"""Initializer.
:param users_factory: (objects.providers.Factory) -> User
:return:
"""
self.users_factory = users_factory
def get_by_id(self, id):
"""Return user info by user id."""
return self.users_factory(id=id, name=self._get_name_from_db(id))
def _get_name_from_db(self, id):
"""Return user's name from database by his id.
Main purpose of this method is just to show the fact of retrieving
some user's data from database, so, actually, it simulates work
with database just by merging constant string with provided user's id.
"""
return ''.join(('user', str(id)))
# Users factory and UserService provider:
users_factory = Factory(User)
users_service = Singleton(UserService,
KwArg('users_factory', Delegate(users_factory)))
# Creating several User objects:
user1 = users_service().get_by_id(1)
user2 = users_service().get_by_id(2)
# Making some asserts:
assert user1.id == 1
assert user1.name == 'user1'
assert user2.id == 2
assert user2.name == 'user2'

View File

@ -7,7 +7,6 @@ class User(object):
"""Example class User."""
# Factory provider creates new instance of specified class on every call.
users_factory = Factory(User)

View File

@ -23,7 +23,6 @@ class CreditCard(object):
"""Example class CreditCard."""
# User, Photo and CreditCard factories:
credit_cards_factory = Factory(CreditCard)
photos_factory = Factory(Photo)
@ -32,10 +31,12 @@ users_factory = Factory(User,
Attribute('credit_card', credit_cards_factory))
# Creating several User objects:
user1 = users_factory() # Same as: user1 = User()
user1 = users_factory()
# Same as: user1 = User()
# user1.main_photo = Photo()
# user1.credit_card = CreditCard()
user2 = users_factory() # Same as: user2 = User()
user2 = users_factory()
# Same as: user2 = User()
# user2.main_photo = Photo()
# user2.credit_card = CreditCard()

View File

@ -0,0 +1,50 @@
"""`Factory` providers delegation example."""
from objects.providers import Factory
from objects.injections import KwArg
class User(object):
"""Example class User."""
def __init__(self, photos_factory):
"""Initializer.
:param photos_factory: objects.providers.Factory
:return:
"""
self.photos_factory = photos_factory
self._main_photo = None
super(User, self).__init__()
@property
def main_photo(self):
"""Return user's main photo."""
if not self._main_photo:
self._main_photo = self.photos_factory()
return self._main_photo
class Photo(object):
"""Example class Photo."""
# User and Photo factories:
photos_factory = Factory(Photo)
users_factory = Factory(User,
KwArg('photos_factory', photos_factory.delegate()))
# Creating several User objects:
user1 = users_factory()
user2 = users_factory()
# Making some asserts:
assert isinstance(user1, User)
assert isinstance(user1.main_photo, Photo)
assert isinstance(user2, User)
assert isinstance(user2.main_photo, Photo)
assert user1 is not user2
assert user1.main_photo is not user2.main_photo

View File

@ -22,7 +22,6 @@ class Photo(object):
"""Example class Photo."""
# User and Photo factories:
photos_factory = Factory(Photo)
users_factory = Factory(User,

View File

@ -39,7 +39,6 @@ class CreditCard(object):
"""Example class CreditCard."""
# User, Photo and CreditCard factories:
credit_cards_factory = Factory(CreditCard)
photos_factory = Factory(Photo)
@ -48,10 +47,12 @@ users_factory = Factory(User,
KwArg('credit_card', credit_cards_factory))
# Creating several User objects:
user1 = users_factory(1) # Same as: user1 = User(1,
user1 = users_factory(1)
# Same as: user1 = User(1,
# main_photo=Photo(),
# credit_card=CreditCard())
user2 = users_factory(2) # Same as: user2 = User(2,
user2 = users_factory(2)
# Same as: user2 = User(2,
# main_photo=Photo(),
# credit_card=CreditCard())

View File

@ -31,7 +31,6 @@ class CreditCard(object):
"""Example class CreditCard."""
# User, Photo and CreditCard factories:
credit_cards_factory = Factory(CreditCard)
photos_factory = Factory(Photo)
@ -40,10 +39,12 @@ users_factory = Factory(User,
Method('set_credit_card', credit_cards_factory))
# Creating several User objects:
user1 = users_factory() # Same as: user1 = User()
user1 = users_factory()
# Same as: user1 = User()
# user1.set_main_photo(Photo())
# user1.set_credit_card(CreditCard())
user2 = users_factory() # Same as: user2 = User()
user2 = users_factory()
# Same as: user2 = User()
# user2.set_main_photo(Photo())
# user2.set_credit_card(CreditCard())