diff --git a/.travis.yml b/.travis.yml index 3e4d7015..95984110 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ script: # Run tests - PYTHONPATH=. nosetests -s -v --with-doctest --with-cov --cover-package . --logging-level=INFO -v . # Actually run all the scripts, contributing to coverage - - ./run_all.sh + - PYTHONPATH=. ./run_all.sh # for now failure in flaking is ignored - flake8 *py || echo "PEP8 the code" diff --git a/README.md b/README.md index 6d637eac..2c12ab47 100644 --- a/README.md +++ b/README.md @@ -13,52 +13,59 @@ __Creational Patterns__: | Pattern | Description | |:-------:| ----------- | -| [abstract_factory](abstract_factory.py) | use a generic function with specific factories | -| [borg](borg.py) | a singleton with shared-state among instances | -| [builder](builder.py) | instead of using multiple constructors, builder object receives parameters and returns constructed objects | -| [factory_method](factory_method.py) | delegate a specialized function/method to create instances | -| [lazy_evaluation](lazy_evaluation.py) | lazily-evaluated property pattern in Python | -| [pool](pool.py) | preinstantiate and maintain a group of instances of the same type | -| [prototype](prototype.py) | use a factory and clones of a prototype for new instances (if instantiation is expensive) | +| [abstract_factory](creational/abstract_factory.py) | use a generic function with specific factories | +| [borg](creational/borg.py) | a singleton with shared-state among instances | +| [builder](creational/builder.py) | instead of using multiple constructors, builder object receives parameters and returns constructed objects | +| [factory_method](creational/factory_method.py) | delegate a specialized function/method to create instances | +| [lazy_evaluation](creational/lazy_evaluation.py) | lazily-evaluated property pattern in Python | +| [pool](creational/pool.py) | preinstantiate and maintain a group of instances of the same type | +| [prototype](creational/prototype.py) | use a factory and clones of a prototype for new instances (if instantiation is expensive) | __Structural Patterns__: | Pattern | Description | |:-------:| ----------- | -| [3-tier](3-tier.py) | data<->business logic<->presentation separation (strict relationships) | -| [adapter](adapter.py) | adapt one interface to another using a white-list | -| [bridge](bridge.py) | a client-provider middleman to soften interface changes | -| [composite](composite.py) | encapsulate and provide access to a number of different objects | -| [decorator](decorator.py) | wrap functionality with other functionality in order to affect outputs | -| [facade](facade.py) | use one class as an API to a number of others | -| [flyweight](flyweight.py) | transparently reuse existing instances of objects with similar/identical state | -| [front_controller](front_controller.py) | single handler requests coming to the application | -| [mvc](mvc.py) | model<->view<->controller (non-strict relationships) | -| [proxy](proxy.py) | an object funnels operations to something else | +| [3-tier](structural/3-tier.py) | data<->business logic<->presentation separation (strict relationships) | +| [adapter](structural/adapter.py) | adapt one interface to another using a white-list | +| [bridge](structural/bridge.py) | a client-provider middleman to soften interface changes | +| [composite](structural/composite.py) | encapsulate and provide access to a number of different objects | +| [decorator](structural/decorator.py) | wrap functionality with other functionality in order to affect outputs | +| [facade](structural/facade.py) | use one class as an API to a number of others | +| [flyweight](structural/flyweight.py) | transparently reuse existing instances of objects with similar/identical state | +| [front_controller](structural/front_controller.py) | single handler requests coming to the application | +| [mvc](structural/mvc.py) | model<->view<->controller (non-strict relationships) | +| [proxy](structural/proxy.py) | an object funnels operations to something else | __Behavioral Patterns__: | Pattern | Description | |:-------:| ----------- | -| [chain](chain.py) | apply a chain of successive handlers to try and process the data | -| [catalog](catalog.py) | general methods will call different specialized methods based on construction parameter | -| [chaining_method](chaining_method.py) | continue callback next object method | -| [command](command.py) | bundle a command and arguments to call later | -| [mediator](mediator.py) | an object that knows how to connect other objects and act as a proxy | -| [memento](memento.py) | generate an opaque token that can be used to go back to a previous state | -| [observer](observer.py) | provide a callback for notification of events/changes to data | -| [publish_subscribe](publish_subscribe.py) | a source syndicates events/data to 0+ registered listeners | -| [registry](registry.py) | keep track of all subclasses of a given class | -| [specification](specification.py) | business rules can be recombined by chaining the business rules together using boolean logic | -| [state](state.py) | logic is organized into a discrete number of potential states and the next state that can be transitioned to | -| [strategy](strategy.py) | selectable operations over the same data | -| [template](template.py) | an object imposes a structure but takes pluggable components | -| [visitor](visitor.py) | invoke a callback for all items of a collection | +| [chain](behavioral/chain.py) | apply a chain of successive handlers to try and process the data | +| [catalog](behavioral/catalog.py) | general methods will call different specialized methods based on construction parameter | +| [chaining_method](behavioral/chaining_method.py) | continue callback next object method | +| [command](behavioral/command.py) | bundle a command and arguments to call later | +| [iterator](behavioral/iterator.py) | traverse a container and access the container's elements | +| [mediator](behavioral/mediator.py) | an object that knows how to connect other objects and act as a proxy | +| [memento](behavioral/memento.py) | generate an opaque token that can be used to go back to a previous state | +| [observer](behavioral/observer.py) | provide a callback for notification of events/changes to data | +| [publish_subscribe](behavioral/publish_subscribe.py) | a source syndicates events/data to 0+ registered listeners | +| [registry](behavioral/registry.py) | keep track of all subclasses of a given class | +| [specification](behavioral/specification.py) | business rules can be recombined by chaining the business rules together using boolean logic | +| [state](behavioral/state.py) | logic is organized into a discrete number of potential states and the next state that can be transitioned to | +| [strategy](behavioral/strategy.py) | selectable operations over the same data | +| [template](behavioral/template.py) | an object imposes a structure but takes pluggable components | +| [visitor](behavioral/visitor.py) | invoke a callback for all items of a collection | +__Fundamental Patterns__: + +| Pattern | Description | +|:-------:| ----------- | +| [delegation_pattern](fundamental/delegation_pattern.py) | an object handles a request by delegating to a second object (the delegate) | __Others__: | Pattern | Description | |:-------:| ----------- | -| [blackboard](blackboard.py) | (architectural model, assemble different sub-system knowledge to build a solution, AI approach - non gang of four pattern) | -| [graph_search](graph_search.py) | (graphing algorithms, not design patterns) | +| [blackboard](other/blackboard.py) | architectural model, assemble different sub-system knowledge to build a solution, AI approach - non gang of four pattern | +| [graph_search](other/graph_search.py) | graphing algorithms - non gang of four pattern | +| [hsm](other/hsm/hsm.py) | hierarchical state machine - non gang of four pattern | diff --git a/behavioral/__init__.py b/behavioral/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/catalog.py b/behavioral/catalog.py similarity index 100% rename from catalog.py rename to behavioral/catalog.py diff --git a/chain.py b/behavioral/chain.py similarity index 100% rename from chain.py rename to behavioral/chain.py diff --git a/chaining_method.py b/behavioral/chaining_method.py similarity index 100% rename from chaining_method.py rename to behavioral/chaining_method.py diff --git a/command.py b/behavioral/command.py similarity index 100% rename from command.py rename to behavioral/command.py diff --git a/iterator.py b/behavioral/iterator.py similarity index 100% rename from iterator.py rename to behavioral/iterator.py diff --git a/mediator.py b/behavioral/mediator.py similarity index 100% rename from mediator.py rename to behavioral/mediator.py diff --git a/memento.py b/behavioral/memento.py similarity index 100% rename from memento.py rename to behavioral/memento.py diff --git a/observer.py b/behavioral/observer.py similarity index 100% rename from observer.py rename to behavioral/observer.py diff --git a/publish_subscribe.py b/behavioral/publish_subscribe.py similarity index 100% rename from publish_subscribe.py rename to behavioral/publish_subscribe.py diff --git a/registry.py b/behavioral/registry.py similarity index 100% rename from registry.py rename to behavioral/registry.py diff --git a/specification.py b/behavioral/specification.py similarity index 100% rename from specification.py rename to behavioral/specification.py diff --git a/state.py b/behavioral/state.py similarity index 100% rename from state.py rename to behavioral/state.py diff --git a/strategy.py b/behavioral/strategy.py similarity index 100% rename from strategy.py rename to behavioral/strategy.py diff --git a/template.py b/behavioral/template.py similarity index 100% rename from template.py rename to behavioral/template.py diff --git a/visitor.py b/behavioral/visitor.py similarity index 100% rename from visitor.py rename to behavioral/visitor.py diff --git a/creational/__init__.py b/creational/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/abstract_factory.py b/creational/abstract_factory.py similarity index 100% rename from abstract_factory.py rename to creational/abstract_factory.py diff --git a/borg.py b/creational/borg.py similarity index 100% rename from borg.py rename to creational/borg.py diff --git a/builder.py b/creational/builder.py similarity index 100% rename from builder.py rename to creational/builder.py diff --git a/factory_method.py b/creational/factory_method.py similarity index 100% rename from factory_method.py rename to creational/factory_method.py diff --git a/lazy_evaluation.py b/creational/lazy_evaluation.py similarity index 100% rename from lazy_evaluation.py rename to creational/lazy_evaluation.py diff --git a/pool.py b/creational/pool.py similarity index 100% rename from pool.py rename to creational/pool.py diff --git a/prototype.py b/creational/prototype.py similarity index 100% rename from prototype.py rename to creational/prototype.py diff --git a/fundamental/__init__.py b/fundamental/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/delegation_pattern.py b/fundamental/delegation_pattern.py similarity index 100% rename from delegation_pattern.py rename to fundamental/delegation_pattern.py diff --git a/other/__init__.py b/other/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/blackboard.py b/other/blackboard.py similarity index 100% rename from blackboard.py rename to other/blackboard.py diff --git a/graph_search.py b/other/graph_search.py similarity index 100% rename from graph_search.py rename to other/graph_search.py diff --git a/other/hsm/__init__.py b/other/hsm/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/classes_hsm.png b/other/hsm/classes_hsm.png similarity index 100% rename from classes_hsm.png rename to other/hsm/classes_hsm.png diff --git a/classes_test_hsm.png b/other/hsm/classes_test_hsm.png similarity index 100% rename from classes_test_hsm.png rename to other/hsm/classes_test_hsm.png diff --git a/hsm.py b/other/hsm/hsm.py similarity index 100% rename from hsm.py rename to other/hsm/hsm.py diff --git a/run_all.sh b/run_all.sh index 1a90150d..50922f3d 100755 --- a/run_all.sh +++ b/run_all.sh @@ -11,8 +11,8 @@ if which coverage > /dev/null; then else COVERAGE='' fi -for f in [^_]*py; do - python $COVERAGE $f || failed+=" $f" +for f in */[^_]*py; do + PYTHONPATH=. python $COVERAGE $f || failed+=" $f" echo "I: done $f. Exit code $?" done; diff --git a/3-tier.py b/structural/3-tier.py similarity index 100% rename from 3-tier.py rename to structural/3-tier.py diff --git a/structural/__init__.py b/structural/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/adapter.py b/structural/adapter.py similarity index 100% rename from adapter.py rename to structural/adapter.py diff --git a/bridge.py b/structural/bridge.py similarity index 100% rename from bridge.py rename to structural/bridge.py diff --git a/composite.py b/structural/composite.py similarity index 100% rename from composite.py rename to structural/composite.py diff --git a/decorator.py b/structural/decorator.py similarity index 100% rename from decorator.py rename to structural/decorator.py diff --git a/facade.py b/structural/facade.py similarity index 100% rename from facade.py rename to structural/facade.py diff --git a/flyweight.py b/structural/flyweight.py similarity index 100% rename from flyweight.py rename to structural/flyweight.py diff --git a/front_controller.py b/structural/front_controller.py similarity index 100% rename from front_controller.py rename to structural/front_controller.py diff --git a/mvc.py b/structural/mvc.py similarity index 100% rename from mvc.py rename to structural/mvc.py diff --git a/proxy.py b/structural/proxy.py similarity index 100% rename from proxy.py rename to structural/proxy.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/test_abstract_factory.py b/tests/test_abstract_factory.py similarity index 95% rename from test_abstract_factory.py rename to tests/test_abstract_factory.py index c43b655a..095b2fa9 100644 --- a/test_abstract_factory.py +++ b/tests/test_abstract_factory.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from abstract_factory import PetShop, Dog, Cat, DogFactory, CatFactory +from creational.abstract_factory import PetShop, Dog, Cat, DogFactory, CatFactory import sys if sys.version_info < (2, 7): diff --git a/test_adapter.py b/tests/test_adapter.py similarity index 97% rename from test_adapter.py rename to tests/test_adapter.py index 1961127d..da3fdc38 100644 --- a/test_adapter.py +++ b/tests/test_adapter.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -from adapter import Dog, Cat, Human, Car, Adapter +from structural.adapter import Dog, Cat, Human, Car, Adapter import sys if sys.version_info < (2, 7): diff --git a/test_borg.py b/tests/test_borg.py similarity index 95% rename from test_borg.py rename to tests/test_borg.py index 97470eaf..66af05dc 100644 --- a/test_borg.py +++ b/tests/test_borg.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -from borg import Borg, YourBorg +from creational.borg import Borg, YourBorg import sys if sys.version_info < (2, 7): diff --git a/test_bridge.py b/tests/test_bridge.py similarity index 96% rename from test_bridge.py rename to tests/test_bridge.py index c4db5e8c..7a1f44f0 100644 --- a/test_bridge.py +++ b/tests/test_bridge.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from bridge import DrawingAPI1, DrawingAPI2, CircleShape +from structural.bridge import DrawingAPI1, DrawingAPI2, CircleShape from sys import version_info if version_info < (2, 7): # pragma: no cover diff --git a/test_command.py b/tests/test_command.py similarity index 91% rename from test_command.py rename to tests/test_command.py index 584b273b..4c2adeae 100644 --- a/test_command.py +++ b/tests/test_command.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -from command import MoveFileCommand +from behavioral.command import MoveFileCommand import os, shutil, subprocess, sys if sys.version_info < (2, 7): @@ -25,8 +25,8 @@ def setUpClass(self): - get the temporary test directory - and initializes the command stack. """ - os.mkdir('test_command') - open('test_command/foo.txt', 'w').close() + os.mkdir('tests/test_command') + open('tests/test_command/foo.txt', 'w').close() self.__get_test_directory() self.command_stack = [] self.command_stack.append(MoveFileCommand(os.path.join(self.test_dir, 'foo.txt'), os.path.join(self.test_dir, 'bar.txt'))) @@ -54,7 +54,7 @@ def tearDownClass(self): """ Remove the temporary directory /test_command and its content. """ - shutil.rmtree('test_command') + shutil.rmtree('tests/test_command') if __name__ == "__main__": unittest.main() diff --git a/test_flyweight.py b/tests/test_flyweight.py similarity index 96% rename from test_flyweight.py rename to tests/test_flyweight.py index 11017ad5..dfb9c635 100644 --- a/test_flyweight.py +++ b/tests/test_flyweight.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from flyweight import Card +from structural.flyweight import Card from sys import version_info if version_info < (2, 7): # pragma: no cover diff --git a/test_hsm.py b/tests/test_hsm.py similarity index 98% rename from test_hsm.py rename to tests/test_hsm.py index 79e38440..c9cff983 100644 --- a/test_hsm.py +++ b/tests/test_hsm.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -from hsm import HierachicalStateMachine, UnsupportedMessageType,\ +from other.hsm.hsm import HierachicalStateMachine, UnsupportedMessageType,\ UnsupportedState, UnsupportedTransition, Active, Standby, Suspect, Failed from sys import version_info diff --git a/test_observer.py b/tests/test_observer.py similarity index 96% rename from test_observer.py rename to tests/test_observer.py index 733ee633..25456041 100644 --- a/test_observer.py +++ b/tests/test_observer.py @@ -3,7 +3,7 @@ import sys from io import StringIO -from observer import Subject, Data, DecimalViewer, HexViewer +from behavioral.observer import Subject, Data, DecimalViewer, HexViewer if sys.version_info < (2, 7): import unittest2 as unittest diff --git a/test_proxy.py b/tests/test_proxy.py old mode 100755 new mode 100644 similarity index 98% rename from test_proxy.py rename to tests/test_proxy.py index 839b4130..8df407e3 --- a/test_proxy.py +++ b/tests/test_proxy.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from proxy import Proxy, NoTalkProxy +from structural.proxy import Proxy, NoTalkProxy import sys from time import time diff --git a/test_publish_subscribe.py b/tests/test_publish_subscribe.py similarity index 97% rename from test_publish_subscribe.py rename to tests/test_publish_subscribe.py index 962a1299..8b30a0f1 100644 --- a/test_publish_subscribe.py +++ b/tests/test_publish_subscribe.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- from sys import version_info -from publish_subscribe import Provider, Publisher, Subscriber +from behavioral.publish_subscribe import Provider, Publisher, Subscriber if version_info < (2, 7): # pragma: no cover import unittest2 as unittest diff --git a/test_state.py b/tests/test_state.py similarity index 98% rename from test_state.py rename to tests/test_state.py index e96f8fbe..49167032 100644 --- a/test_state.py +++ b/tests/test_state.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -from state import Radio +from behavioral.state import Radio import sys if sys.version_info < (2, 7): diff --git a/test_strategy.py b/tests/test_strategy.py similarity index 92% rename from test_strategy.py rename to tests/test_strategy.py index 22bfe43d..d569c5c5 100644 --- a/test_strategy.py +++ b/tests/test_strategy.py @@ -21,7 +21,7 @@ def test_print_output(self): The expected_output is equivalent to the output on the command line when running 'python strategy.py'. """ - output = subprocess.check_output(["python", "strategy.py"]) + output = subprocess.check_output(["python", "behavioral/strategy.py"]) expected_output = os.linesep.join([ 'Strategy Example 0', 'Strategy Example 1 from execute 1',