added abstract factory pattern
This commit is contained in:
@@ -3,11 +3,10 @@ from abc import abstractmethod, ABCMeta
|
|||||||
|
|
||||||
class Factory(object, metaclass=ABCMeta):
|
class Factory(object, metaclass=ABCMeta):
|
||||||
"""
|
"""
|
||||||
Abstract Factory Class.
|
Factory Interface.
|
||||||
|
|
||||||
All Factories should inherit this class and overwrite the create method.
|
All Factories should inherit this class and overwrite the create method.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def create(self, **kwargs):
|
def create(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
@@ -19,3 +18,37 @@ class Factory(object, metaclass=ABCMeta):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AbstractFactory(object):
|
||||||
|
"""
|
||||||
|
Abstract Factory Class.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
"""
|
||||||
|
Initialize the abstract factory.
|
||||||
|
|
||||||
|
Concrete implementations should call this from within their own __init__ method
|
||||||
|
and register all their factories to keys using the register method.
|
||||||
|
"""
|
||||||
|
self._factories = dict()
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def create(self, **kwargs):
|
||||||
|
"""
|
||||||
|
Abstract create method.
|
||||||
|
|
||||||
|
Concrete implementations should return a new instance of an object by calling the appropriate factory.
|
||||||
|
|
||||||
|
@param kwargs: Arguments for object creation.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _register(self, key, factory):
|
||||||
|
"""
|
||||||
|
Register a factory to a key.
|
||||||
|
|
||||||
|
@param key: Key for identifying which factory to use.
|
||||||
|
@type key: str
|
||||||
|
@param factory: The factory to register to the key.
|
||||||
|
"""
|
||||||
|
self._factories[str(key)] = factory()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from pypatterns.creational.factory import Factory
|
from pypatterns.creational.factory import Factory, AbstractFactory
|
||||||
|
|
||||||
|
|
||||||
class FactoryTestCase(TestCase):
|
class FactoryTestCase(TestCase):
|
||||||
@@ -35,18 +35,6 @@ class FactoryTestCase(TestCase):
|
|||||||
self.cat_factory = CatFactory()
|
self.cat_factory = CatFactory()
|
||||||
self.dog_factory = DogFactory()
|
self.dog_factory = DogFactory()
|
||||||
|
|
||||||
def test_not_implemented(self):
|
|
||||||
"""
|
|
||||||
Test that TypeError is raised when the create method is not overridden.
|
|
||||||
|
|
||||||
@raise AssertionError: If the test fails.
|
|
||||||
"""
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
class EmptyFactory(Factory):
|
|
||||||
pass
|
|
||||||
|
|
||||||
EmptyFactory()
|
|
||||||
|
|
||||||
def test_create(self):
|
def test_create(self):
|
||||||
"""
|
"""
|
||||||
Test the create method.
|
Test the create method.
|
||||||
@@ -61,3 +49,58 @@ class FactoryTestCase(TestCase):
|
|||||||
|
|
||||||
self.assertEquals('Meow', cat.speak())
|
self.assertEquals('Meow', cat.speak())
|
||||||
self.assertEquals('Woof', dog.speak())
|
self.assertEquals('Woof', dog.speak())
|
||||||
|
|
||||||
|
|
||||||
|
class AbstractFactoryTestCase(TestCase):
|
||||||
|
"""
|
||||||
|
Unit testing class for the AbstractFactory class.
|
||||||
|
"""
|
||||||
|
def setUp(self):
|
||||||
|
"""
|
||||||
|
Initialize testing data.
|
||||||
|
"""
|
||||||
|
class Cat(object):
|
||||||
|
def speak(self):
|
||||||
|
return 'Meow'
|
||||||
|
|
||||||
|
class Dog(object):
|
||||||
|
def speak(self):
|
||||||
|
return 'Woof'
|
||||||
|
|
||||||
|
class CatFactory(Factory):
|
||||||
|
def create(self, **kwargs):
|
||||||
|
return Cat()
|
||||||
|
|
||||||
|
class DogFactory(Factory):
|
||||||
|
def create(self, **kwargs):
|
||||||
|
return Dog()
|
||||||
|
|
||||||
|
class AnimalFactory(AbstractFactory):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self._register('cat', CatFactory)
|
||||||
|
self._register('dog', DogFactory)
|
||||||
|
|
||||||
|
def create(self, animal_type):
|
||||||
|
return self._factories[animal_type].create()
|
||||||
|
|
||||||
|
self.cat_class = Cat
|
||||||
|
self.dog_class = Dog
|
||||||
|
self.animal_factory = AnimalFactory()
|
||||||
|
|
||||||
|
def test_create(self):
|
||||||
|
"""
|
||||||
|
Test the create method.
|
||||||
|
|
||||||
|
@raise AssertionError: If the test fails.
|
||||||
|
"""
|
||||||
|
cat = self.animal_factory.create('cat')
|
||||||
|
dog = self.animal_factory.create('dog')
|
||||||
|
|
||||||
|
self.assertEquals(self.cat_class, cat.__class__)
|
||||||
|
self.assertEquals(self.dog_class, dog.__class__)
|
||||||
|
|
||||||
|
self.assertEquals('Meow', cat.speak())
|
||||||
|
self.assertEquals('Woof', dog.speak())
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user