Production OOP Patterns in ML: Interview Reference
Table of Contents
- Classes and Objects
- Encapsulation: Hide Implementation, Expose Interface
- Inheritance: Reuse Code Across Models
- Polymorphism: Same Interface, Different Behavior
- Abstraction with ABC: Enforce the Contract
- Duck Typing vs. ABC
- Method Overriding
- Composition: Building Complex Objects
- Attributes: Data in Objects
- Namespace and Scope
- Quick Reference
- Interview Talking Points
- Decision Tree: When to Use Each Concept
- Key Takeaway
Classes and Objects
What is a Class?
A class is a blueprint for creating objects. It defines:
- Attributes (data the object holds)
- Methods (functions the object can perform)
What is an Object?
An object is a concrete instance of a class. Multiple objects can exist from the same class, each with different data.
Production Example
| |
Why it matters: Classes enforce structure. Every model follows the same .fit() + .predict() interface. KServe expects this contract.
Encapsulation: Hide Implementation, Expose Interface
What is Encapsulation?
Bundle data (attributes) and behavior (methods) in a single unit, controlling what users can access.
The Problem
Without encapsulation, callers repeat internal logic:
Risk: One mistake propagates everywhere.
The Solution
Hide preprocessing inside the class:
| |
Why it matters: If we change preprocessing tomorrow, we update once inside _preprocess(), not in 50 services.
Private vs. Public convention:
public_method()— designed for external use_private_method()— internal implementation, users shouldn’t call this
Inheritance: Reuse Code Across Models
What is Inheritance?
A child class inherits attributes and methods from a parent class, reducing duplication.
The Pattern
| |
Why it matters: Write _validate_input() once. Both XGBoost and CatBoost inherit it. No duplication.
Polymorphism: Same Interface, Different Behavior
What is Polymorphism?
Different classes respond to the same method call in different ways.
The Pattern
| |
Why it matters: Ensemble doesn’t care what’s inside. Drop in a new model type without touching ensemble code.
Abstraction with ABC: Enforce the Contract
Why ABC Exists
In Python, everything is dynamic. Without enforcement, you can create a class that looks complete but misses required methods.
ABC fixes this by: Preventing incomplete subclasses from being instantiated.
How ABC Works
| |
Error timing matters: With ABC, you fail at class definition time, not at runtime.
When to Use ABC
| Use Case | Decision |
|---|---|
| Small scripts, one-off analysis | Don’t use ABC |
| Production system, multiple teams | Use ABC |
| Framework design, plug-and-play system | Use ABC |
| Large codebase, implicit contracts become chaos | Use ABC |
Duck Typing vs. ABC
What is Duck Typing?
“If it walks like a duck and quacks like a duck, it’s a duck.”
Python doesn’t check type — it checks capability.
| |
Duck Typing Characteristics
- Implicit contract — no formal requirement
- Flexible — add new types easily
- Risky at scale — bugs discovered at runtime
ABC Characteristics
- Explicit contract — formal requirement
- Enforced — bugs caught at instantiation time
- Rigid — requires inheritance from ABC
When to Use Which?
Duck Typing works when:
- Code is small and well-understood
- Team is small
- Requirements are stable
ABC works when:
- Multiple teams contribute
- Requirements change frequently
- You want strict architectural discipline
- Production reliability matters
Hybrid Approach (Best for ML)
| |
Why this works: Core contract is enforced (ABC). Additional methods are flexible (duck typing).
Method Overriding
What is Method Overriding?
A subclass defines a method with the same name as a parent class method, replacing the parent’s implementation.
| |
Why it matters: Subclasses specialize parent behavior without breaking the interface.
Composition: Building Complex Objects
What is Composition?
Include instances of other classes as attributes within a class.
| |
Why it matters: More flexible than inheritance. You can swap components at runtime.
Attributes: Data in Objects
What are Attributes?
Variables that belong to an object and describe its state.
Why it matters: Track model metadata (version, timestamp, performance). Enables versioning and rollbacks.
Namespace and Scope
What is a Namespace?
A mapping of names → objects. Think: a dictionary of identifiers.
What is Scope?
The region of code where Python will look for a name.
LEGB Resolution Rule
Python searches for a name in this order:
- Local (inside current function)
- Enclosing (in outer function, for nested functions)
- Global (module-level)
- Built-in (Python’s built-ins like
print,len)
Why it matters: Understanding scope prevents variable shadowing bugs in nested class methods.
Quick Reference
| Term | Means | Example |
|---|---|---|
| Class | Template for objects | class Model |
| Object | Instance of a class | fraud_detector = Model() |
| Attribute | Data in an object | model.version |
| Method | Function in a class | model.fit() |
| Inheritance | Child reuses parent | XGBoostModel(BaseModel) |
| Encapsulation | Hide internals, expose interface | def predict() public, _validate() private |
| Polymorphism | Same interface, different behavior | All models respond to .fit() and .predict() |
| Abstraction (ABC) | Enforce required methods | @abstractmethod forces implementation |
| Duck Typing | Check capability, not type | If it has .speak(), call it |
| Composition | Include other objects as attributes | Pipeline(model1, model2, model3) |
| Method Overriding | Subclass replaces parent method | RobustModel.validate() overrides BaseModel.validate() |
Interview Talking Points
“Tell me about inheritance in your production systems.”
“Every model at Adform—fraud, RTB, forecasting—inherits from BaseEstimator that enforces .fit(), .predict(). This ensures consistency across domains. When we deploy to KServe, the container expects this interface. Inheritance reduces boilerplate ~60%.”
“How do you handle incomplete implementations?”
“We use abstract base classes (ABC) with @abstractmethod. If a model skips .predict(), the code fails at instantiation—we catch bugs at definition time, not runtime. In production, that discipline matters.”
“Duck typing vs. ABC—which do you prefer?”
“At small scale, duck typing is flexible. At Adform’s scale, ABC enforces architectural discipline. Core contract is ABC (.fit(), .predict()). Optional methods are duck typing (.explain(), .get_metadata()). Hybrid approach.”
“How does encapsulation help in production?”
“Every model deployed to KServe is wrapped with a .predict() method that handles scaling, validation, fallback, logging. Teams call one method. If we upgrade preprocessing tomorrow, we change it once inside the wrapper, not in 50 places.”
“Tell me about polymorphism in your work.”
“In our RTB simulator, different bidding strategies (fixed, learned, dynamic) all inherit from BiddingStrategy. The loop calls .generate_bid() without knowing which strategy runs. We A/B tested three new strategies by dropping them into the same harness.”
Decision Tree: When to Use Each Concept
| |
Key Takeaway
OOP solves production problems:
- Classes enforce structure and contracts
- Inheritance reduces boilerplate across models
- Encapsulation prevents breaking changes
- Polymorphism enables safe composition
- ABC enforces discipline; duck typing enables flexibility
- Composition is more flexible than inheritance for complex systems
Not academic—it makes codebases maintainable at scale.