Some notes from Rails architect MasterClass

What is the business domain? A translation into code of the business model. A business domain in object-oriented programming is the set of classes that represent objects in the business model being implemented.

Event Sourcing to make our Rails Apps totally free from ActiveRecord, like a gem.

What are bounded contexts? Bounded context defines tangible boundaries of applicability of some sub-domain.

What is a sub-domain? domain that is a part of another domain.

Connect your code, not the data, to your external apps or clients, otherwise it would be very difficult to refactor.

A bounded context has: data and code.

Big problems:

  • The code of one bounded context is reading the data directly from another bounded context. Solution: when something happens in the data the code publishes a Domain Event and they can connect to a different bounded context.

namespaces :: are great sep for bounded context but as long as our persistence in the db is mixed together with has_many relations for example, it is a problem, we don’t have strong boundaries.

Do we need event sourcing when we have been event driven (domain events)? Yes, event sourcing is a good complement to event driven. First even driven and then, event sourcing.

Event sourcing: another way to storing the current state of the data. To store all the changes. If you want to read those changes, you read from the read model.

You don’t fix mistakes, you create a new event.

Is there any magic trick which turns active record into events? With this tool you can track create/update/destroy actions on active_record models:

Active Record associations are cure and poison.

Moving the business vocabulary to the code base

Domain-driven design is the concept that the structure and language of your code should match the business domain.

Domain model. Solution space. Validate your model and explore other possibilities.

Domain discovery: model exploration whirlpool, event storming, domain storytelling…

A new language: Ubiquitous Language, to understand

Domain events: Described at past tense and relevant for business. DE as an interface to communicate between Bounded Contexts.

Commands: Usually result of some decision made. Different sources. Can be a source of more than 1 domain event.

Aggregate: Let the names emerge, do not focus on them yet. Focus on behaviour not data.

Two difficult problems in CS: cache invalidation and naming things.

Domain Safari. We go to online places and see how domain experts communicate between them.

How to find the core domain? The discourse.

Strategic patterns: Bounded context, context maps, core & sub-domains.

Tactical patterns:

  • Value object(1 pound. We need the number 1 and the currency to know our object. VatRate, GrossAmount, Level, ID, ActiveSupport::TimeZone). They don’t have identity, they are immutable,
  • Entity. Domain object with unique identity. Usually have mutable state. What you have in ActiveRecord Base, my tables in the db.
  • aggregate: Set of composed domain objects defining single consistency unit. Root of the objects hierarchy is an aggregate root. Usually it is used as conceptual name of an aggregate. Order (aggregate root)has many order rows (entities that can have value objects).
  • domain event,
  • design patterns like: Repository, Factory, Strategy…

CQRS (Command-query separation) to speed your app having 2 models, one for reading and the other one to perform some action, write.  “Every model should either be a command that performs an action, or a query that returns data to the caller.”


One simple trick to make Event Sourcing click

Event Sourcing is a transferable skill

What is a process manager?

Microservices are not much about architecture.  Microservices are a deployment strategy.
Code can be divided into: libraries, components and deliverables/assemblies. Microservices don’t have state so they are not components. They are from the 3rd group.

Algorithms and how they used with Ruby


Importance of algorithms

An algorithm is a set of rules to follow in order to solve a problem.

We use algorithms to improve the performance of our program using the available resources and get the best combination of speed and use of memory.

They are important because programming languages rely on them and because if we find a problem that has already been solved by an algorithm, we can replicate its technique and when appropriate, use it.

We are going to talk about time, but despite speed is an important factor to consider when using algorithms we should still have our priorities as follows:

  • Make it work
  • Make it right
  • Make it fast.


We can and should calculate the cost of our code. When we talk about cost in the context of algorithms , what we mean is time.

A shorthand to know how long a procedure takes is to ask how many lines of code are involved. But there are more factors to consider. If we want to calculate how long does it takes to find if a word contains a specific letter, well, the answer will depend on the size of the word. The cost of performing a function  varies with the size of the input, so we describe the cost in terms of the size of the input. We call this cost the time complexity of the function.

Time complexity

Time complexity of an algorithm signifies the total time required by the program to run until its completion and in the worst case scenario. It is defined as a function using Big O notation, an asymptotic notation.

n is the size of the input.

O is the worst case scenario.

* The worst case scenario is one where given an input of a certain size, our function takes as long as possible.

The O function is the growth rate in function of the input size n.

Great resources to learn about algorithms and data structures using Ruby:



Limit a method’s access in Ruby

To limit a method’s access we use 3 methods: private, protected and public.
Public: By default all methods defined are public. All instances of a class can use these public methods. Public methods are called with an explicit receiver.
Private methods are the ones defined under the private keyword and they can only be used within the class definition. The receiver in private methods is self. We use private methods for internal usage without a receiver.
Protected methods are similar to private with addition that it can be called with or without an explicit receiver but that receiver is always self or an object that inherit from self. We use protected methods defined as self.my_method for internal usage in other classes whenever inheritance isn’t used.

Different ways to invoke a method in Ruby

  1. (Single run time) Using dot notation and calling the method on the object:
  2. (Persist name of method to database) Using send method:
  3. Get the method and call it like a Proc:
  4. Not good practice but useful sometimes. (Self-modifying method code):

Differences between class, object and module in Ruby

Ruby is a class-based object-oriented programming language. Meaning that every object is an instance of a class, and a class defines the state (variables) and behaviours (methods) of an object. An object is an entity with state and behaviour, as defined by its class.

Object is an instance of a class which allows you to use the classes attributes and methods. Object is the default root of all Ruby objects. Everything in Ruby is an object, including classes. An object in code is a thing with all the data and all the logic required to complete a task. Objects are models and metaphors for the problems we solve in code. Ruby comes with a few types of Objects to get us started, things like Integer, String, Array, etc. We call these base types of Objects “Primitives.” But what if we wanted to create a new type in our programming universe, a new kind of object for our code? That’s what the class keyword and object orientation allows us to do.
Class is a type of structure of information and code. A Ruby class is an object of class Class, which contains all the object things plus a list of methods and a reference to a superclass. A class is the blueprint from which individual objects are created.
A module is a collection of methods and constants. They hold methods, like classes but they can’ t be instantiated. It is not possible to create objects from a module. Modules are useful when we have methods that want to reuse in certain classes

Stubs, mocks, spies and fakes

Minimal implementations of interfaces or base classes
A Spy will record which members were invoked
More complex, a fake may resemble a production implementation
It is usually dynamically created by a mock library and depending in its configuration a mock can behave like a dummy, a stub, or a spy.
They all relate to functions, objects and other types.
Stubbing is a way to provide dummy data/info instead of making the calling to the actual DB
It is for example a function which you create inside the test file to mimic the real function or be a simplified version of the actual function.

Virtual environment (Python)

Create a virtual environment for your Python app in a few steps. (For Linux and OS X). Go inside the directory where you want your virtual environment and type in the terminal:

This command will create a directory called myvenv with the virtual environment.

Start your virtual environment by running:

Now that you inside the virtual environment (you will know it because the prompt of the console is prefixed with ( myenv )) you can install whatever you need using pip. To get the latest version of pip type:

When working within a virtual environment, python will automatically refer to the correct version so you don’t need to specify anything.

Create a requirements.text file and add packages inside.

Run the following to install them:

The end! Happy coding!

Junior developer interview questions

I am looking for my first job as a Junior developer and during my interviews I was asked the following:

  • Difference between === and ==:
    • === Compares the value ad the type (true / false).
    • == Compares only type.
  • Difference between slack and heap memories:
    • Slack memory: local variables and function call.
    • Heap memory: store objects.
  • Difference between data type and data structure:
    • Data type: the most basic classification. (int, string, var).
    • Data structure: collection of data types. (stacks (LIFO(last in first out)), queues, linked lists, binary tree)
  • Difference between padding and margin:
    • padding is the space between the content and the border, whereas margin is the space outside the border.

Time complexity

  • You can get it counting the number of operations
  • Time complexity is defined as a function using Big O notation.
  • n is the size of the input.
  • O is the worst case scenario.
  • The O function is the growth rate in function of the input size n.

O(1) Constant : odd or even / look up table / check if item in array is null / print first element from a list / find on a map.

O(log n) Logarithmic: find in sorted array with binary search.

O(n) Linear: find max in unsorted array / duplicate elements in array with Hash map / find / print all values.

Algorithms running times:

Factorial complexity(no good),

exponential complexity(no good),

polinomial complexity (no good),

linearithmic complexity (middle point),

linear time complexity (good)(for loop in one level array, searching, printing) O(n),

logarithmic complexity (good) O(log n),

constant time complexity (best one)(swap variables). O(1)

Time Conversion

Problem from Hackerranck.

I am practising algorithms and tried this one today.

I first get the two first characters of the string ‘s’, the ones that represent the hour and change them to a number with parseInt and assign them to the variable hour.

If this variable hour is bigger than 12 I rest 12, if it is equals 12, hour would be the string ’00’ and for the rest of the cases I add 12.

Then I add hour to a substring of the argument without the two first characters and delete the two last characters too, the one that should be “AM” or “PM”.

My solution: