#πŸ”’ Design Patterns: Command, Chain of Responsibility, Strategy and/or Memento for New System

20 messages Β· Page 1 of 1 (latest)

summer moss
#

Hey guys. I'm trying to implement a new system for my job. The idea for it is to have a workflow of provisioning operations that need to be applied on a device with a specific compliance standard in mind for each setting addressed in the operations.

We already have something in place, but it lacks features and it needs to be changed very frequently, adding new operations and checks. Currently its a very awkward process, but maybe patterns can help me here.

These are the basic requirements:

  • Task workflow: Have a set of tasks that need to be executed in sequence. Some have dependencies on previous tasks, and tasks can be executed in "parallel" (I know its python and that's not really possible, but still). Thought of a DAG to manage this.
  • Alternate modes: The workflow can be executed in either "diagnosis" or "execution" mode. In diagnosis, we return the state of a setting, while in execution we change it to its "intended state" based on its current state and return if the operation was successful or not
  • Undo: The user should be able to undo the entire flow or specific steps (hence the memento/command patterns)
  • Disabling steps: The client can disable and enable certain operations in the chain (hence the chain of responsibility).
  • DB Based: The state of a settings must be stored in the database, instead of in memory like in the traditional memento pattern
  • Feedback heavy: The system must notify almost everything to the client, success status of an execution, diagnosis results, errors, etc.
  • Tasks of tasks: Some tasks in the chain, may consist themselves of other chains of commands, with the same requirements as above.

Im still kinda new to design patterns, so implementing 3 or 4 cohesively feels pretty daunting, and since Im aiming at making the system better for the long term, I don't know if what I'm doing is correct or just overcomplicating things. Would love to get some feedback or ideas. Thanks!

ebon fableBOT
#

@summer moss

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

digital veldt
#

I'd encourage you to think about your own requirements and your designs to fulfill them rather than in terms of design patterns, if that makes sense

#

note that a task that contains a chain of subtasks is equivalent to putting those subtacks in the main DAG

#

if your tasks are I/O-bound you can use async to work on multiple at the same time

#

if not you could use multiprocessing, but either option will increase your complexity a bit

#

celery might be worth a look, but might not

summer moss
#

Thank you for the feedback!

#

Right now I just have a function receiving a "diagnose" parameter that returns a different data type depending on what the user intends

#

But I feel like my code is starting to become way too clutered. Initially I thought that I could separate between execution and diagnosis functions, but there is common logic, and I dont want to keep that logic too separate from the diagnosis and execution logic, so I started looking into patterns to maybe get a glimpse into something useful or more extensible

#

Only the command pattern rings a bell and I feel like the memento pattern is something that you sort of need to do in order to get a properly working undo system. But Im going crazy. Do you know of something better?

digital veldt
#

but there is common logic, and I dont want to keep that logic too separate
i would try to factor out the common logic into its own function that both can call

#

or even conceive of the execution function as doing the diagnosis logic and then committing it

summer moss
#

Yeah, I thought of doing a "get_state" function. But in that case I feel like having a class that groups the "get_state", "diagnose", "execute" and "undo" could be a bit better, since all tasks would inherit from the same abstract base class, and a more structured approach would be enforced

#

But then the idea of the command pattern starts showing up. Where you can have like a "DoThisCommand" that just calls a receiver with multiple methods which would be the "get_state", "diagnose" and "execute",

digital veldt
#

this is sort of what I mean by not thinking in terms of design patterns
don't try to shoehorn your code into a design patter, at most you should use one as a high-level inspiration

summer moss
#

I see. What would you recommend then?

#

Just leave it as functions?

ebon fableBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.