I modeled a small automation domain with Python classes, abstract base classes, and dataclasses for value objects. An explicit object model with clear interfaces made the system easy to extend and unit-test without touching existing code.

Objective & Context

OOP organizes state and behaviour behind interfaces. This lab covers instance vs class attributes, inheritance, polymorphism via abstract base classes, and boilerplate-free value types with @dataclass, applying the open/closed principle to automation components.

Environment & Prerequisites

  • Python 3.11 with dataclasses and abc.
  • A domain with multiple related entity types.
  • pytest for behaviour verification.

Step-by-Step Execution

1. Define an interface with abc

from abc import ABC, abstractmethod
class Notifier(ABC):
    @abstractmethod
    def send(self, msg: str) -> bool: ...

2. A dataclass value object

python -c "from dataclasses import dataclass; exec('@dataclass\nclass Alert:\n ip:str\n sev:int'); print(Alert('1.2.3.4',2))"

3. Polymorphic dispatch

python -c "from notify import SlackNotifier; SlackNotifier().send('up')"
Alert(ip='1.2.3.4', sev=2)

Validation & Testing

Add a new Notifier subclass without modifying the dispatcher and confirm it works via the shared interface. Pass criteria: subclasses are interchangeable, dataclasses compare by value, and abstract methods enforce the contract.

Advanced: Troubleshooting
  • Cannot instantiate ABC: implement all abstract methods in the subclass.
  • Mutable dataclass default: use field(default_factory=list).
  • Shared class attribute mutated: initialize per-instance state in __init__.

Key Results

  • Modeled the domain behind a single abstract interface.
  • Added new behaviour via subclassing with zero changes to callers.
  • Eliminated boilerplate with dataclass value objects.
  • Verified polymorphism and value equality with unit tests.