added abstract factory pattern

This commit is contained in:
tylerlaberge
2016-07-24 16:03:55 -04:00
parent cf68b753d7
commit 6c3aedc08b
2 changed files with 91 additions and 15 deletions

View File

@@ -3,11 +3,10 @@ from abc import abstractmethod, ABCMeta
class Factory(object, metaclass=ABCMeta):
"""
Abstract Factory Class.
Factory Interface.
All Factories should inherit this class and overwrite the create method.
"""
@abstractmethod
def create(self, **kwargs):
"""
@@ -19,3 +18,37 @@ class Factory(object, metaclass=ABCMeta):
"""
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()

View File

@@ -1,5 +1,5 @@
from unittest import TestCase
from pypatterns.creational.factory import Factory
from pypatterns.creational.factory import Factory, AbstractFactory
class FactoryTestCase(TestCase):
@@ -35,18 +35,6 @@ class FactoryTestCase(TestCase):
self.cat_factory = CatFactory()
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):
"""
Test the create method.
@@ -61,3 +49,58 @@ class FactoryTestCase(TestCase):
self.assertEquals('Meow', cat.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())