Home Projects Portfolio Dashboard Export PDF Log in

Decoupling Appointment Logic with Factory and Observer Patterns

Managing a complex scheduling system like mediTurn requires a delicate balance between flexibility and maintainability. As our appointment management needs grew, the core code started becoming brittle, with too many responsibilities crammed into a single service. To address this, we recently refactored the module by implementing the Factory and Observer patterns.

The Problem: Tightly Coupled Appointments

Previously, creating an appointment meant instantiating objects directly and manually notifying multiple subsystems (like notifications and calendar synchronization). This approach made our code look like a giant "spaghetti" junction, where changing one part of the flow risked breaking three others.

The Refactor: Introducing Structure

We decided to separate creation logic from lifecycle events.

First, we used the Factory Pattern to centralize object creation. Instead of scattering new Appointment() calls throughout the codebase, we created a factory that handles the complexities of building valid appointment instances.

public class AppointmentFactory {
    public Appointment create(AppointmentRequest request) {
        // Encapsulate validation and object construction
        return new Appointment(request.getDate(), request.getProviderId());
    }
}

Next, we adopted the Observer Pattern to handle side effects. Rather than the appointment service knowing about every system that needs to know about a new booking, the appointment object now acts as a "Subject" that notifies registered "Observers."

Implementing Reactive Notifications

By leveraging concepts similar to RxJS, we ensure our system remains reactive. When an appointment status changes, observers act independently.

public interface AppointmentObserver {
    void onStatusChange(Appointment appointment);
}

// Usage in the service
public void updateStatus(Appointment appointment, String status) {
    appointment.setStatus(status);
    observers.forEach(o -> o.onStatusChange(appointment));
}

The Outcome

This refactor turned our monolithic appointment management into a decoupled, event-driven architecture. Adding a new feature—like sending a confirmation SMS—is now as simple as registering a new observer, rather than modifying the appointment service itself.

Takeaway

If your service classes are growing uncontrollably, stop and ask: "Does this class really need to know about all these side effects?" Use a Factory to clean up instantiation and the Observer pattern to handle secondary tasks. Your future self will thank you for the reduced complexity.


Generated with Gitvlg.com

Decoupling Appointment Logic with Factory and Observer Patterns
S

Sabrina Massola

Author

Share: