Service Objects are objects that perform a discrete operation or procedure. When a process becomes complex, hard to test, or touches more than one type of model, a Service Object is useful for cleaning up your code base. Even a Service Object that performs one single step can be a valuable abstraction for clarity and testing.
To ensure isolation of a Service Object, follow these principles:
- Strict with input and output. Service Objects are designed to handle a very specific process, so we can forego the Robustness Principle in favor of creating a tool for a single, specific purpose.
- Documented thoroughly. Since Service Object code likely lives in a different file than the code where it is used (e.g. a controller or model method), the reader will not have the benefit of context when trying to understand what the Service Object is doing. Hence, documenting the argument types, logical paths, and return values is crucial.
- Terminates after completion. This pattern should not be conflated with a worker process, which could set an interval, listen for web socket messages, or perform some other procedure with no immediate end. Service Objects should be invoked, perform their operations (whether synchronous or asynchronous), and terminate.