I've got an application that uses MVC to run individual, isolated scripts to support our office.
There is a root application will open new windows (limit 1 per tool) for each tool opened and each window gets its own MVC. I've read various articles on single vs multiple MVCs, but I preferred to "package" each MVC into its own environment for readability and maintainability. I thought that it made no sense to have a large single controller that must implement a variety of methods based on what tools may be running.
This looks a bit like so:
app.root
app.root.AppController
app.root.AppModel
app.root.AppView
app.tools.CSVDownloaderTool
app.tools.CSVDownloaderToolController
app.tools.CSVDownloaderToolModel
app.tools.CSVDownloaderToolView
app.tools.CSVParserTool
app.tools.CSVParserToolController
app.tools.CSVParserToolModel
app.tools.CSVParserToolView
This works quite well and is easy to reason about since everything is "packaged" on its own; no failure in one tool leads to a systemic failure across the application. But a new request has arisen that I would like to implement and place in a new releases: workflows, or pipelines.
Suppose the CSVDownloaderTool outputs a CSV file that a user wants to immediately parse. As it stands, they would need to then launch the CSVParserTool and fill out all the information in the prompts screen. What has been requested now is that the user be able to specify what subsequent programs to send output to as inputs; effectively eliminating the need to prompt for user inputs view a new window. Therefore the requirements for an individual tool would be:
- Must be able to open and run as a standalone tool
- Must be able to receive input from another tools output
This is where I am stuck, as the Controller is defined as:
class Controller(Observer):
def __init__(self, model, view) -> None:
self.model = model
self.view = view
# methods based on events in View via Observer Pattern
Therefore all the inputs placed in the View would be updated via the Controller to the Model. When the tool is running, that logic is part of the methods in the Controller and it updates the Model which signals changes to the View. I'm not sure how to adapt this to allow for the workflow or pipeline functionality. I know of the Pipeline Pattern and I'm looking at that primarily, but it doesn't resolve the problems I've mentioned.
The only solution I've come up with so far would be to implement multiple interfaces:
- Standalone Interface
- Workflow Interface
I'm hesitant to do this as it means I would be duplicating all the logic defined in each Controller, but to handle a shared context between throughout the workflow. Is this the right approach or is there another pattern or adaptation I should be looking at?