Search code examples
pythondesign-patternsraspberry-pichain-of-responsibility

Is chain of responsibility design pattern suitable for Python solution operating over hardware components


I have an OOP solution written in Python which is mostly focused on managing different kind of hardware components such as camera, servo, proximity sensors etc.

What I have is a bunch of operation managers. An operation manager is basically a class which has more than one public methods defined inside of it. The rules I have defined are as follows:

1. Different operation managers can call each other’s public methods
2. Multiple operation managers are involved into one specific use-case
3. Operation manager's method execution depends on the result of the previous operation manager (if previous was successfully executed - execute this one, otherwise terminate)
4. Each operation manager must be able to report its failure to a common channel (logging)
5. There’s no need for a transactional behavior (rollback)

What I am aiming here is to be able to

  • easily integrate a new operation manager
  • Be able to test a specific use-case (set of operation manager operations)
  • Bring a level of abstraction and have the different operation managers decoupled from each other.

I have been looking at CoR but still not sure if it is the best option for me or not.


Solution

  • Nope. Chain of responsibility is useful for step-by-step processing of something, where each component may or may not be involved, or may or may not terminate entire execution. It describes a linear ordering of "steps" and typically implemented in terms of linked list of a "links" - particular objects responsible for processing particular data. HTTP interceptors are classical examples. For non-linear ordering a graph is used and it has little to do with GoF's chain of responsibility: "little" because linked list is a kind of graph by it's nature.

    What you've described is too broad to specify a certain pattern. It can be solved with few patterns in place, depending upon code complexity, outer dependencies, number of use cases and many other factors.

    Since you are centered around a use case primitive, why don't you define it rigorously in your code? A UseCase accepts whatever it needs and spits out a result of a certain unified form - you'll have to introduce common result/failure-reporting object, general enough to be reused by all use cases.

    What I've described is not a pattern, at least not a GoF pattern, though is definitely a good starting point to specialize your requirements and expectations.