I’m a big fun of event-driven architecture and how different components in a system react to different state changes in a domain. Mostly because it promotes loose coupling between components and services. Sometimes it's also a good paradigm to pipe and filter architecture since, for instance, the consumer of an event might just have the responsibility to filter, transform and forward the event to another component of the system. Moreover coming from distributed environments and architectures, an event-driven approach extends horizontal scalability making them more resilient to failures promoting high availability and eventual consistency [6, 7].
The initial scope of the article was to avoid ActiveRecord Callbacks mostly because of its unwanted side effects [4] and hard to remove afterward. Other drawbacks would be violating the single responsibility principle and slowing down our test suite. Leaving AR callbacks on the side the next thought would be to decouple a service object from directly calling other services to fulfill a use case as we will see below. The advantage of the last point is that we promote the open-close principle and have a better view of the purpose of a given use case and what are its side-effects. …
The question is quite common in software development. Given an instance of a class, you want to know when to check if a class is valid or not. Do you skip validations before executing an action or do you first check if the instance is valid before executing an action?
Let’s see a simple example. Image an entity called FlightReservation
and some validation or better business invariant rules that require a flight reservation to be valid when it contains no more than max_passenger
passengers.
class FlightReservation < AggregateRoot
MaxPassengersReachedError = Class.new(StandardError) attr_reader :passengers
attr_reader :max_passengersdef initialize(max_passenger)
@max_passengers = max_passengers
@passengers = Set.new
end
add_passenger(passenger)
if (passengers.size …
Design patterns are reusable solutions to a commonly occurring problem within a given context in software design [1]. Having design patterns in mind is a good habit in general, but it should be avoided to apply them from the beginning. Thinking about good design is a good thing but applying it all the time can hurt your software, maintenance and the effort that someone needs to put in order to understand what a single class does. …
The Repository pattern is a way of working with a data source. In the book Patterns of Enterprise Application Architecture, Martin Fowler describes a repository as follows:
A repository performs the tasks of an intermediary between the domain model layers and data mapping, acting in a similar way to a set of domain objects in memory. Client objects declaratively build queries and send them to the repositories for answers. Conceptually, a repository encapsulates a set of objects stored in the database and operations that can be performed on them, providing a way that is closer to the persistence layer. …
As developers we always try to find the chance to apply new ideas. Normally I tend to keep things simple and rarely plan ahead on good design and abstractions. Having the big picture upfront and plan your code ahead needs experience and a lot of passed failures to learn from.
Recently I came across a codebase where we had to add a new feature on top of an existing implementation. It was implemented a couple of months ago and still, it kept growing an growing. …