diff --git a/README.md b/README.md index 1231d619..05e01a17 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ __Creational Patterns__: | [abstract_factory](patterns/creational/abstract_factory.py) | use a generic function with specific factories | | [borg](patterns/creational/borg.py) | a singleton with shared-state among instances | | [builder](patterns/creational/builder.py) | instead of using multiple constructors, builder object receives parameters and returns constructed objects | -| [factory_method](patterns/creational/factory_method.py) | delegate a specialized function/method to create instances | +| [factory](patterns/creational/factory.py) | delegate a specialized function/method to create instances | | [lazy_evaluation](patterns/creational/lazy_evaluation.py) | lazily-evaluated property pattern in Python | | [pool](patterns/creational/pool.py) | preinstantiate and maintain a group of instances of the same type | | [prototype](patterns/creational/prototype.py) | use a factory and clones of a prototype for new instances (if instantiation is expensive) | diff --git a/patterns/creational/factory_method.py b/patterns/creational/factory.py similarity index 52% rename from patterns/creational/factory_method.py rename to patterns/creational/factory.py index 74154784..0143854f 100644 --- a/patterns/creational/factory_method.py +++ b/patterns/creational/factory.py @@ -2,17 +2,15 @@ # -*- coding: utf-8 -*- """*What is this pattern about? -The Factory Method pattern can be used to create an interface for a -method, leaving the implementation to the class that gets -instantiated. +A Factory is an object for creating other objects. *What does this example do? The code shows a way to localize words in two languages: English and -Greek. "getLocalizer" is the factory method that constructs a +Greek. "get_localizer" is the factory function that constructs a localizer depending on the language chosen. The localizer object will be an instance from a different class according to the language localized. However, the main code does not have to worry about which -localizer will be instantiated, since the method "get" will be called +localizer will be instantiated, since the method "localize" will be called in the same way independently of the language. *Where can the pattern be used practically? @@ -25,49 +23,57 @@ *References: http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/ -https://fkromer.github.io/python-pattern-references/design/#factory-method -https://sourcemaking.com/design_patterns/factory_method *TL;DR80 Creates objects without having to specify the exact class. """ +from __future__ import unicode_literals +from __future__ import print_function -class GreekGetter(object): +class GreekLocalizer(object): """A simple localizer a la gettext""" def __init__(self): - self.trans = dict(dog="σκύλος", cat="γάτα") + self.translations = {"dog": "σκύλος", "cat": "γάτα"} - def get(self, msgid): + def localize(self, msg): """We'll punt if we don't have a translation""" - return self.trans.get(msgid, str(msgid)) + return self.translations.get(msg, msg) -class EnglishGetter(object): +class EnglishLocalizer(object): + """Simply echoes the message""" - """Simply echoes the msg ids""" - - def get(self, msgid): - return str(msgid) + def localize(self, msg): + return msg def get_localizer(language="English"): - """The factory method""" - languages = dict(English=EnglishGetter, Greek=GreekGetter) - return languages[language]() + """Factory""" + localizers = { + "English": EnglishLocalizer, + "Greek": GreekLocalizer, + } + return localizers[language]() -if __name__ == '__main__': +def main(): + """ # Create our localizers - e, g = get_localizer(language="English"), get_localizer(language="Greek") + >>> e, g = get_localizer(language="English"), get_localizer(language="Greek") + # Localize some text - for msgid in "dog parrot cat bear".split(): - print(e.get(msgid), g.get(msgid)) - -### OUTPUT ### -# dog σκύλος -# parrot parrot -# cat γάτα -# bear bear + >>> for msg in "dog parrot cat bear".split(): + ... print(e.localize(msg), g.localize(msg)) + dog σκύλος + parrot parrot + cat γάτα + bear bear + """ + + +if __name__ == "__main__": + import doctest + doctest.testmod() diff --git a/tests/creational/test_factory_method.py b/tests/creational/test_factory_method.py deleted file mode 100644 index dd6ae66e..00000000 --- a/tests/creational/test_factory_method.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -import unittest -from patterns.creational.factory_method import get_localizer - - -class TestLocalizer(unittest.TestCase): - def setUp(self): - self.e, self.g = get_localizer(language="English"), get_localizer(language="Greek") - - def test_parrot_eng_localization(self): - self.assertEqual(self.e.get('parrot'), 'parrot') - - def test_parrot_greek_localization(self): - self.assertEqual(self.g.get('parrot'), 'parrot') - - def test_dog_eng_localization(self): - self.assertEqual(self.e.get('dog'), 'dog') - - def test_dog_greek_localization(self): - self.assertEqual(self.g.get('dog'), 'σκύλος') - - def test_cat_eng_localization(self): - self.assertEqual(self.e.get('cat'), 'cat') - - def test_cat_greek_localization(self): - self.assertEqual(self.g.get('cat'), 'γάτα') - - def test_bear_eng_localization(self): - self.assertEqual(self.e.get('bear'), 'bear') - - def test_bear_greek_localization(self): - self.assertEqual(self.g.get('bear'), 'bear')