If terms like “Modules,” “Classes,” “Interfaces,”, “Delegates” feel new or abstract, keep this article as a map. I’ll explain what each one does, why they matter, and how to choose the right one. Think of these features as your toolkit:
- Modules: organize shared helpers that don’t store data. They just do a job and return a result.
- Classes: represent objects that keep data and have actions.
- Interfaces: agreements about what methods exist so parts can work together without caring how they’re built.
- Delegates: a way to pass a function around so another part of your app can call it later (a callback).
Modules
Purpose
- Provide a namespace for related helpers, constants, and enums.
- Offer reusable helpers that don’t remember data between calls.
- Add extension methods that make calling code cleaner.
Use when
- You need shared helpers (formatting, parsing, conversions).
- You want to group constants/enums (error codes, log levels).
- You’re adding behavior to existing types via extension methods.
Avoid when
- You’re tempted to store changeable global data that creates hidden dependencies.
Benefits
Read more: Xojo Modules Documentation
Classes
Purpose
- Represent real concepts in your app (e.g., an order, a report, a session).
- Keep data and the related rules/actions in one place.
- Separate concerns: core logic in classes, screen logic in the UI.
Use when
- You have data that changes over time and rules to enforce.
- You need services that coordinate steps (for example, “Export report” or “Sync data”).
- You want testable units that don’t depend on UI elements.
Avoid when
- You only need a simple helper that returns a result (that belongs in a Module).
- Platform-specific calls would leak into core logic (hide those behind Interfaces).
Benefits
- Clear rules kept close to the data they protect.
- Clean boundaries between UI, core logic, and data access.
Read more: Xojo OOP Classes Documentation
Interfaces
Purpose
- Define the what without the how.
- Let you swap implementations (e.g., memory vs. SQLite vs. REST) without changing calling code.
- Make testing simple by substituting fakes/mocks.
Use when
- A feature may vary by platform or environment (file system, keychain, camera, notifications).
- You want to keep app logic separate from the details of databases, files, or network calls.
- You’ll have multiple strategies that share the same shape.
Avoid when
- There’s only one implementation and you don’t need to test in isolation.
Benefits
- Loose coupling and easier future changes.
- Cleaner, more stable internal APIs.
Read more: Xojo Interfaces Documentation
Delegates
Purpose
- Provide type-safe callbacks by letting you hand a function to another part of your app.
- Enable flexible behavior without defining a whole interface and class.
- Power progress updates, cancel handlers, filters, or small strategies.
Use when
- You need a one-off callback (progress, completion, error reporting).
- You want to inject small pieces of behavior (sorting, filtering, formatting).
- You’re wiring up dynamic behavior at runtime.
Avoid when
- You need a broader contract with multiple related methods (use an Interface instead).
- You need lifecycle or semantic grouping (a Class with events may be clearer).
Benefits
- Lightweight and expressive.
- Less boilerplate than creating full classes for simple callbacks.
- Encourages small, composable, testable pieces.
Read more: Xojo Delegates Documentation
Quick Decision Guide
- I need to group common helpers and constants. → Module
- I’m modeling an object with data and rules. → Class
- I want to depend on behavior, not a specific implementation. → Interface
- I need a small callback or injected behavior. → Delegate
- I need many subscribers to a lifecycle change. → Event on a class
Quick glossary
- Interface: a contract, a named list of methods something promises to have.
- Delegate: a variable that holds a function to call later (a callback).
- Event: a signal that something happened; other parts can listen for it.
Use Modules to organize shared helpers, Classes to model your world, Interfaces to decouple and swap implementations, and Delegates to pass behavior flexibly. Combined thoughtfully, these features keep Xojo projects easy to change, easy to test, and ready to ship across platforms.
Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!