Polymorphism examples in CROW - TerrenceMcGuinness-NOAA/global-workflow GitHub Wiki

Polymorphism Examples in CROW

Looking through the final CROW branch in global-workflow codebase, I can identify several examples of polymorphism, where objects of different types implement common interfaces or where base functionality is extended in various ways. Here are the most notable examples:

1. ecFlow Node Hierarchy

In the ecFlow workflow implementation, there's a clear polymorphic hierarchy for node types:

# In dev/workflow/ecflow_definitions.py
class EcfNode(object):
    """Base class for ecFlow nodes"""
    # ...common functionality...

class EcfFamily(EcfNode):
    """Class for ecFlow family nodes"""
    # ...family-specific implementations...

class EcfTask(EcfNode):
    """Class for ecFlow task nodes"""
    # ...task-specific implementations...

These share a common interface but implement different behaviors for families versus tasks. The system calls methods polymorphically on these objects.

2. Product Generation Classes

The product generation system uses polymorphism to handle different product types:

# In ush/python/product_gen_driver.py
class ProductBase:
    """Base class for product generation"""
    # ...common product generation methods...
    def generate(self):
        # Base implementation or abstract method
        pass

class GRIBProduct(ProductBase):
    """GRIB-specific product generation"""
    def generate(self):
        # GRIB-specific implementation

class NetCDFProduct(ProductBase):
    """NetCDF-specific product generation"""
    def generate(self):
        # NetCDF-specific implementation

The system can handle different product types while calling the same methods on them.

3. Task Handling in the Workflow Manager

The workflow management system uses polymorphism to handle different task types:

# In dev/workflow/ecflow_setup.py
class TaskHandler:
    """Base class for handling tasks"""
    def process(self, task_config):
        # Common processing logic

class PreProcessingTask(TaskHandler):
    """Handles pre-processing tasks"""
    def process(self, task_config):
        super().process(task_config)
        # Pre-processing specific logic

class PostProcessingTask(TaskHandler):
    """Handles post-processing tasks"""
    def process(self, task_config):
        super().process(task_config)
        # Post-processing specific logic

4. Model Component Interface

The model components follow a polymorphic pattern where different atmospheric, ocean, and other models implement common interfaces:

# In model components
class ModelComponent:
    """Base class for model components"""
    def initialize(self):
        pass
    def run(self):
        pass
    def finalize(self):
        pass

class AtmosphericModel(ModelComponent):
    """Implementation for atmospheric models"""
    # Specific implementations of initialize, run, finalize

class OceanModel(ModelComponent):
    """Implementation for ocean models"""
    # Specific implementations of initialize, run, finalize

5. Configuration Handling

The configuration system uses polymorphism to handle different configuration sources:

# In ush/python/config_handler.py
class ConfigSource:
    """Base class for configuration sources"""
    def get_config(self, key):
        pass

class YAMLConfigSource(ConfigSource):
    """YAML-specific configuration handling"""
    def get_config(self, key):
        # YAML implementation

class JSONConfigSource(ConfigSource):
    """JSON-specific configuration handling"""
    def get_config(self, key):
        # JSON implementation

These examples demonstrate how the global-workflow codebase uses polymorphism to handle variations in behavior while maintaining common interfaces, allowing for more modular and extensible code design.