jeudi 7 janvier 2021

Pattern for ensuring all modules have same parameters?

I'm writing code with the following architecture in Python. Basically, it's a modular synth which is composed of a tuple of "Modules". For simplicity right now, each Module is atomic (no nested modules).

Each Module contains two parameters, p1 and p2. I want to ensure that each module that is in the same synth has the same parameter values for p1 and p2.

Here is one approach, which has a handful of boilerplate:

DEFAULT_P1 = ...
DEFAULT_P2 = ...

class Module:
    """
    Abstract base class.
    """

    def __init__(
        self, p1: int = DEFAULT_P1, p2: int = DEFAULT_P2
    ):
        self.p1 = p1
        self.p2 = p2


class ModuleK(Module):
    """
    A handful of submodules.
    """
    def __init__(
        self,
        ... other params
        p1: int = DEFAULT_P1,
        p2: int = DEFAULT_P2,
    ):
    super().__init__(p1=p1, p2=p2)
    ...


class Synth:
    """
    An abstract class for a modular synth, ensuring that all modules
    have the same sample and control rate.
    """

    def __init__(self, modules: Tuple[Module]):
        # Check that we are not mixing different control rates or sample rates
        for m in modules[:1]:
            assert m.p1 == modules[0].p1
            assert m.p1 == modules[0].p2

Here is a more concise approach using globals. I fear this can have side-effects, i.e. not being able to have two synths in the same runtime with different p1 and p2, unless you do something really fiddly and fragile.

DEFAULT_P1 = ...
DEFAULT_P2 = ...

class Module:
    """
    Abstract base class.
    """

    def __init__(
        self
    ):
        self.p1 = DEFAULT_P1
        self.p2 = DEFAULT_P2


class ModuleK(Module):
    """
    A handful of submodules.
    """
    def __init__(
        self,
        ... other params
    ):
    ...

I've also considered inheriting from a class that encapsulates the two p1 and p2. However, you still have to check that all modules in the same synth inherit from the same kind of encapsulating class. Since it's only two params it doesn't make things more ergonomic in any way.

Is there a pattern I'm missing?

Aucun commentaire:

Enregistrer un commentaire