diff --git a/_cloudcannon/bookshop-site-data.json b/_cloudcannon/bookshop-site-data.json index ee744587..7258990e 100644 --- a/_cloudcannon/bookshop-site-data.json +++ b/_cloudcannon/bookshop-site-data.json @@ -1 +1 @@ -{"site":{"posts":[{"draft":false,"categories":[],"layout":"post","title":"Command and command handler design pattern","date":"2021-02-25 00:00:00 -0600","image":"command-handler/command-handler.webp","image_credit":"redaquamedia","tags":["command-bus","design-patterns"],"keywords":"design patterns,software,software architecture,command,command handler,command bus","description":"Discover the command design pattern in software development. Learn how commands represent user intents, handled by command handlers. Learn practical tips, examples, and insights for efficient command validation.","slug":"command-handler-patterns","ext":".md","excerpt":"

This pattern is really interesting; it can help you handle use cases. A command represents the user’s intent, while the command handler performs the actions needed to achieve the use case. Let’s dig a bit into these two concepts.

\n","content":"

This pattern is really interesting; it can help you handle use cases. A command represents the user’s intent, while the command handler performs the actions needed to achieve the use case. Let’s dig a bit into these two concepts.

\n\n

What is a command?

\n\n

A command is an object used to encapsulate all the information needed to perform an action. This design pattern is used to represent user intents, and the command is given to a command handler.

\n\n

A command is often designed as a Data Transfer Object (DTO), which is an object without any behavior (a data structure). The most important design rule to consider is that a command should be easily serializable. This way, it can be sent to a queue such as RabbitMQ or pub-sub to be handled asynchronously.

\n\n

What is a command handler?

\n\n

A command handler is just a callable that executes all the actions needed to fulfill a user’s intent. As you may understand, this design pattern is perfect for managing your business use cases.

\n\n

How does it work?

\n\n

\"Command

\n\n

This pattern has some rules. The first one is that a command can be handled by a single command handler because there is only a single way to handle a use case. The second rule is that a command handler should receive a valid command. Validating the command ensures that the user provides the correct data to prevent the handling from failing. It also helps to provide early feedback to the user about the data they provided.

\n\n

The command is only a DTO that carries data while the command handler is responsible to handle use cases.

\n\n

How to use it?

\n\n

Let’s consider a simple example: creating an account. Our business expert expects users to provide an email and a password to create an account for login purposes. We will create a command named CreateAnAccount and its handler, CreateAnAccountHandler.\nFirst, we need to create a command named CreateAnAccount to represent the user’s intent.

\n\n
final class CreateAnAccount\n{\n   public readonly string $username;\n   public readonly string $password;\n   \n   public function __construct(string $username, string $password) \n   {\n       $this->username = $username;\n       $this->password = $password;\n   }\n}\n
\n\n

Next, we need to create a command handler to manage this use case. The command handler can be a function or an invocable object. It should return nothing (void) to be handled asynchronously as we don’t know when it will be processed and can’t expect an instant result. Using the command data, we perform all actions needed to handle the use case. In our example, we create an account aggregate and pass it to the account repository.

\n\n
final class CreateAnAccountHandler\n{\n   private Accounts $accounts;\n\n   public function __construct(Accounts $accounts)\n   {\n       $this->accounts = $accounts;\n   }\n\n   public function __invoke(CreateAnAccount $createAnAccount): void\n   {\n       $account = Account::create(\n           $createAnAccount->username(),\n           $createAnAccount->password()\n       );\n\n       $this->accounts->add($account);\n   }\n}\n
\n\n

Finally, let’s stick those pieces of code together in a controller (this example is made with a Symfony Framework). This controller receives JSON-encoded data to create a command, which is then validated and passed to the handler

\n\n
final class CreateAnAccount\n{\n    // ...\n    \n    public function __invoke(Request $request): Response\n    {\n        $command = $this->serializer->deserialize(\n            $request->getContent(),\n            CreateAnAccount::class,\n            'json'\n        );\n        \n        $violations = $this->validator->validate($command);\n        \n        if (0 < $violations->count()) {\n           throw new BadRequestHttpException(/*json encoded violation*/);\n        }\n        \n        ($this->createAnAccountHandler)($command);\n        \n        return new JsonResponse(null, Response::HTTP_CREATED);\n    }\n}\n\n
\n

Tip: : To simplify command creation, you can use libraries such as the Symfony Serializer component. It eases object creation from a set of data (e.g., JSON), making the process easier and faster.

\n\n
$createAccount = $serializer->deserialize(\n    '{“username”:”arnaud”, “password”:“password”}',\n    CreateAnAccount::class,\n    'json'\n);\n
\n\n

Tip: To avoid reinventing the wheel, you can leverage libraries like the Symfony Validator component to validate the command.

\n\n
$violation = $validator->validate($createAccount);\n
\n\n

I’ve written a dedicated blog post explaining how to validate a command:

\n\n
\n \n \n \"How\n \n \n How to validate a command?\n \n \n
\n\n

How to simplify that?

\n\n

To simplify this controller, consider using a command bus, which is responsible for finding the right handler for a given command. For more information about this pattern, I’ve written a dedicated blog post explaining how it works:

\n\n
\n \n \n \"The\n \n \n The command bus design pattern\n \n \n
\n\n

The following example is built with Symfony Messenger.

\n\n
public function __invoke(Request $request): Response\n{\n    $command = $this->serializer->deserialize(\n        $request->getContent(),\n        CreateAnAccount::class,\n        'json'\n    );\n    \n    $this->commandBus->handle($command);\n    \n    return new JsonResponse(null, Response::HTTP_CREATED);\n}\n
\n\n

Where is the command validation in this example? Command buses are often built with middleware, making them highly configurable. To ensure that all commands are valid before passing them to a command handler, we need to add middleware to the command bus for command validation.

\n\n
class ValidationMiddleware implements MiddlewareInterface\n{\n    // …\n\n    public function handle(Envelope $envelope, StackInterface $stack): Envelope\n    {\n        $message = $envelope->getMessage();        \n        $violations = $this->validator->validate($message, null, $groups);\n        if (\\count($violations)) {\n            throw new ValidationFailedException($message, $violations);\n        }\n\n        return $stack->next()->handle($envelope, $stack);\n    }\n}\n
\n\n

Tip: Take a look at this blog post if you need to manage user permissions. Adding a middleware to the command bus can enhance the security of your application:

\n\n
\n \n \n \"How\n \n \n How to handle user permissions through command bus middleware\n \n \n
\n\n

My last thoughts

\n\n

In many applications,I have seen a lot of classes named managers or services (e.g., AccountService, AccountManager) that gather all use case management into a single class. While this approach might be effective initially as development progresses, these classes tend to grow larger and larger, and become a “god object.” This makes maintenance challenging, reduces readability, and can quickly turn into a dump. I believe this pattern can address these issues.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/command-handler-patterns.html","relative_path":"_posts/2021-02-25-command-handler-patterns.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"How to validate a command?","description":"Domain validation ensures your aggregate cannot be built in an invalid state but that is not enough to give good feedback to the end users. Validating commands is the best to prevent their processing if data given by users are wrong.","date":"2021-03-04 00:00:00 -0600","image":"data-validation.webp","image_credit":"heapdump","tags":["command-bus","design-patterns"],"keywords":"oop,design patterns,software,software architecture,command,command handler,command bus,data validation,domain validation","slug":"how-to-validate-a-command","ext":".md","excerpt":"

In my previous blog post, I talked about command and command handler design patterns. I got several questions about data validation and how to give feedback to users. We are going to talk about several kinds of data validation in this blog post. We will start with domain validation, this validation ensures we can build our domain objects in a good state depending on business rules. Then, we will talk about command validation and how we can use it to give feedback to users when they submit data to the application.

\n","content":"

In my previous blog post, I talked about command and command handler design patterns. I got several questions about data validation and how to give feedback to users. We are going to talk about several kinds of data validation in this blog post. We will start with domain validation, this validation ensures we can build our domain objects in a good state depending on business rules. Then, we will talk about command validation and how we can use it to give feedback to users when they submit data to the application.

\n\n

Let’s take the same example I used in my previous blog post: an account creation. To create an account, my business expert expects that I provide a username and a password. The username should have at least three characters and should be unique. The password should have at least eight characters, an uppercase letter, a lowercase letter, and a number.

\n\n

Domain validation

\n\n

How to make sure the domain objects follow the business rules? Value object will help us to achieve that. I strongly recommend you to wrap all primitives into value objects. It is a good way to introduce new types in your codebase, make it clearer and business-focused. And don’t forget, value objects cannot be built in a wrong state.

\n\n
final class Username\n{\n    private string $username;\n\n    public function __construct(string $username)\n    {\n        if (\\strlen($username) < 3) {\n            throw new \\InvalidArgumentException('The username is too short, it should contain at least 3 characters');\n        }\n\n        $this->username = $username;\n    }\n}\n\nfinal class Password\n{\n    private string $password;\n\n    public function __construct(string $password)\n    {\n        if (1 !== \\preg_match('#(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,}#', $password)) {\n            throw new \\InvalidArgumentException(\n                'The password must contain at least 8 characters, an uppercase letter, lowercase letter and a number'\n            );\n        }\n\n        $this->password = $password;\n    }\n}\n
\n\n

Then we are able to modelize the Account aggregate using the Username and Password value objects.

\n\n
final class Account\n{\n    private Username $username;\n    private Password $password;\n\n    public function __construct(\n        Username $username,\n        Password $password\n    ) {\n        $this->username = $username;\n        $this->password = $password;\n    }\n}\n
\n\n

Now, we are sure that as developers we cannot instantiate the Account aggregate in a wrong state. In the next section, we are going to see how to use the domain objects to give users feedback about their data.

\n\n

Command validation

\n\n

As I explained in my previous blog post, an account creation is represented by a CreateAnAccount command with two properties: the username and the password. We need to validate them to create the account aggregate without any errors and tell users if they provided valid data to perform this action. The command validation will be done by the Symfony validator. Don’t hesitate to have a look at the validator documentation if you are not familiar with it.

\n\n

First, we will use the callback constraint to make sure the username and password follow the patterns given by the business expert. Thanks to annotation we will configure the validator to call a static method to validate command properties. I will call them “static validators“ in this blog post.

\n\n
final class CreateAnAccount\n{\n    /** @Assert\\Callback({\"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\UsernameShouldBeValid\", \"validate\"}) */\n    private string $username;\n    /** @Assert\\Callback({\"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\PasswordShouldBeValid\", \"validate\"}) */\n    private string $password;\n}\n
\n\n

Then, it is time to create those static validators. We just need to instantiate our value objects and check if they throw exceptions to catch them and turn them into violations.

\n\n
final class UsernameShouldBeValid\n{\n    public static function validate(string $username, ExecutionContextInterface $context): void\n    {\n        try {\n            new Username($username);\n        } catch (\\InvalidArgumentException $e) {\n            $context->buildViolation('account.usernameShouldBeValid')\n                ->addViolation();\n        }\n    }\n}\n\nfinal class PasswordShouldBeValid\n{\n    public static function validate(string $password, ExecutionContextInterface $context): void\n    {\n        try {\n            new Password($password);\n        } catch (\\InvalidArgumentException $e) {\n            $context->buildViolation('account.passwordShouldBeValid')\n                ->addViolation();\n        }\n    }\n}\n
\n\n

For more complex use cases you can call any methods on value objects, but you need to keep in mind that you cannot inject services into those static validators.

\n\n
public static function validate(BookFlightTicket $flightTicket, ExecutionContextInterface $context): void\n{\n    if (\n    !Date::fromString($flightTicket>departureDate)->laterThan(\n        Date::fromString($flightTicket>arrivalDate)\n    )\n    ) {\n        $context->buildViolation('flightTicket.dateShouldBeValid')\n            ->addViolation();\n    }\n}\n
\n\n

The first step is done! Thanks to those static validators, we apply domain validation on command properties to ensure we can instantiate domain objects. But, domain validation only works with a single account because the account aggregate only represents the account of a single user. For instance, an account cannot validate if a username is unique because it needs to be aware of the rest of the created account.

\n\n

To check if a username is used by another user we will need to ask the repository if an account already exists with the given username. That’s why we will need to create a custom validation constraint because those constraints are declared as services, and they can depend on other application services.

\n\n
/** @Annotation */\nfinal class UsernameShouldBeUnique extends Constraint\n{\n}\n\nfinal class UsernameShouldBeUniqueValidator extends ConstraintValidator\n{\n    private Accounts $accounts;\n\n    public function __construct(Accounts $accounts)\n    {\n        $this->accounts = $accounts;\n    }\n\n    public function validate($username, Constraint $constraint): void\n    {\n        if (!$constraint instanceof UsernameShouldBeUnique) {\n            throw new UnexpectedTypeException($constraint, UsernameShouldBeUnique::class);\n        }\n\n        try {\n            $this->accounts->getByUsername(new Username($username));\n\n            // an exception is thrown if an account does not exist so we don’t add violation\n            $this->context->buildViolation('account.usernameShouldBeUnique')\n                ->addViolation();\n        } catch (UnknownAccount $exception) {\n        }\n    }\n}\n
\n\n

Finally, we need to configure the validator to apply this new constraint to the username property.

\n\n
/**\n * @Assert\\GroupSequence({\"CreateAnAccount\", \"Business\"})\n */\nfinal class CreateAnAccount\n{\n    /** \n     * @Assert\\Callback({\"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\UsernameShouldBeValid\", \"validate\"})\n     * @Domain\\Account\\UseCase\\ValidationRule\\UsernameShouldBeUnique(groups={\"Business\"})\n     */\n    private string $username;\n    \n    // ...\n}\n
\n\n

Caution: we need to apply static validators before applying custom constraints because we need to be sure we can instantiate all domain objects without raising any error. For instance, the instantiation of Username in UsernameShouldBeUniqueValidator must not raise any error because the goal of this constraint is not to check if the username contains at least three characters but if the username is already used. It can be done with GroupSequence. This validator feature allows adding groups to constraints and defining the validation constraint execution order.

\n\n

Now, this is the end of the story! If commands are invalid, we just need to serialize violations, give them to your front application, and print errors to users.

\n\n

Last word

\n\n

This might not be the only way to validate data but it worked on my previous project. Even if I use a service to validate my command I try to use as many domain objects as possible to avoid reinventing the wheel. I hope it answers Baptiste Langlade’s question on Twitter. If you wonder, Baptiste is not my brother ;).

\n\n

Thanks to my proofreaders @LaureBrosseau and @jjanvier_.

\n","url":"/how-to-validate-a-command.html","relative_path":"_posts/2021-03-04-how-to-validate-a-command.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"OOP: how to build an object","description":"Object-oriented programming: primary and secondary constructors. The primary constructor is the default way to build an object with all its dependencies. The secondary constructors provide other ways to build objects depending on use cases.","date":"2021-03-10 00:00:00 -0600","image":"build-object.webp","image_credit":"danist07","tags":["OOP","design-patterns"],"keywords":"software,oop,design patterns,primary constructor, secondary constructor","slug":"oop-how-to-build-an-object","ext":".md","excerpt":"

In this new blog post, I want to talk about object building more specifically about primary and secondary constructors. The primary constructor is the default way to build an object with all its dependencies. The secondary constructors provide other ways to build objects depending on use cases.

\n","content":"

In this new blog post, I want to talk about object building more specifically about primary and secondary constructors. The primary constructor is the default way to build an object with all its dependencies. The secondary constructors provide other ways to build objects depending on use cases.

\n\n

Note: I did not work on a PHP8 project yet so that is why I won’t talk about named arguments feature.

\n\n

Primary constructor

\n\n

The PHP language provides a single way to build an object thanks to the __construct() method. I use this method to define the primary constructor of my classes to encapsulate all their dependencies.

\n\n
final class Map\n{\n   private MapName $name;\n   private CartographersAllowedToEditMap $cartographersAllowedToEditMap;\n   /** @var Marker[] */\n   private array $markers;\n\n   public function __construct(\n       MapName $name,\n       CartographersAllowedToEditMap $cartographersAllowedToEditMap,\n       Marker ...$markers\n   ) {  \n       $this->name = $name;\n       $this->cartographersAllowedToEditMap = $cartographersAllowedToEditMap;\n       $this->markers = $markers;\n   }\n}\n
\n\n

Tip: If your objects encapsulate a collection of a specific type (like the Marker in this example), you can use variadic arguments to automatically validate each item of this collection. Here, we don’t need to iterate the collection to check the type of its items, the language does it for us.

\n\n

Secondary constructor

\n\n

The PHP language does not ease the data encapsulation because it only provides a single way to build objects but we should be able to define several constructors depending on all our use cases. How to solve this problem? Named constructors! Named constructors are static factories, in other words static methods that build the object itself.\nLet’s take an example with the map object. How to initialize a map without any marker?

\n\n
final class Map\n{\n    public static function initialize(\n       string $name,\n       array $cartographerAllowedToEditMap\n    ): self {\n       return new self(\n           new MapName($name),\n           new CartographersAllowedToEditMap($cartographerAllowedToEditMap),\n       );\n    }\n}\n
\n\n

Here, we added a named constructor called initialize to the Map class. It uses the primary constructor to build the map object with an empty collection of Marker objects.

\n\n

Tip: Some developers change the visibility of the primary constructor method to private but I am not a big fan of that. I use object comparison to test objects to avoid the usage of getters. I like keeping my primary constructor public because it allows me to build objects in any state to compare them to other ones.

\n\n
function it adds a marker on the map()\n{\n   $actualMap = Map::initialize(\n       'Bons plans sur Nantes',\n       ['Arnaud']\n   );\n\n   $actualMap->addMarker('Bubar');\n\n   $expectedMap = new Map(\n       new MapName('Bons plans sur Nantes'),\n       new CartographersAllowedToEditMap(['Arnaud']),\n       new Marker('Bubar')\n   );\n   \n   assertSame($actualMap, $expectedMap);\n}\n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/oop-how-to-build-an-object.html","relative_path":"_posts/2021-03-10-oop-how-to-build-an-object.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Persisting entities without ORM","description":"The repository pattern provides a good abstraction to manage object persistence. Even if a lot of projects use an ORM, persisting entities do not necessarily require it.","date":"2021-03-23 00:00:00 -0500","image":"persisting-entity-without-orm.webp","image_credit":"tofi","tags":["OOP","design-patterns"],"keywords":"software,oop,repository,design patterns,orm,persistence,sql,database","slug":"persisting-entities-without-orm","ext":".md","excerpt":"

Today, I will talk about persisting entities without ORM. First, I will introduce the repository pattern because it provides a good abstraction to manage object persistence. Then, we will see what are the impacts on the entity design.

\n","content":"

Today, I will talk about persisting entities without ORM. First, I will introduce the repository pattern because it provides a good abstraction to manage object persistence. Then, we will see what are the impacts on the entity design.

\n\n

Repository pattern

\n\n

The repository design pattern can be used to manage entity persistence and retrieval. It behaves like a collection of objects and hides the complexity of their storage. It ensures a clean separation between the domain model (the entity) and the data model (SQL tables). The following example shows a basic repository interface. Thanks to the Maps interface we will be able to add and retrieve Map entities, no matter their storage.

\n\n
interface Maps\n{\n   /**\n    * @throws \\LogicException\n    * @throws UnknownMap\n    */\n   public function get(MapId $mapId): Map;\n\n   /**\n    * @throws \\LogicException\n    */\n   public function add(Map $map): void;\n}\n
\n\n

Caution: All Maps implementations should be tested with the same test because we need to be sure they behave the same way. It ensures the application works no matter the chosen implementation.

\n\n

Let’s see how we can implement this interface with PostgreSQL for instance. The get method is only responsible to get information from the database to build the map entity whereas the add method extracts the entity information to store them in the database.

\n\n
class PostgreSqlMaps implements Maps\n{\n   private Connection $connection;\n\n   public function __construct(Connection $connection)\n   {\n       $this->connection = $connection;\n   }\n\n   public function get(MapId $mapId): Map\n   {\n       $sql = <<<SQL\n           SELECT map.\"mapId\", map.name\n           FROM map\n           WHERE map.\"mapId\" = :mapId\n       SQL;\n\n       $statement = $this->executeQuery($sql, ['mapId' => (string) $mapId]);\n\n       if (false === $map = $statement->fetchAssociative()) {\n           throw UnknownMap::withId($mapId);\n       }\n\n       return new Map($map['mapId'], $map['name']);\n   }\n\n   public function add(Map $map): void\n   {\n       $sql = <<<SQL\n           INSERT INTO map (\"mapId\", name)\n           VALUES (:mapId, :name)\n           ON CONFLICT (\"mapId\")\n           DO UPDATE SET name = :name;\n       SQL;\n\n       $this->executeQuery($sql, ['mapId' => $map, 'name' => $map->name()]);\n   }\n\n   private function executeQuery(string $sql, array $data): Result\n   {\n       // Execute query or throw logic exceptions if something goes wrong.\n   }\n}\n
\n\n

Tip: Thanks to the clause ON CONFLICT we can easily insert or update data with a single query.

\n\n

Entity design impacts

\n\n

Now we are able to persist and retrieve our map entity. Let’s study the impact on entity design.

\n\n

Let’s start with persistence. In the previous example, I used getters to get its properties but I am not a fan of the getter to be honest! Getters break data encapsulation because they expose object implementation details. They don’t follow the Tell don’t ask principle because we should not ask about the object state to do something, we should tell the object to do something for us. I like adding a toState method that is responsible to turn the entity into an associative array.

\n\n
final class Map\n{\n   public function toState(): array\n   {\n      return [\n          'mapId' => (string) $this->mapId,\n          'name' => (string) $this->name,\n      ];\n   }\n}\n
\n\n

So I just need to call the toState method instead of getters, this method returns data expected by the executeQuery method.

\n\n
class PostgreSqlMaps implements Maps\n{\n   // ...\n   public function add(Map $map): void\n   {\n       // ...\n       $this->executeQuery($sql, $map->toState());\n   }\n   // ...\n}\n
\n\n

Let’s continue with retrieval. If we have a look at the Mapconstructor method we can see that a MapInitialized event is recorded there. Houston, we have a problem! When we build an entity from its state (data stored somewhere) we don’t want to record any event because nothing happens. So, we need to find a solution to avoid recording those events.

\n\n
public function __construct(\n   MapId $mapId,\n   MapName $name\n) {\n   $this->mapId = $mapId;\n   $this->name = $name;\n\n   $this->recordEvent(new MapInitialized(\n       $mapId,\n       $name\n   ));\n}\n
\n\n

I like adding a named constructor called fromState to the entity. This constructor is responsible for building the aggregate from the state. Moreover, named constructors are explicit and give developers information about when to use them. In the following example, after calling the primary constructor we call the eraseRecordedEvents method to reset events before returning the object in the right state.

\n\n
public static function fromState(array $state): self\n{\n   $map = new self(\n       new MapId($state['mapId']),\n       new MapName($state['name'])\n   );\n\n   $map->eraseRecordedEvents();\n\n   return $map;\n}\n
\n\n

So, the only change in the repository is to build the Map entity from the named constructor.

\n\n
class PostgreSqlMaps implements Maps\n{\n\n   public function get(MapId $mapId): Map\n   {\n       // ...\n\n       return Map::fromState($map);\n   }\n}\n
\n\n

Last word

\n\n

I did a presentation about the repository design pattern at the Forum PHP in 2018. A video is only available in French here but the slides are in English here (press “s” to display English notes). Even if this presentation was made for Doctrine ORM it gives a lot of information about the pattern.

\n\n

Note: In this talk I spoke about generating the entity identity by the repository. To be honest, I stopped doing that because generating it from controllers is easier and makes the repository design simpler.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/persisting-entities-without-orm.html","relative_path":"_posts/2021-03-23-persisting-entities-without-orm.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"How did I organize my last Symfony projects?","description":"Return of experience: In this blog post, I will explain how I organized my last Symfony projects. They are mainly inspired by Hexagonal and CQRS architecture.","date":"2021-03-30 00:00:00 -0500","image":"project-symfony-organization.webp","image_credit":"alexkixa","tags":["software-architecture","symfony"],"keywords":"software,software architecture,symfony,cqrs,php,hexagonal architecture,port adapters,rex","slug":"how-did-I-organize-my-last-symfony-project","ext":".md","excerpt":"

In this blog post, I will explain how I organized my last Symfony projects. They are mainly inspired by Hexagonal and CQRS architecture. Keep in mind that I did not try to implement these architectures by the book, I only took some concepts that helped me to have a simple and clear codebase organization.

\n","content":"

In this blog post, I will explain how I organized my last Symfony projects. They are mainly inspired by Hexagonal and CQRS architecture. Keep in mind that I did not try to implement these architectures by the book, I only took some concepts that helped me to have a simple and clear codebase organization.

\n\n

If we have a look at the project’s root, nothing special happens, I kept all folders and files created during Symfony installation.

\n\n
tree . -L 1                       \n├── bin\n├── composer.json\n├── composer.lock\n├── config\n├── features\n├── public\n├── src\n├── symfony.lock\n├── tests\n├── translations\n├── var\n└── vendor\n
\n\n

In the next sections, we are going to see how I organized the src folder.

\n\n

Hexagonal architecture

\n\n

The foundation of the hexagonal architecture is the explicit separation between the domain (inside) and the infrastructure (outside). All dependencies are going from Infrastructure to the Domain.

\n\n

The domain is the part of the application that contains your business logic. It must reflect as much as possible the problem your application has to solve. This part of the application must not use IO, the infrastructure contains them all. For instance, IO are side effects like network calls, database queries, filesystem operations, actual timestamps or randomness..

\n\n

Based on that information my first decision was to split src into two areas: Domain and Infrastructure.

\n\n
tree src/Domain/ -L 1\napi/src/Domain/\n├── Domain\n└── Infrastructure\n
\n\n

Coupling rules:

\n\n\n

I am not a big fan of the onion architecture because I want to keep my projects as simple as possible. Having a lot of layers can be really hard to maintain because you need to align the whole team on the coupling rules. Agreeing with yourself is not easy, so getting several people to agree may be really hard. Here, we only have a single rule.

\n\n

Sometimes, I needed to write libraries because I could not find any open source libraries that match my expectations. To avoid coding in the vendor directory, I introduced a third area called Libraries (this new area is optional). Those libraries may be used in the domain and the infrastructure but their usage should not break the coupling rules that are defined for those areas.

\n\n
tree src/Domain/ -L 1\napi/src/Domain/\n├── Domain\n├── Infrastructure\n└── Librairies\n
\n\n

Coupling rules:

\n\n\n

Finally, I created a “sub” area called Application in the infrastructure that contains all pieces of code needed to have an application up and running: framework code (Symfony kernel, framework customizations), data fixtures, and migration.

\n\n
tree src/Infrastructure/Application -L 1 \napi/src/Infrastructure/Application\n├── Exception \n├── Fixture\n├── Kernel.php\n├── Migrations\n├── Security\n└── Kernel\n
\n

In this example, Exception and Security folders contain framework customizations.

\n\n

Business first

\n\n

A really important thing for me is to drive codebase organization by business concepts. I don’t want to name folders and classes with technical patterns like factory or repository for instance. Non-tech people should be able to understand what a class does thanks to its name.

\n\n

Domain

\n\n
tree src/Domain -L 1\napi/src/Domain\n├── Cartographer\n└── Map\n
\n\n

Because I did not use any technical words to name folders we can easily imagine the project is about making maps. Now, let’s have a look inside the Map directory:

\n\n
tree src/Domain/Map -L 1\n├── CartographersAllowedToEditMap.php   // Value object\n├── Description.php   // Value object\n├── MapCreated.php   // Event \n├── MapId.php   // Value object\n├── MapName.php   // Value object\n├── Map.php   // Root aggregate\n├── Maps.php   // Repository interface\n├── Marker    // All classes to design Marker entity\n├── MarkerAddedToMap.php   // Event\n├── MarkerDeletedFromMap.php   // Event\n├── MarkerEditedOnMap.php   // Event\n├── UnknownMap.php   // Exception\n└── UseCase    // Use cases orchestration\n
\n\n

In this folder, we have all the pieces of code needed to design the Map aggregate. As you can see, I did not organize it by design patterns like ValueObject, Event or Exception.

\n\n

As you might have understood the Map entity has a one-to-many relationship with the Marker entity. All classes needed to modelize this entity are in the Marker folder and they are organized the same way as the Map directory.

\n\n

The UseCase folder gathers all pieces of code needed to orchestrate use cases like command, their handler and business validation.

\n\n

Tip: I don’t suffix repositories by ‘Repository’ but I try to use a business concept to name them like ProductCatalog for a Product aggregate. If I can find a business concept to name it I use the plural of the aggregate because a repository is a collection of objects.

\n\n

Infrastructure

\n\n

I organize the root of the Infrastructure folder the same way as the Domain one.

\n\n
tree src/Infrastructure -L 1            \napi/src/Infrastructure\n├── Application\n├── Cartographer\n└── Map\n
\n\n

Now, let’s have a look at the Map directory:

\n\n
tree src/Infrastructure/Map -L 1 \napi/src/Infrastructure/Map\n├── Storage\n└── UserInterface\n        └── Web\n        └── Cli\n
\n\n

The Storage namespace gathers everything related to data storage like repositories, queries. The UserInterface namespace gathers everything related to ways to interact with the application like the WEB API (controllers) called by the front application or CLI (Symfony commands).

\n\n

CQRS

\n\n

CQRS is the acronym for Command Query Responsibility Segregation. The main idea of CQRS is that you can use different models for writing (command) or reading (query) information. I like the idea of having two small and simple models dedicated to a precise purpose: reading or writing instead of having one big model. It can prevent your aggregate from becoming a god object because as things progress you can have many write and read use cases to handle.

\n\n

From this pattern, I decided to split the domain into two areas, the first one: Command and the second one: Query. It allows me to design a model with the same name for these reading or writing purposes.

\n\n
tree src/Domain/ -L 2\napi/src/Domain/\n├── Command\n│   ├── Cartographer\n│   └── Map\n└── Query\n    ├── Cartographer\n    └── Map\n
\n\n

Coupling rule:

\n\n\n

Note: I did not make major changes in the infrastructure, the only change I made is to split the storage into two areas like the domain.

\n\n

Caution: For those projects, I did not make any projections because my database schema remained simple so I did not need them. I only decided to split my models because my codebase was simple and clearer this way.

\n\n

Last word

\n

I tried for the last few years to find the perfect architecture but it does not exist. I just tried to use some architectural concepts that make me and my teammates comfortable to work on a daily basis. This project organization has been used for two projects that are in production. One of these projects is a side project I made for fun to create maps without Google Maps. The second was a professional project, real people use it on a daily basis.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/how-did-I-organize-my-last-symfony-project.html","relative_path":"_posts/2021-03-30-how-did-I-organize-my-last-symfony-project.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Why you should not expose objects' state to test them","description":"Exposing the object's state to test them is not a good idea. Comparing object instances is better because it avoids breaking encapsulation and it does not have any impact on their design.","date":"2021-04-13 00:00:00 -0500","image":"test-comparison.webp","image_credit":"jdent","tags":["testing","OOP"],"keywords":"software,testing,unit test,oop,encapsulation,ask don't tell","slug":"you-should-not-expose-objects-state-to-test-them","ext":".md","excerpt":"

To introduce this topic, let’s have a look at the PHP documentation to understand how object comparison works using the comparison and identity operators.

\n","content":"

To introduce this topic, let’s have a look at the PHP documentation to understand how object comparison works using the comparison and identity operators.

\n\n
\n

When using the comparison operator (==), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values (values are compared with ==), and are instances of the same class.

\n\n

When using the identity operator (===), object variables are identical if and only if they refer to the same instance of the same class.

\n\n

PHP documentation

\n
\n\n
$object = new Object();\n$otherObject = new Object();\n\n$object == $otherObject // true\n$object === $otherObject // false \n
\n\n

I add an equals method to objects to handle object comparison. The purpose of this method is to compare an object state with another one. In the following example, I use the comparison operator (==) because I want to check if the objects have the same state no matter their references.

\n\n
final class Email\n{\n   private string $email;\n\n   public function __construct(string $email)\n   {\n       $this->email = $email;\n   }\n\n   public function equals(Email $email): bool\n   {\n       return $this == $email;\n   }\n}\n
\n\n

There is another way to compare object state. Do you know that instances of the same class can access each other’s private members?

\n\n
final class Email\n{\n   public function equals(Email $email): bool\n   {\n       return $this->email === $email->email;\n   }\n}\n
\n\n

Tip: This is really useful to compare Doctrine entities that have persistent collections. The error Error: Nesting level too deep - recursive dependency? is raised when we compare entities using the comparison operator (==). You should have a look at this blog post to understand why this error occured. Accessing private attributes let you use the identity operator (===) to prevent this error.

\n\n

By the way, entities are a bit special because an entity is an object that has an identity. It means that if we want to compare them we should compare their identities instead of their states.

\n\n
final class Map\n{\n   private MapId $mapId;\n\n   public function equals(MapId $mapId): bool\n   {\n       return $this->mapId->equals($mapId);\n   }\n}\n
\n\n

I add an extra method called hasSameState to entities to compare their states because entity state comparison remains really useful for testing.

\n\n
final class Map\n{\n   public function hasSameState(Map $map): bool\n   {\n       return $this == $map;\n   }\n}\n
\n\n

For a long time, I used getters for testing purposes. I only knew this way to ensure objects had the right state.

\n\n
$map = new Map('Best places at Nantes');\n\n$map->rename('Best places at Bordeaux');\n\n$map->getName()->shouldReturn('Best places at Bordeaux') ;\n
\n\n

It was a mistake because exposing objects’ state breaks data encapsulation. We should not know how objects work internally, we should only use their public API (public methods) to interact with them. But, if we need to build the Map object with something else than a string, this assertion will no longer be true. That will break all application tests and parts that use this getter! That’s not great! Object comparison I described previously helps to get rid of getters.

\n\n
$map = new Map('Best places at Nantes');\n\n$map->rename('Best places at Bordeaux');\n\n$map->hasSameState(new Map('Best places at Bordeaux'))->shouldReturn(true);\n
\n\n

Now, the Map object is better designed. Its state is not exposed anymore which improves data encapsulation. It follows the “Tell don’t ask” principle because I don’t need to extract its internal state to test it. I only need to use its public API to check if it meets the business exceptions.

\n\n

Tip: If you don’t want or if you can’t add a method to your objects that handles comparison you can still compare their instances to avoid adding getters.

\n\n
Assert::equals($map, new Map('Best places at Bordeaux'));\n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/you-should-not-expose-objects-state-to-test-them.html","relative_path":"_posts/2021-04-15-you-should-not-expose-objects-state-to-test-them.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Why unit testing can be hard?","description":"Testing can be really difficult for beginners. The main reason is that your code probably uses IO. This blog post gives you tips about improving your code design to ease testing.","date":"2021-05-03 00:00:00 -0500","image":"why-unit-testing-can-be-hard.webp","image_credit":"craftedbygc","tags":["testing","OOP"],"keywords":"software,testing,unit test,coupling,io,dependency inversion","slug":"why-unit-testing-can-be-hard","ext":".md","excerpt":"
\n

Unit tests are typically automated tests written and run by software developers to ensure that a section of an application (known as the “unit”) meets its design and behaves as intended

\n\n

Wikipedia

\n
\n","content":"
\n

Unit tests are typically automated tests written and run by software developers to ensure that a section of an application (known as the “unit”) meets its design and behaves as intended

\n\n

Wikipedia

\n
\n\n

I remember when I started to test my code it was really hard! It was mainly because I misunderstood some basics like what testing was about and the need of well-designed code. Unit tests ensure your code works as expected, but we often forget that unit testing is also the simplest way to have quick feedback during development phase.

\n\n

In this blog post, I will share what I learned to easily unit test my codebases.

\n\n

Test your public methods

\n\n

Objects should be seen as black boxes. Public methods are the only way to interact with objects, while private and protected methods are implementation details. We should not pay attention to how objects work internally. That’s why we don’t test private and protected methods. If you need to test them, that’s a design smell! Your objects might do too many things and they probably do not respect the Single Responsibility Principle.

\n\n
\n

The single-responsibility principle (SRP) is a computer-programming principle that states that every class in a computer program should have responsibility over a single part of that program’s functionality, which it should encapsulate.

\n\n

Wikipedia

\n
\n\n

Actually, it is better to have several small objects solving simple problems instead of having god objects that are doing everything the wrong way. If your objects become too big, split them into smaller ones because they are easier to maintain and to test.

\n\n

Do not unit test code that uses IOs

\n\n
\n

Input/output (I/O, or informally io or IO) is the communication between an information processing system, such as a computer, and the outside world, possibly a human or another information processing system.

\n\n

Wikipedia

\n
\n\n

For example, IO are side effects like: network calls, database queries, filesystem operations, actual timestamps or randomness.

\n\n

Do not deal with the outside

\n\n

The code covered by unit tests should not depend on the outside world like databases, external services and so on. Unit tests should not require any application setup, they have to remain as simple as possible. Their goal is to give you quick feedback by checking that a small piece of code (a unit) matches a business expectation. If you want to be sure that all application parts are well integrated with the outside world, you have to use an integration test.

\n\n

The following example shows a piece of code that depends on the external service. Here, we can’t build the Map object without a working database.

\n\n
final class HandleMarkerAddition\n{\n   private Connection $connection;\n\n   public function __construct(Connection $connection)\n   {\n       $this->connection = $connection;\n   }\n\n   public function __invoke(AddMarkerToMap $command): void\n   {\n       $mapState = $this->connection->executeQuery('SELECT ... FROM ...', [$command->mapId()]);\n\n       $map = Map::fromState($mapState);\n       $map->addMarker($command->name(), $command->location());\n\n       $this->connection->executeQuery('INSERT INTO ...', $map->toState()]);\n   }\n}\n
\n\n

The goal of this piece of code is to add a marker to a Map object, no matter how the object is stored. Tests that cover this class should focus on business use cases instead of technical details. A solution would be to use a repository design pattern to hide the map storage logic. The class will better follow the Single Responsable Principle because it will only handle the marker addition use case whereas the map repository will be in charge of storing data.

\n\n
final class HandleMarkerAddition\n{\n   private Maps $maps;\n\n   public function __construct(Maps $maps)\n   {\n       $this->maps = $maps;\n   }\n\n   public function __invoke(AddMarkerToMap $command): void\n   {\n       $map = $this->maps->get($command->mapId());\n       $map->addMarker($command->name(), $command->location());\n\n       $this->maps->add($map);\n   }\n}\n
\n\n

With this new design, it is easier to test this class. Thanks to the Maps interface , we are able to simply create test doubles for the map repository.

\n\n
// `PostgreSQLMaps` is the implementation used by default on the production\n$maps = new PostgreSQLMaps();\n(new HandleMarkerAddition($postgreSQLMaps)($command);\n\n// `InMemoryMaps` is an implementation that keeps map objects in memory for testing \n$maps = new InMemoryMaps();\n(new HandleMarkerAddition($inMemoryMaps)($command);\n\n// In both cases we can retrieve the Map object from the repository to check the map has the new marker.\n$map = $maps->get($command->mapId());\n$map->hasSameState(new Map('Best place', new Marker(/* … */))) // should return true;\n\n
\n\n

Do not deal with randomness

\n\n

Randomness makes your code unpredictable. To simply test a piece of code you should be able to predict its result. To ease unit testing your code should avoid using randomness as much as possible.

\n\n

The following example shows a piece of code that uses randomness.

\n\n
final class HashedPassword\n{\n   // ... \n\n   public function __construct(string $hash)\n   {\n       $this->hash = $hash;\n   }\n\n\n   public static function fromString(string $password): self\n   {\n       $hash = \\password_hash($password, PASSWORD_BCRYPT);\n\n       return new self($hash);\n   }\n\n   // ...\n}\n\nclass HashedPasswordTest extends TestCase\n{\n    /** @test */\n    function it builds a password from a string()\n    {\n        $this->assertEquals(\n            $this::fromString('Password1'),\n            new HashedPassword('$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu')\n        );\n    }\n}\n
\n\n

When we run HashedPasswordTest we get an error because the password_hash generates a random salt to hash the password. The problem is that the password_hash function cannot return the same hash for a given password. Each time you call this function a different hash will be returned.

\n\n
-Password Object &000000006e7168e60000000023b11bb2 (\n-    'hash' => '$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'\n+Password Object &000000006e7168210000000023b11bb2 (\n+    'hash' => '$2y$10$b/9GX4grnt4gH5cm8FzzSuUNGGQUiA/w.5HdKNEsW3dHtSUeTMXgK'\n
\n\n

The simplest solution would be to hardcode the salt to make sure the hash_password returns the same hash every time but this is not a good design. This would weaken the password generation because we need to test it. Another way would be to extract the hash generation in another place.

\n\n
final class HashedPassword\n{\n   // ...\n   public static function fromString(string $password, PasswordEncryptor $passwordEncryptor): self\n   {\n       $hash = $passwordEncryptor->hash($password);\n\n       return new self($hash);\n   }\n   // ...\n}\n
\n\n

The PasswordEncryptor interface makes test doubles creation possible. Now, we just need to create a fake object to test this method.

\n\n
final class FakePasswordEncryptor implements PasswordEncryptor\n{\n    public function hash(): string\n    {\n        return '$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu';\n    }\n\n}\n\nclass HashedPasswordTest extends TestCase\n{\n   /** @test */\n   function it builds a password from a string()\n   {\n        $fakePasswordEncryptor = new FakePasswordEncryptor();\n\n        $this->assertEquals(\n            this::fromString('Password1', $fakePasswordEncryptor),\n            new HashedPassword('$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu')\n        );\n   }\n}\n
\n\n

Avoid actual datetimes

\n\n

With actual datetimes, we have the same problem as with randomness, neither can be predicted.

\n\n

The following example shows you that actual datetimes are not predictable like hash_password in the previous section.

\n\n
final class Map\n{\n   // ...\n   public function __construct(\\DateTimeImmutable $markerAddedAt = null, Marker ...$makers)\n   {\n       // ...\n   }\n\n   public function addMarker(string $name, array $location): void\n   {\n       // ...\n       $this->markerAddedAt = new \\DateTimeImmutable('now');\n   }\n}\n\nclass MapTest extends TestCase\n{\n    /** @test */\n    function it adds marker to the map()\n    {\n        $map = new Map('Map name');\n        $map->addMarker('Bubar', [47.21725, -1.55336]);\n        \n        $this->assetTrue(\n            $map->hasSameState(\n                new Map(\n                    new Marker('Bubar', [47.21725, -1.55336]), \n                    new \\DateTimeImmutable('now')\n                )\n            )\n        );\n    }\n}\n
\n\n

When we run MapTest we get an error because we can predict to the millisecond when the marker was added to the map.

\n\n
-Map Object &000000003acad975000000006b83e943 ()\n+Map Object &000000003acad936000000006b83e943 (\n+    'markerAddedAt' => DateTimeImmutable Object &000000003acad946000000006b83e943 (\n+        'date' => '2021-04-18 17:36:02.919004'\n+        'timezone_type' => 3\n+        'timezone' => 'UTC'\n+    )\n+)\n
\n\n

To prevent this kind of problem, a good idea is to abstract time by introducing an interface that is responsible for time management.

\n\n
final class Map\n{\n  // ...\n  public function addMarker(string $name, array $location, Clock $clock): void\n  {\n      // ...\n      $this->markerAddedAt = $clock->now();\n  }\n   // ...\n}\n
\n\n

Now, thanks to the Clock interface we will be able to create test doubles and easily test this method.

\n\n

Coupling might be your worst enemy

\n\n
\n

Coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.

\n\n

Wikipedia

\n
\n\n

As you have seen in the previous sections, objects should depend on abstractions instead of concrete implementations. Abstractions (e.g. interfaces) ease testing because your code is more modular. You can use test doubles to reduce the complexity and facilitate testing. Their goal is to mimic the behavior of real objects to replace a subpart of an algorithm.

\n\n

The following example shows that hardcoding object dependencies won’t help to create test doubles.

\n\n
class MyClass\n{\n   public function __construct(ConcreteImplementation $concreteImplementation)\n   {\n       // Here we can only use these concrete implementations, if they use IO for instance you won't be able to test it.\n       $this->concreteImplementation = $concreteImplementation;\n       $this->anotherConcreteImplementation = new AnotherConcreteImplementation();\n      \n       // Singleton pattern does not help because it hides object dependencies and makes them hard coded.\n       $this->connection = Connection::getInstance();\n   }\n}\n
\n\n

The solution is to use the dependency inversion pattern to remove hard coded dependencies introducing abstractions as much as possible.

\n\n
\n

High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g., interfaces). Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.

\n\n

Wikipedia

\n
\n\n

In the following example, all class dependencies are interchangeable. So, you can easily create test doubles like fake, stub, or mocks to make sure your objects meet business expectations.

\n\n
class MyClass\n{\n   public function __construct(\n       ImplementationInterface $concreteImplementation,\n       AnoherImplementationInterface $anotherConcreteImplementation,\n       ConnectionInterface $connection\n   ) {\n       $this->concreteImplementation = $concreteImplementation;\n       $this->anotherConcreteImplementation = $anotherConcreteImplementation;\n       $this->connection = $connection;\n   }\n}\n
\n\n

Caution: That does not mean you should use interfaces everywhere! Knowing when to introduce new abstractions might be hard at the beginning, there is no magic recipe!

\n\n

Thanks to my proofreaders @LaureBrosseau and @jjanvier_.

\n","url":"/why-unit-testing-can-be-hard.html","relative_path":"_posts/2021-05-04-why-unit-testing-can-be-hard.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Objective: set up your projects more easily","description":"Setting up a project locally should be easy to let devs focus on delivering value. Makefile can provide an abstraction to simplify their installation and hide the complexity.","date":"2021-06-02 00:00:00 -0500","image":"set-up-your-projects-more-easily.webp","image_credit":"intelligenciya","tags":["makefile"],"keywords":"makefile,software,setup,installation","slug":"objective-set-up-your-projects-more-easily","ext":".md","excerpt":"

For the last decade I worked on several more or less complex projects. I often had problems with their installation. Sometimes, the project was not documented or the existing documentation was not up to date. I had to run commands but I did not understand all of them. When I got errors it was hard to understand what happened. That was not always simple.

\n","content":"

For the last decade I worked on several more or less complex projects. I often had problems with their installation. Sometimes, the project was not documented or the existing documentation was not up to date. I had to run commands but I did not understand all of them. When I got errors it was hard to understand what happened. That was not always simple.

\n\n

During my last projects, I used makefile to provide an abstraction to simplify their installation and hide complexity. It let me install projects with a single command and provided a minimal set of targets which made my daily work easier.

\n\n

How does makefile work?

\n\n

A makefile is a set of “rules” that looks like:

\n\n
target: prerequisites prerequisites\n        recipe\n        recipe\n        ...\n
\n\n

A target is the name of a file (or a folder) that is generated by make. It could also be the name of an action to perform but you need to declare it as PHONY.

\n\n

A prerequisite are the files (or folders) needed to create the target, you can see them as target dependencies.

\n\n

A recipe are all actions executed when the target is run. Caution: you need to indent all recipes using a “real” tab character otherwise you will get errors.

\n\n
.env:\n     cp .env.dist .env\n
\n\n

If the .env file does not exist, the recipe will be carried out, but if it does exist the recipe won’t be executed #magic.

\n\n
.PHONY: cache\ncache: .env\n      bin/console c:c\n
\n\n

The cache target does not target a file. Declaring this target as PHONY allows having a file named cache in the same directory as the Makefile.

\n\n

Note: If the .env file does not exist the .env target will be performed before the cache target.

\n\n

Let’s take an example

\n\n

For instance, a project orchestrated by docker-compose having:

\n\n\n

Caution: I will only speak about projects setup for dev purposes. I won’t talk about making docker images ready for production.

\n\n

Let’s start installing the project dependencies. The following targets install project dependencies if they have not been downloaded yet. They can guess if they are outdated to upgrade them thanks to target prerequisites. Another interesting thing is that nothing will be done if dependencies are already installed and up to date.

\n\n
# Front\nweb/yarn.lock: web/package.json\n  docker-compose run --rm node yarn install\n\nweb/node_modules: web/yarn.lock\n  docker-compose run --rm node yarn install --frozen-lockfile\n  docker-compose run --rm node yarn check --integrity\n\n# back\napi/composer.lock: api/composer.json\n  docker-compose run --rm fpm composer update\n\napi/vendor: api/composer.lock\n  docker-compose run --rm fpm composer install\n\n
\n\n

Then, we need to “up” all docker-compose services: the web server, the PHP process manager, the datatable, and the node to run the front application in development mode.

\n\n
.PHONY: up\nup:\n  docker-compose up -d\n
\n\n
docker-compose ps                                              \n         Name                        Command               State                                     Ports                                   \n---------------------------------------------------------------------------------------------------------------------------------------------                                                     \nmy-maps-node              docker-entrypoint.sh yarn  ...   Up                                                                                \nmy-maps-web               nginx -g daemon off;             Up      80/tcp                                                                    \nmy-maps_database_1        docker-entrypoint.sh postgres    Up      5432/tcp                                                                  \nmy-maps_fpm_1             php-fpm -F                       Up                                                                           \n
\n\n

The last thing to do is to create the database schema using Doctrine migration.

\n\n
.PHONY: db-migration\ndb-migration: api/vendor\n  docker-compose run --rm fpm bin/console doctrine:migrations:migrate --no-interaction\n
\n\n

Tip: To ease my daily work, I like introducing other targets like db target that resets database quickly or fixture to load some data fixtures.

\n\n
.PHONY: db\ndb: api/vendor\n  docker-compose run --rm fpm bin/console doctrine:database:drop --force --no-interaction\n  docker-compose run --rm fpm bin/console doctrine:database:create --no-interaction\n\n.PHONY: fixtures\nfixtures: api/vendor\n  docker-compose run --rm fpm bin/console project:fixtures:load\n
\n\n

Now, we have all atomic targets to set up all parts of the application. Another interesting thing with make, is that it can run several targets within a single command make up api/vendor web/node_modules.This is pretty useful to create scenarios. For instance, to set up and run the project I only need to run the following command:

\n\n
make up api/vendor web/node_modules db db-migration fixtures\n
\n\n

But it works with everything:

\n\n
make db db-migration fixtures\nmake api/vendor web/node_modules\n
\n\n

To make your day-to-day basis, you can introduce targets that run those scenarios.

\n\n
# It builds and runs the application\n.PHONY: app-dev\napp-dev: up api/vendor web/node_modules db db-migration fixtures\n\n# It resets the database\n.PHONY: db-reset\ndb-reset: db db-migration fixtures\n\n# It resets the database\n.PHONY: dependencies\ndependencies: api/vendor web/node_modules\n
\n\n

Tip: I advise you to introduce the minimum set of targets into the makefile. Keep it simple! Don’t forget that everyone uses it! To let developers have their custom targets you may want to include custom makefiles using include. Don’t forget to add an entry into .ignore to avoid committing those files. Now, developers can create their own makefile with their personal targets.

\n\n

One last word

\n\n

Makefile is only a solution, this is not THE solution. The important thing to keep in mind is that you should be able to easily run your project to reduce the developer’s mental load and let them focus on the right thing. It will improve the day-to-day basis and make newcomers’ onboarding easier.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/objective-set-up-your-projects-more-easily.html","relative_path":"_posts/2021-06-02-objective-set-up-your-projects-more-easily.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"The command bus design pattern","description":"The goal of command and the event bus is to deliver a command or an event to its handler(s). Events and commands are objects used to encapsulate information needed to achieve an action (a command) or to tell what happened in the system (an event).","date":"2022-09-12 00:00:00 -0500","image":"command-bus/command-bus.svg","keywords":"software,software architecture,design patterns,command bus,event bus,bus,middleware","tags":["command-bus","design-patterns"],"slug":"command-bus-design-pattern","ext":".md","excerpt":"

Note: Before reading this blog post, if you don’t know what a command and a command handler are, I advise you to first read the blog post I’ve written about those design patterns. It will help you to understand this new article:

\n","content":"

Note: Before reading this blog post, if you don’t know what a command and a command handler are, I advise you to first read the blog post I’ve written about those design patterns. It will help you to understand this new article:

\n\n
\n \n \n \"Command\n \n \n Command and command handler design pattern\n \n \n
\n\n

What is a bus?

\n\n

Let’s start with the basics, what is a bus? In computer science, a bus is a system that connects several components and transfers data between them. In software, those components are called middleware. A middleware processes an incoming request and returns a response. As you can see in the schema below, the main advantage of a bus is that it is highly customizable as you can add as many middleware as you want.

\n\n

\"A

\n\n

In the next sections, we will speak about the command bus which is often associated with an event bus. Using an event bus is not mandatory but we will see how it will make your application more modular and evolutive. Their goal is to deliver a command or an event to their handler(s). Events and commands are objects used to encapsulate information needed to achieve an action (a command) or to tell what happened in the system (an event).

\n\n

The command bus

\n\n

Quick reminder about command and command handler: A command represents a user’s intent. The data carried by the command has to be valid. It can be only handled by only one handler that is just a callable that will perform the user action.

\n\n

Now, we will build a command bus following the same architecture that I described in the previous section. The only difference is that the command bus will return void. As commands canmight be handled asynchronously, we don’t want to wait for the result of the command processing.

\n\n

\"A

\n\n

Let’s see the most common middleware used to build a command bus. The first one is probably the “logging middleware”. It helps to make your application observable and it is really useful for bug hunting. Then the “validation middleware” ensures that the command is valid before giving it to the handler. Its purpose is to stop the command processing if data is invalid. It is pretty convenient because it avoids validating them manually. When your application uses a database, the “transaction middleware” wraps the handler execution into a SQL transaction. It makes sure all database changes are done, otherwise it rollbacks the transaction. Finally, the last middleware is responsible for finding and executing the handler that matches the command.

\n\n

The event bus

\n\n

An event represents something that happened in the application. Unlike a command, an event can be handled by several handlers. Listening to events allows us to enhance existing features or add new ones very quickly. Several teams can listen to the same event to perform additional tasks depending on business needs. It makes applications more evolutive without adding accidental complexity and lets your team work isolated from each other.

\n\n

Tip: I would like to encourage you to mainly use business-oriented events instead of technical ones. They clearly describe what happened from a business point of view. For example, NewAccountHasBeenCreated is more understandable than ResourceCreated with a resource property equal to ‘Account’

\n\n

Even if the event bus is built the same way as the command bus we don’t need all the different middleware. We don’t need the validation middleware because events are generated by the aggregates with value objects. Those objects ensure domain invariant which means they are always valid. We also don’t need the transactional middleware because the event will be processed into the transaction begun during the command processing. Moreover, depending on your business needs you may not want to process events into this transaction. Let’s take a simple example. After creating an account, an event AccountCreated is dispatched, then a welcome email is sent during AccountCreated processing. If the email sending fails, do we want to roll back the account creation? Not sure! In that case, you need to speak with your product manager to decide how to process this event.

\n\n

As I said previously, events are recorded by aggregates and they should be business oriented. I will share with you two ways to dispatch events into the event bus.

\n\n

\"A

\n\n

Solution 1: You can collect them from your repository if no errors have been raised during the aggregate persisting and then dispatch them.

\n\n

Solution 2: The other solution is to collect events from the command handler. The handler can return them, and then the “handle command” middleware catches and dispatches them.

\n\n

Note: My previous blog post about the command and command handler pattern said that a command handler should return void. Here, the idea is that the command bus should return void only the “handle command” should be aware of the result of the handler execution.

\n\n

I’ve written a bunch of articles about how to handle a command, validate its data, handle user permissions, and so on. Take a look at these articles:

\n\n
\n \n \n \"See\n \n \n See all blog posts about command handling.\n \n \n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/command-bus-design-pattern.html","relative_path":"_posts/2022-09-12-command-bus-design-pattern.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"How to handle user permissions through command bus middleware","description":"Applying user permissions might be very complex and can lead to introducing a lot of accidental complexity to your application. Adding a middleware to your command bus can solve this issue.","date":"2022-09-26 00:00:00 -0500","image":"how-to-handle-permissions-through-command-bus-middleware.webp","image_credit":"kellysikkema","keywords":"software,software architecture,design patterns,command bus,permissions,security,bus,middleware","tags":["command-bus"],"slug":"how-to-handle-user-permissions-through-command-bus-middleware","ext":".md","excerpt":"

Applying user permissions might be very complex and can lead to introducing a lot of accidental complexity to your application. In this blog post, I want to share with you how to do it by simply adding a middleware to your command bus.

\n","content":"

Applying user permissions might be very complex and can lead to introducing a lot of accidental complexity to your application. In this blog post, I want to share with you how to do it by simply adding a middleware to your command bus.

\n\n

Note: If you’re not familiar with this pattern, please have a look at this blog post, it explains what a command bus and a middleware are.

\n\n

Let’s imagine a basic use case: an application with two kinds of users: regular ones and admins. We want to allow certain actions only to admin users.

\n\n

First, I will introduce an interface OnlyPerformedByAdministrator that will be implemented by the command restricted to the admin users.

\n\n
interface OnlyPerformedByAdministrator\n{\n    public function username(): string;\n}\n\nclass CreateNewProduct implements OnlyPerformedByAdministrator\n{\n    // ...\n    public function username(): string\n    {\n        return $this->username;\n    }\n}\n
\n\n

Then, we will add a CheckAccessPermission middleware to the command bus that will check if the user can execute an action. If he/she can’t, an AccessDenied exception will be thrown. It will be caught later in the execution flow to be turned into something that will be understandable to the user.

\n\n
final class AccessDenied extends \\Exception\n{\n}\n\nclass CheckAccessPermission implements Middleware\n{\n    public function __construct(private Users $users) {}\n\n    final public function handle(Command $command, Middleware $next): void\n    {\n        $user = $this->users->get(new Username($command->username()));\n        if ($command instanceof OnlyPerformedByAdministrator && !$user->isAdmin()) {\n            throw new AccessDenied();\n        }\n\n        $next->handle($command);\n    }\n}\n
\n\n

This middleware will stop the command processing if an error is raised. We need to catch this exception to return a 403 HTTP response in the web controller, or to return a status code greater than 0 in the CLI command.

\n\n
final class WebToggleCartographerPremiumStatus\n{\n    public function __construct(private CommandBus $commandBus) {}\n    \n    public function __invoke(Request $request): Response\n    {\n        try {\n            $this->commandBus->handle(new CreateNewProduct(/** ... */));\n        } catch (AccessDenied) {\n            throw new Response(403, 'Access denied');\n        }\n\n        return new Response(200);\n    }\n}\n
\n\n

Why do I handle permissions with a middleware?

\n\n

I decided to add a middleware to the command bus because it ensures that permissions are checked no matter where commands are dispatched. For example: from the web controller or a CLI command. Moreover, I don’t depend on a security library or any framework configuration. All permission business rules are coded in the domain.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/how-to-handle-user-permissions-through-command-bus-middleware.html","relative_path":"_posts/2022-09-26-how-to-handle-user-permissions-through-command-bus-middleware.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Increase your test quality thanks to builders or factories","description":"Bad tests are hard to maintain and they slow down your productivity. Test code quality is as important as production code. The builder or factory patterns can help you to improve your test code quality. It will ease test refactoring and make tests more readable.","date":"2022-10-10 00:00:00 -0500","image":"increase-your-test-quality-thanks-to-builders-or-factories.webp","image_credit":"thoughtcatalog","keywords":"testing,test,software,design pattern,code quality","tags":["testing"],"slug":"increase-your-test-quality-thanks-to-builders-or-factories","ext":".md","excerpt":"

In a previous blog post, I explained why it’s better to compare object instances instead of exposing their state to test them. This avoids breaking encapsulation and it does not have any impact on their design.

\n","content":"

In a previous blog post, I explained why it’s better to compare object instances instead of exposing their state to test them. This avoids breaking encapsulation and it does not have any impact on their design.

\n\n

Let’s take an example! My side project allows me to create maps to remember places I have been. A map has a name and, as a cartographer, I am allowed to rename it. Real basic use case but more than enough! The following test ensures I can rename this map:

\n\n
$map = new Map(\n    new MapId('e9a01a8a-9d40-476e-a946-06b159cd484a'),\n    new Username('Pepito'),\n    new MapName('Bordeaux city'),\n    new Description('Good places in Anglet'),\n    Tag::city(),\n    MarkerList::empty(),\n);\n\n$map->rename('Anglet city');\n\nAssert::equals(\n    $map,\n    new Map(\n        new MapId('e9a01a8a-9d40-476e-a946-06b159cd484a'),\n        new Username('Pepito'),\n        new MapName('Anglet city'),\n        new Description('Good places in Anglet'),\n        Tag::city(),\n        MarkerList::empty(),\n    )\n);\n
\n\n

We can see that comparing object instances is great for encapsulation because we don’t expose the object’s state but this makes the test less readable. Here, the only thing we want to focus on is the value of MapName. The values of the other value object are only noise because they are not useful for this test. But, this is not the only drawback of this test. What happens if you want to add an extra property to the Map object? In this case, we will need to refactor all the tests that create a map object. It might be easily doable in small projects but it can become messy for big ones.

\n\n

Now, let’s show how we can improve this test. The title of my blogpost can give you a huge hint on the solution. We will add a named constructor called whatever to the Map object to centralize the object construction. Named constructors are static factories that build the object itself.

\n\n
class Map \n{\n    /** @internal */\n    public static function whatever(\n        string $mapId = 'e9a01a8a-9d40-476e-a946-06b159cd484a',\n        string $addedBy = 'Pepito',\n        string $name = 'Anglet city',\n        string $description = 'Good places in Anglet',\n        string $tag = 'city',\n        array $markers = [],\n    ): self {\n        return new self(\n            new MapId($mapId),\n            new Username($addedBy),\n            new MapName($name),\n            new Description($description),\n            new Tag($tag),\n            new MarkerList($markers),\n        );\n    }\n}\n
\n\n

Tip: I like to add a @internal annotation to remind all teammates that the object constructor should only be used in tests.

\n\n

The value object instantiation is delegated to the whatever constructor. I try to use primitive data types like arguments as much as possible, it makes me write less code and it’s easier to read. All constructor arguments have a default value, then I can override a given value depending on the needs thanks to the named argument feature.

\n\n
$map =  Map::whatever(name: 'Bordeaux city');\n\n$map->rename('Anglet city');\n\nAssert::equals(\n    $map,\n    Map::whatever(name: 'Anglet city')\n);\n
\n\n

Now, the test is clear and focuses on the right thing. Everyone can easily understand it, and it will help your teammates to grasp the code you wrote. Refactoring will be simplified as you only have to rewrite the whatever constructor if the signature of the primary constructor of Map changes.

\n\n

I know that some people won’t like the idea of adding a method to objects only for testing purposes. If you don’t like that, you can replace this static factory with a builder.

\n\n
class MapBuilder\n{\n    private string $mapId = 'e9a01a8a-9d40-476e-a946-06b159cd484a';\n    private string $addedBy = 'Pepito';\n    private string $name = 'Anglet city';\n    private string $description = 'Good places in Anglet';\n    private string $tag = 'city';\n    private array $markers = [];\n\n    public function identifiedBy(string $mapId): self\n    {\n        $this->mapId = $mapId;\n        \n        return $this;\n    }\n\n    public function named(string $name): self\n    {\n        $this->name = $name;\n\n        return $this;\n    }\n\n    // ... other setters ....\n\n    public function build(): Map {\n        return new Map(\n            new MapId($this->mapId),\n            new Username($this->addedBy),\n            new MapName($this->name),\n            new Description($this->description),\n            new Tag($this->tag),\n            new MarkerList($this->markers),\n        );\n    }\n}\n
\n\n

Then your test will look like this:

\n\n
$map =  (new MapBuilder())->named('Bordeaux city')->build();\n\n$map->rename('Anglet city');\n\nAssert::equals(\n    $map,\n    (new MapBuilder())->named('Anglet city')->build()\n);\n
\n\n

Tip: Read or anemic models don’t have logic to ensure they are built in a good way. If you use this method for them you can add some logic to your builder/factories to ensure they are created with consistent data. It will make your tests stronger.

\n\n

Final thought

\n\n

Builders or factories ease test refactoring and make tests more readable. Don’t forget that bad test suites are a nightmare to maintain and can drastically slow down your delivery. Taking care of your test quality will help you to ship fast. Moreover, good tests are free documentation.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/increase-your-test-quality-thanks-to-builders-or-factories.html","relative_path":"_posts/2022-10-10-increase-your-test-quality-thanks-to-builders-or-factories.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"How I have learned programming by myself","description":"Learning is an important part of our job. It is not that easy when you don’t know where to start, especially if you're self-taught like me. I share what I did to learn software development for the last 15 years in this blog post.","date":"2022-10-17 00:00:00 -0500","image":"how-I-have-learned-programming-by-myself.webp","image_credit":"thoughtcatalog","keywords":"learning,knowledge,software,continuous learning,self taught,mentor,open source,conference,books,burnout,training","tags":["learning"],"slug":"how-I-have-learned-programming-by-myself","ext":".md","excerpt":"

I am, what we call, a self-taught. I studied telecommunications and networks at school, unfortunately, I only learned the basics of programming. I had to learn and improve my skills by myself for many years during my free time. I did not take the easiest path to learn! That’s why I wanted to share with you my own experience and what I did to learn software development. I hope this post will help some of you.

\n","content":"

I am, what we call, a self-taught. I studied telecommunications and networks at school, unfortunately, I only learned the basics of programming. I had to learn and improve my skills by myself for many years during my free time. I did not take the easiest path to learn! That’s why I wanted to share with you my own experience and what I did to learn software development. I hope this post will help some of you.

\n\n

Find a mentor

\n\n

In the beginning, even though I knew some basics of programming I was a bit lost. I wasn’t able to build an application end to end and I did not know which subject I had to study to solve that. That’s why I advise junior engineers to find at least one mentor. A mentor can teach you what is important like how to test, design patterns, software architecture, and so on. A mentor will help you focus on the right topics like how to build robust applications instead of focusing on hype technologies.

\n\n

Tip: If you’re a junior, I would recommend you focus on testing: TDD will help you to design your code step by step. Architectural patterns like hexagonal architecture will help you to decouple your code from IO. Agile: eXtreme programming will help you to reduce the cost of changes by having multiple short development cycles rather than a long one.

\n\n

Play and have fun with a side project

\n\n

You can have strong constraints at work, so it can be really hard to try new things because of bad processes, bad code quality, impossible deadlines etc. I have worked on several side projects for the last 10 years. I tried twice to release an application for a French NGO to manage their volunteer data. Then I tried to make an application to organize my trips. The last one is about making maps to remember places I have been. I learned a lot from those projects, they let me try what I read in blog posts, books or what I saw in conferences without any pressure of production. The funny thing is that I learned more from failures. Only my last side project “mymaps” is live, I did not release the other ones! This is because they were only playgrounds rather than real projects. They helped me understand why being pragmatic is important, focusing only on technical aspects does not help to build an application. Keep in mind that a good codebase is not the only thing you need to make a successful project.

\n\n

Contribute to an open-source project

\n\n

I worked on Sylius which is an open-source e-commerce framework. The community of Sylius is great. I learned a lot of good practices like testing, code review and behaviour-driven development for instance. I mainly worked on the SyliusResourceBundle which is a library that eases CRUD management. During this period, I was working for a web agency, it helped me to be more efficient at work and ship projects faster.

\n\n

Caution: Many companies use open-source projects but they don’t contribute to them. I was happy to contribute to this project during my free time, but you should negotiate allocated time with your company to help those projects if they help you deliver value to your customers.

\n\n

I would like to thank Pawel for making me a core team member. Contributing to Sylius has opened many doors to me.

\n\n

Thanks to what I have done in that library, I had the chance to do my first conference (Symfony live) as a speaker. That was so great! I was so excited and terrified at the same time. Then I got hired by a french startup Akeneo to work on an open-source PIM (Product Information Management). I only worked for service companies before Akeneo, this experience made me discover what was software edition.

\n\n

Attend conferences and meetups

\n\n

Attending conferences is a great way to learn and open your mind to new things. You can have a chat with other attendees during breaks as well. It is a good way to meet new people and to have interesting talks. One of my favourite conferences is newcraft, its local edition at Bordeaux was really great too.

\n\n

When you will be comfortable the next step will be to do a presentation. Preparing a talk is good to dive into the topic you will present and formalize your ideas. Even if you know this topic, it may not be that easy to clearly explain it to someone else. Don’t be shy, submit your talks! A lot of conference organizations help new speakers. I did not think too much when I submitted my first talk. I thought it wouldn’t be selected but I received an email that said my talk was accepted. I was so happy and excited! I realized what happened and I really started to panic (true story, a little panic attack) so I started to work on my talk to be ready for D-day. You can have a look at my talks.

\n\n

Read books

\n\n

Another way to learn is through books. This is a good way to shut down your computer while still learning new things about software engineering.

\n\n

Tip: Some books in my library: Accelerate, Extreme Programming Explained, Domain-Driven Design Distilled, Patterns, Principles, and Practices of Domain-Driven Design, Elegant Objects and so on.

\n\n

Final thoughts

\n\n

A few weeks ago, I saw some software engineers saying on social media that we should self-train in our free time. Learning in your free time will help you progress faster but it can be time and energy consuming. Don’t forget that burnouts are real. One of my friends experienced burnout and couldn’t do anything for almost a year, he was completely out of energy.

\n\n

I also had to take several breaks in my learning process to avoid going to the dark side of the force. Only do things when you want in your free time! Don’t put pressure on yourself! And keep in mind that learning should be fun!

\n\n

Learning is a part of your job. Companies should let you learn during business hours. On a day-to-day basis, pair and mob programming is a good way to learn and challenge your ideas. Your company should train you as well. For instance, Mathias Noback gave us some training when I was at Akeneo. I learned a lot from him, and I definitely recommend him!

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/how-I-have-learned-programming-by-myself.html","relative_path":"_posts/2022-10-17-how-I-have-learned-programming-by-myself.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"My feedback about example mapping","description":"Example mapping is a good way to align the team's understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.","date":"2022-10-31 00:00:00 -0500","image":"example-mapping/my-feedback-about-example-mapping.webp","image_credit":"amandagraphc","keywords":"example mapping,bdd,behavior driven development,no estimate,team collaboration,sticky note,small story,domain problem","tags":["BDD","methodology"],"slug":"my-feedback-about-example-mapping","ext":".md","excerpt":"

Example mapping is a workshop that gathers tech and non-tech people to ensure everyone has the same understanding of the domain problem. It also helps clarify the acceptance criteria for a given story. Because it’s always better to understand what is expected and raise all bottlenecks before developing a story.

\n","content":"

Example mapping is a workshop that gathers tech and non-tech people to ensure everyone has the same understanding of the domain problem. It also helps clarify the acceptance criteria for a given story. Because it’s always better to understand what is expected and raise all bottlenecks before developing a story.

\n\n

Disclaimer! I won’t explain how to run such a workshop, you can easily find a bunch of articles on the web. You can also have a look at these slides, they come from one of my talks about example mapping if you’re not familiar with it. In this blog article, I want to share with you my experience on Example Mapping and how it helps me to prepare and organize the team’s work.

\n\n

Caution: A little while ago, I got feedback from Bruno Boucard about using sticky notes. He advised me to use index cards instead of sticky notes. The workshop attendees can put them on a table and easily move them, unlike stick notes. I speak about sticky notes in this blog post because I only practiced this workshop remotely using tools like Miro.

\n\n

Who will attend the workshop?

\n\n

The methodology recommends to involve at least the product managers, developers and testers. The goal of example mapping is that the product manager shares the problem with the person(s) who will solve it. I will go further, you can invite anyone who wants to understand what you are doing. It is a good way to share knowledge.

\n\n

During my last year at Akeneo, I worked on a new product called Shared Catalogs. All my teammates including devs, product manager, and engineering managers were newcomers. Even if they were really well onboarded on Akeneo’s products, they had a micro vision of what Akeneo PIM did, and the software’s functional perimeter was pretty huge. At this time, I was working at Akeneo for 4 years, andI had a good understanding of the product. During the example mapping sessions I shared as much knowledge as possible with my teammates, it helped the team to quickly improve their functional skills.

\n\n

When do we plan it?

\n\n

From my experience, a 30-minute slot is a good tradeoff. It’s not too long and you can easily illustrate the main business rules of the story and detect all bottlenecks. With a 30-minute meeting, you’re sure that your teammates will stay focused, especially when you work remotely. Having regular and short workshops is better than doing a big and long one.

\n\n

Depending on their roles, some team members can be really busy. For instance, I worked with several PMs who were often in meetings and it was really hard to catch them. To be sure that everyone can be available, each team member booked a 30 minutes slot after the daily meeting. Doing an example mapping was not mandatory, we only did the workshop if we needed to prepare stories.

\n\n

How organize the team

\n\n

The attendees can have different roles: onek person writes sticky notes, another animates the workshop and the others ask questions and drive the person who writes sticky notes. I think it is important to switch his/her role each session to keep everyone involved during the workshop.

\n\n

I worked with some product managers and domain experts who wanted to contribute and write sticky notes. It is not a good idea because they should focus on sharing the knowledge and let the rest of the team grasp the business expectations. You won’t help someone if you do his/her job.

\n\n

How to start

\n\n

Writing the title of a story on a yellow sticky note is pretty simple but I sometimes had difficulties getting the business rules and the examples listed. Especially, when you are doing this workshop with a team for the first time. I found out that it was easier to sometimes start by writing the example first or sometimes by writing the business rules first.

\n\n

First option: start by writing the business rules and then write the examples if your team is comfortable with the exercise and your product manager has a clear vision of what is expected.

\n\n

Second option: start by writing examples and then extract business rules from examples if your team is not comfortable with the workshop or if your product manager needs to explore a topic and he/she waits for your feedback. It will let you and your teammates speak, and understand what is going on. When you have enough examples and your understanding of business is better you can extract the business rules.

\n\n

Don’t be afraid if it is a bit complicated to be efficient in the beginning. One day, my teammates and I prepared a story about exporting a CSV file, quite simple, right? We only needed to “take data from the DB and build a file” but it wasn’t that simple! We turned this “simple” story into at least 15 stories. We discovered a lot of “hidden” business rules. We thought it was a story but it was an epic…

\n\n

How to write example

\n\n

Don’t try to write gherkins scenarios at all costs because it can be time-consuming. The goal of this workshop is to ensure all teammates grasp what the business expects and it is the right time to raise all problems and incomprehension.

\n\n

The simplest format I used to define the example looked like the Given / When / Then but a really simplified version.

\n\n

\"Simplified

\n\n

Sometimes it can be more readable to draw something.

\n\n

\"Draw

\n\n

Don’t limit yourself, if you prefer another format, use it. The most important thing is that everyone understands what is expected.

\n\n

Don’t forget red sticky notes

\n\n

Avoid endless debates! Don’t hesitate to use red sticky notes if your teammates disagree on something. Keep in mind that your product manager can’t answer all questions during the workshops. It’s normal, the product manager is not a super(wo)man! Thus, add a red sticky note and take time to think about it, he/she’ll answer all questions in the next session.

\n\n

Have small stories

\n\n

I like to talk with the PM when the story is ready to be developed (when there are no more red stickies and when all teammates are OK with it). I usually challenge him/her to know which business rules are really mandatory and which ones are nice-to-have. It ensures your stories are really small and it eases the prioritization. You can focus on what is really important and keep what is nice-to-have for later.

\n\n

Tip: If your story has too many business rules, it’s a smell! That means you should split it into small ones. It will be easier to ship several small stories than a big one. If a business rule has too many examples, that’s a smell too. You might have missed some business rules.

\n\n

\"Split

\n\n

I am not a big fan of estimates, it’s a waste of time. We should focus on understanding the problem we want to solve, instead of giving figures that will probably be wrong. Having a really small story will help you to be more predictive. You can count the stories done during a time frame and easily forecast what your team will be able to do during the next iteration.

\n\n

Final thoughts

\n\n

The first example mapping workshop can be complex but don’t give up. The more you practice, the more comfortable your team will be with the workshop. Example mapping is a good way to align the team’s understanding with the stakeholders expectations. It will help your team to better collaborate and break all silos between all kinds of positions in your team. Last but not least, it will help you refine your stories and improve your backlog prioritization.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/my-feedback-about-example-mapping.html","relative_path":"_posts/2022-10-31-my-feedback-about-example-mapping.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"What is the event sourcing pattern?","description":"Event sourcing consists in storing all changes that happened to the application state as a sequence of events instead of only storing the current state of the application. The sum of all events makes the current application state.","date":"2022-11-28 00:00:00 -0600","image":"what-is-the-event-sourcing-pattern.webp","image_credit":"vitsinkevich","keywords":"software,software architecture,design patterns,es,event sourcing,table soccer","tags":["software-architecture"],"slug":"what-is-the-event-sourcing-pattern","ext":".md","excerpt":"

Event sourcing consists in storing all changes that happened to an application as a sequence of events instead of only storing the current state of the application. The sum of all events is the current application state. When I heard about this pattern a few years ago, I was really confused. I used to only persist the current application state in a database and that was fine! So I asked myself do I need that?

\n","content":"

Event sourcing consists in storing all changes that happened to an application as a sequence of events instead of only storing the current state of the application. The sum of all events is the current application state. When I heard about this pattern a few years ago, I was really confused. I used to only persist the current application state in a database and that was fine! So I asked myself do I need that?

\n\n

I will show you an example to help you understand what this pattern stands for. People used to explain it with a bank account but I wanted to find something funnier: a table soccer game. A complete example is available on a Github repository:

\n\n
\n \n \n \"Have\n \n \n Have a look at the GitHub repository\n \n \n
\n\n

Let’s start! A group of developers who are fans of table soccer wants to create an application to see who’s the best player. They decided to save the results of matches and rank themselves.

\n\n
export class Game {\n    constructor(\n        private redTeam: Team,\n        private blueTeam: Team,\n        private gameScore: Score,\n    ) {}\n\n    public recordScore(redPlayerScore: number, bluePlayerScore: number) {\n        return new Game(\n            this.redTeam,\n            this.blueTeam,\n            new Score(redPlayerScore, bluePlayerScore),\n        );\n    }\n\n    // example: ['arn0', 'momos', 'Popeye', 'coco', 10, 1]\n    public toState(): [string, string, string, string, number, number] {\n        return [\n            ...this.redTeam.toState(),\n            ...this.blueTeam.toState(),\n            ...this.gameScore.toState()\n        ];\n    }\n}\n
\n\n

The Game Aggregate has a recordScore method to record the score at the end of the game. Then we get the current state of Game with the toState method to save it in the database.

\n\n

That works perfectly for the one versus one games but what happens for two versus two games? Let’s focus on one of the players, we will call him Popeye. Actually, Popeye is not a really good player even if he is full of goodwill. He is smart, he always wants to play with the best player to have more chances to win. We cannot know who is the best player with only the result of the game. Who has really scored? Popeye or its teammate?

\n\n

Event sourcing is the solution. Instead of saving the score of the game, we will store what really happens. We will refactor the Game aggregate to make it compliant with the event sourcing pattern.

\n\n

First, we will rework the aggregate construction. We still want to encapsulate its current state but we want to record all events that happened too. In the following example, we added an events argument to the primary constructor and a named constructor (secondary construct) called start to the Game class. From a business point of view, its goal is to initialize the game and from a technical point of view, it lets us record the GameStarted event.

\n\n
export class Game {\n    constructor(\n        private redTeam: Team,\n        private blueTeam: Team,\n        private gameScore: Score,\n        private events: Event[] = []\n    ) {}\n    \n    public static start(\n        redAttacker: Player,\n        redDefender: Player,\n        blueAttacker: Player,\n        blueDefender: Player\n    ): Game {\n        const redTeam = Team.ofTwoPlayer(redAttacker, redDefender);\n        const blueTeam = Team.ofTwoPlayer(blueAttacker, blueDefender);\n\n        return new Game(\n            redTeam,\n            blueTeam,\n            Score.playersHaveNotScored(),\n            [new GameStarted(redTeam, blueTeam)],\n        );\n    }\n}\n
\n\n

Then we will add a new method to Game to record all goals scored by any players. That will let us know who is the best striker in the game. In the following example, we record two events: GoalScored and GameEnded. The first one is recorded every time a player scores and the second one is recorded when the first team has 10 points meaning the game is over.

\n\n
export class Game { \n   // …\n   public goalScoredBy(player: Player): Game {\n        const teamColor = this.redTeam.isTeammate(player) ? TeamColor.Red : TeamColor.Blue;\n        const gameScore = this.gameScore.increase(teamColor);\n\n        this.events.push(new GoalScored(teamColor, player, gameScore))\n\n        if (!gameScore.canIncrease(teamColor)) {\n            this.events.push(new GameEnded(this.redTeam, this.blueTeam, gameScore))\n        }\n\n        return new Game(\n            this.redTeam,\n            this.blueTeam,\n            gameScore,\n            this.events,\n        );\n    }\n    // …\n}\n
\n\n

Note: We can drop the recordScore method because we won’t want to only record the score of the game at the end of the game.

\n\n

Finally, the last thing to refactor is the persistence mechanism. We need to rework the toState because we won’t store a snapshot of the Game state but we want to save all events raised during the game. This method will return all serialized events and metadata like the name of the aggregate. Normally, we should persist some extra metadata like the aggregate id or the date when the event has been raised. Then, those data will be used in the Game repository to persist changes in the database.

\n\n
export class Game { \n    // …\n    public toState(): [[string, string]] {\n        return this.events.map((event: Event) => ['Game', event.toState()]);\n    }\n    // …\n}\n
\n\n

Last thing, we will add a named constructor to be able to build the object from the persisted state (a list of events). The fromEvents will iterate on all events to compute and set the current state of a game.

\n\n
export class Game { \n    // …\n    public static fromEvents(events: Event[]): Game {\n        let redTeam, blueTeam, score;\n        events.forEach((event: Event) => {\n            switch (true) {\n                case event instanceof GameStarted:\n                    redTeam = event.redTeam;\n                    blueTeam = event.blueTeam;\n                    break;\n                case event instanceof GameEnded:\n                    score = event.score;\n                    break;\n            }\n\n        });\n\n        return new Game(redTeam, blueTeam, score, events);\n    }\n    // …\n}\n
\n\n

Now, we have all the data we need to know if Popeye really helps his teammate. In the following code example, we can see that Momos and arn0 were not in a good shape. Coco and Popeye won easily but we can see that Popeye did not score. Perhaps, he is a good defender, who knows?

\n\n
let game = Game.startTwoVersusTwo('arn0', 'momos', 'Popeye', 'coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('momos')\ngame = game.goalScoredBy('arn0')\ngame = game.goalScoredBy('arn0')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('momos')\ngame = game.goalScoredBy('momos')\ngame = game.goalScoredBy('arn0')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\n
\n\n

I explained to you how to save Game aggregate events and create the aggregate from events in the previous sections of the blog post. The last missing feature is the leaderboard! How to create it? It won’t be as simple as querying a SQL table in the database because we need to get all game events for each game and compute them to know who is the better striker. Even though it can be fast in the beginning, the more games you have, the longer it will be.

\n\n

To prevent this problem, we need to create data projections. That means we will compute a representation of the data we want to query from the event stream. We will compute the new projection of the leaderboard each time a game ends.

\n\n

Last but not least, We often associate CQRS with the event sourcing pattern even if there are two different patterns.

\n\n

Don’t forget that a complete example is available on a Github repository.

\n\n
\n \n \n \"Have\n \n \n Have a look at the GitHub repository\n \n \n
\n\n

Any resemblance to real and actual names is purely coincidental!

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/what-is-the-event-sourcing-pattern.html","relative_path":"_posts/2022-11-28-what-is-the-event-sourcing-pattern.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Hexagonal architecture by example","description":"The hexagonal architecture, or ports and adapters architecture, is an architectural pattern used in software design. It aims at creating loosely coupled application components that can be easily connected to their software environment by means of ports and adapters.","date":"2023-01-09 00:00:00 -0600","image":"hexagonal-architecture/hexagonal-architect-by-example.webp","image_credit":"kmitchhodge","keywords":"architectural pattern,design pattern,hexagonal architecture,port adapter architecture,domain,infrastructure,user interface,software","tags":["software-architecture"],"slug":"hexagonal-architect-by-example","ext":".md","excerpt":"

In this blog post, I would like to explain the basics of hexagonal architecture thanks to a simple example: a product catalogue. The catalogue manager can add new products through a user interface and the nightly cron task imports new products from the ERP.

\n","content":"

In this blog post, I would like to explain the basics of hexagonal architecture thanks to a simple example: a product catalogue. The catalogue manager can add new products through a user interface and the nightly cron task imports new products from the ERP.

\n\n

Before going deeper into hexagonal architecture, let’s see what we need to create the product management application. We need two entry points: the first one will be consumed by the graphical client and the other one will be used by the cron task. Then, we will need another piece of code which will be in charge of persisting product data into storage.

\n\n

\"Application

\n\n

What is hexagonal architecture?

\n\n
\n

The hexagonal architecture, or ports and adapters architecture, is an architectural pattern used in software design. It aims at creating loosely coupled application components that can be easily connected to their software environment by means of ports and adapters. This makes components exchangeable at any level and facilitates test automation.

\n\n

Wikipedia

\n
\n\n

There are three main areas in the hexagonal architecture:\nThe primary adapters (user interface) are the whole application entry points that can be consumed by clients like a UI or a CLI.\nThe secondary adapters (infrastructure) connect the application to tools like the database, file system, etc.\nThe domain is all pieces of code that represent the problem we are solving. This part must be side-effect free (it must not use any tools).

\n\n

Domain

\n\n

The domain is the area where we solve our business problems no matter the technical constraints. We can start by designing the product aggregate.

\n\n
type Name = string;\ntype Description = string;\n\nexport class Product {\n    constructor(\n        private name: Name,\n        private description: Description\n    ) {}\n\n    toState(): string[] {\n        return [this.name, this.description];\n    }\n}\n
\n\n

As I said, we need to save products into the database but we don’t mind if the database is PostgreSQL, MySQL or whatever in the domain. We will define an abstraction (an interface) to avoid accessing any technical asset from the domain. This interface which is called a port will specify how to store a new product from a business point of view. This is nothing more than applying the dependency inversion design pattern.

\n\n
export interface ProductCatalog {\n    add(product: Product): void\n}\n
\n\n

What about testing?

\n\n

Moving IO as far as possible from your domain code is really convenient because it eases unit testing. We will mainly test this part of the application with unit testing. It offers a very short feedback loop, it will help you to design your domain step by step without setting up the whole application.

\n\n

Tip: I’ve written a blog post about unit testing that explains why testing can be hard. It mainly gives you tips to move IO outside your code to make it testable.

\n\n
\n \n \n \"Why\n \n \n Why unit testing can be hard?\n \n \n
\n\n

Coupling rules

\n\n

The domain code must not use any IO: any tools like your database, randomness, or actual datetime, nor depend on the primary and the secondary adapters. We will explain what they are in the next sections.

\n\n

Secondary adapters (Infrastructure)

\n\n

The secondary or driven adapters implement the ports defined in the domain. In our example, the adapter will be a PostgresProductCatalog class that implements the ProductCatalog interface (port). Its purpose will be to store product data in a database.

\n\n
class PostgresProductCatalog implements ProductCatalog {\n    constructor(private pg: Client) {}\n\n    add(product: Product) {\n        this.pg.query(\n            'INSERT INTO product (name, properties) VALUES ($1, $2)',\n            product.toState()\n        );\n    }\n}\n
\n\n

An advantage of this architecture is that we can simply delay choices. At the beginning of a project, it may be hard to choose the right tools because you still need to learn and understand the business. In that case, you can implement an in-memory adapter, it will work the same way as the previous one but it will only keep product aggregate in memory.

\n\n
class InMemoryProductCatalog implements ProductCatalog {\n    private products: Product[];\n\n    add(product: Product) {\n        this.products = [product, ...this.products];\n    }\n}\n
\n\n

Tip: This adapter can be used in your test suites because it lets you bypass your tools constraints like foreign key constraints when we use a database, for instance.

\n\n

What about testing?

\n\n

The part of the application is mainly covered by “integration” or “contract” tests. Those tests ensure that the tools used by the application work as expected. For example, you are able to save and query your database.

\n\n

Tip: I encourage you to test all implementations of a given port with the same test because it will ensure they work the same way.

\n\n

Coupling rules

\n\n

The infrastructure code only depends on the domain code.

\n\n

Primary adapters (User interface)

\n\n

The primary adapters or driving adapters are entry points that describe how the application is consumed by the clients. Their purpose is to tell the domain what to do. Actually, it can be a Web controller or CLI command for instance.

\n\n

In our example, we need two adapters: a web controller and a CLI command. Both of them will execute the same action, they will save product data but they have different input and output. The first one takes JSON and returns an HTTP response and the second one takes input and returns code status.

\n\n
try {\n    this.productCatalog.add(new Product(\n        request.get('name'), // get name argument for cli command\n        request.get('description'), // get description argument for cli command\n    ))\n\n    return new HttpResponse(201); // return 0 for cli command\n} catch (Error) {\n    return new HttpResponse(500); // return 1 for cli command\n}\n
\n\n

As you see, the only differences are the input and output of the adapter. We need to refactor this code to avoid duplication between both primary adapters. It should be extracted into a dedicated business service.

\n\n

Tip: These business services can be written using the command and command handler patterns. I’ve written a blog post that explains these design patterns:

\n\n
\n \n \n \"Command\n \n \n Command and command handler design pattern\n \n \n
\n\n

I’ve written a bunch of articles about how to handle a command, validate its data, handle user permissions, and so on. Take a look at these articles:

\n\n
\n \n \n \"See\n \n \n See all blog posts about command handling.\n \n \n
\n\n

What about testing?

\n\n

There are several ways to test primary adapters.

\n\n

First option: the easiest one, your application only has one primary adapter. I advise you to write an acceptance test that boots the application and checks that the whole application works for each business use case.

\n\n

Second option: the complex one, your application has several primary adapters like our example (web and CLI). I advise you to check that your command handler works as expected thanks to an acceptance. That way you ensure your handler will work as expected for both adapters. Thus, you can write a test to ensure that the adapters return the right output (HTTP response or code status) depending on the case.

\n\n

Coupling rules

\n\n

The user interface code only depends on the domain code.

\n\n

Flow of control

\n\n

\"Hexgonal

\n\n

The application flow goes from the user interface (1) through the domain (2) to the infrastructure (3) then goes back through the domain (2) to the user interface (4).

\n\n

Example: The UI sends data to an HTTP controller (1), then a product aggregate is created (2), then the repository saves data into the database (3), and finally the web controller sends a 200 HTTP response (4). We don’t need step (2) because nothing happens in the domain after the product creation.

\n\n

Code organization

\n\n

The domain contains the aggregates, ports, business services and so on. Most importantly, they must not use IO and must be business oriented.

\n\n

The infrastructure contains all secondary adapters that use external tools (IO) like your database.

\n\n

The user interface contains all primary adapters that are the application entry points. Users and machines use them to interact with the application.

\n\n
src\n├── domain\n│   ├── ProductCatalog.ts\n│   └── Product.ts\n├── infra\n│   ├── InMemoryProductCatalog.ts\n│   └── PostgresProductCatalog.ts\n└── user-interface\n    ├── CliCreateProduct.ts\n    └── WebCreateProduct.ts\n
\n\n

Note: I decided to split each class/interface into a dedicated module because I wanted to show you where things are. Feel free to organize your module as you wish.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/hexagonal-architect-by-example.html","relative_path":"_posts/2023-01-09-hexagonal-architect-by-example.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"What is the difference between CQS and CQRS patterns?","description":"CQS and CQRS are misunderstood design patterns. They are more simple than people think! CQS is about dividing an object's methods into two categories: commands and queries while CQRS is about separating query and command into two objects.","date":"2023-02-06 00:00:00 -0600","image":"what-is-the-difference-between-cqs-and-cqrs-patterns.webp","image_credit":"mihaistrompl","keywords":"cqs,cqrs,design pattern,software","tags":["software-architecture","design-patterns"],"slug":"what-is-the-difference-between-cqs-and-cqrs-patterns","ext":".md","excerpt":"

I recently found out that I did not grasp those design patterns. There are a lot of resources on the Internet about them but they are not always accurate. That’s a shame because they are pretty simple. I will share my understanding of them with you.

\n","content":"

I recently found out that I did not grasp those design patterns. There are a lot of resources on the Internet about them but they are not always accurate. That’s a shame because they are pretty simple. I will share my understanding of them with you.

\n\n

What is Command Query Segregation (CQS)?

\n\n
\n

The fundamental idea is that we should divide an object’s methods into two sharply separated categories:

\n \n\n

Martin Fowler

\n
\n\n

This concept is not specific to Object Oriented Programming but improves the object’s design. The object methods only have a single purpose: reading or changing the object state. We can see an object as a living entity. We can ask a question to someone because we need information. For example, we can ask someone what time it is. This is a query. We can ask someone to do something, we don’t expect an answer but we want to get the job done. For example, we can ask a child to finish his/her spinach. This is a command.

\n\n

We can apply this pattern to any object: like an aggregate. Let’s take an example! I would like to add markers on a map and then I would like to find which markers are the closest to a specific location (GPS Coordinates).\nk

\n
class Map {\n    addMarker(label: string, latitude: number, longitude: number): void {\n        // ...\n    }\n\n    findClosestMarkers(location: Location): Marker[] {\n        // ...\n    }\n}\n
\n\n

The addMarker method is in charge of mutating the object state without returning any result, while the ‘findClosestMarkers’ method finds the right markers without changing the object’s state. This object follows the CQS definition.

\n\n

Let’s go further. If we design our aggregates following the CQS pattern, we should apply it to the classes that handle use cases.

\n\n
interface MapService {\n    addMarkerToTheMap(label: string, latitude: number, longitude: number); void\n    findAllMarkersCloseToLocation(): Marker[]\n}\n
\n\n

This ensures there is no inconsistency in the codebase. The business services use and manipulate the aggregates. For example, if the MapService.addMarkerToTheMap method returns a result, it might mean that the Map.addMarker method will need to return the expected result.

\n\n

What is Command Query Responsibility Segregation (CQRS)?

\n\n
\n

Starting with CQRS, CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).

\n\n

Greg young

\n
\n\n

Note: Greg Young’s blog does not exist anymore but his blog posts are still available thanks to archived.org.

\n\n

CQRS is the separation of command and query into two different objects instead of only one. MapService does not follow the CQRS pattern because it has a query and a command. We need to cut this object in half.

\n\n
interface MapReadService {\n    addMarkerToTheMap(label: string, latitude: number, longitude: number); void\n}\n\ninterface MapWriteService {\n    findAllMarkersCloseToLocation(): Marker[]\n}\n
\n\n

That’s pretty simple, right? Anyway, we don’t need to introduce complicated things in our application to use this tactical design pattern. We don’t need a write and a read model,\na command and query bus, an event sourcing architecture or multiple databases. Greg Young published this blog post in 2012 to explain what CQRS was not about.

\n\n
\n

CQRS is not a silver bullet\nCQRS is not a top level architecture\nCQRS is not new\nCQRS is not shiny\nCQRS will not make your jump shot any better\nCQRS is not intrinsically linked to DDD\nCQRS is not Event Sourcing\nCQRS does not require a message bus\nCQRS is not a guiding principle / CQS is\nCQRS is not a good wife\nCQRS is learnable in 5 minutes\nCQRS is a small tactical pattern\nCQRS can open many doors.

\n
\n\n

Note: This blog does not exist anymore but it has been archived by archived.org. The post is available here

\n\n

Depending on the number of use cases the service classes can become really huge. CQRS helps to decrease their size but I am a big fan of them. I like to separate each use case into a dedicated class.

\n\n

I’ve written a blog post to explain what is a commands and we can apply it to query too:

\n\n
\n \n \n \"Command\n \n \n Command and command handler design pattern\n \n \n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/what-is-the-difference-between-cqs-and-cqrs-patterns.html","relative_path":"_posts/2023-02-06-what-is-the-difference-between-cqs-and-cqrs-patterns.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"How to reduce coupling in your React app","description":"The dependency inversion principle is a great design pattern, it makes applications more modular and easier to test. A React Context can help to implement this pattern in a React application. Learn how in this new blog article.","date":"2023-03-06 00:00:00 -0600","image":"how-to-reduce-coupling-in-your-react-app.webp","alt":"How to reduce coupling in your React app","image_credit":"diana_pole","keywords":"react,dependency injection,dependency inversion,typescript,coupling,software,design pattern","tags":["react","design-patterns"],"slug":"how-to-reduce-coupling-in-your-react-app","ext":".md","excerpt":"

Today, I would like to cover dependency injection in React. I worked with several frameworks using tools to build and inject dependencies. It is pretty convenient if you apply the dependency inversion principle because you can easily change a dependency with another one.

\n","content":"

Today, I would like to cover dependency injection in React. I worked with several frameworks using tools to build and inject dependencies. It is pretty convenient if you apply the dependency inversion principle because you can easily change a dependency with another one.

\n\n

I will start by briefly introducing what is a React Context and I will then show you how to solve coupling problems in a React application.

\n\n

What is a React Context?

\n\n
\n

Context provides a way to pass data through the component tree without having to pass props down manually at every level.

\n\n

React documentation

\n
\n\n

Let’s take an example: several components display the username of the user who is connected. We have to pass the username as props to every application component that needs this information. It is annoying, but React context can help for this specific use case.

\n\n

First, we need to create a context:

\n\n

```ts self-taught\nconst UserContext = React.createContext();

\n
\nThen, we need to wrap our components using a context provider and give it a value. The value is the data we want to share with the provider’s children components.\n\n```tsx\nfunction App() {\n    return (\n        <UserContext.Provider value={'arn0'}>\n            <Toolbar />\n            <OtherComponent />\n        </UserContext.Provider>\n    );\n}\n
\n\n

Finally, we can get this value (the username) from the context thanks to the useContext hooks.

\n\n
function Toolbar() {\n    const username = useContext(UserContext);\n\n    return (\n        <div>\n            Welcome {username}\n        </div>\n    );\n}\n\n
\n

Which problems coupling brings?

\n\n
\n

Coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.

\n\n

Wikipedia

\n
\n\n

The developer’s worst enemy is coupling because it makes your code less testable. To illustrate what I am saying we will take an example: a to-do list application. The TodoList component is responsible for retrieving data from the server and building the list of tasks to do.

\n\n
const findTasks = async () => {\n    return await axios.get('/tasks');\n}\n\nfunction TodoList() {\n    const [tasks, setTasks] = useState<Task[]>([]);\n\n    useEffect(() => {\n        (async () => {\n            const response = await findTasks();\n            setTasks(response.data);\n        })();\n    }, []);\n    \n    return (\n        <ul>\n            {tasks.map((task: Task) => <li key={task.id}>{task.label}</li>)}\n        </ul>\n    );\n}\n
\n\n

The problem with the TodoList component is that it depends on the axios library to get data from the server. It does not ease testing because we need to set up the server to make this component work. Unit testing requires a short feedback loop! We need to find a way to get rid of this HTTP call. It would be great to be able to do HTTP calls in production but using stub for testing.

\n\n

How React Context reduces coupling?

\n\n

The problem with the TodoList component is that we should be able to use several implementations of the findTasks, but we can’t with its design. We need an implementation for the production that will make an HTTP call and another one for testing that will return stub.

\n\n

The findTasks function should not be hardcoded but it should be injected as a component dependency. A React Context will help us to solve that issue.

\n\n
type ServiceContainer = {findTasks: () => Promise<Task>};\n\nconst ContainerContext = React.createContext<ServiceContainer>({} as ServiceContainer);\n\nexport const useServiceContainer = () => useContext(ContainerContext);\n\nconst findTasks = async () => {\n    return await axios.get('/tasks');\n}\n\nfunction App() {\n    return (\n        <ContainerContext.Provider value={findTasks}>\n            <TodoList/>\n        </ContainerContext.Provider>\n    );\n}\n
\n\n

The ServiceContainer type represents all services we want to register in our application. The ContainerContext will share those services with ContainerContext.Provider children.

\n\n

Then, we only need to get the findTasks function from the React Context.

\n\n
function TodoList() {\n    const {findTasks} = useServiceContainer();\n    const [tasks, setTasks] = useState<Task[]>([]);\n\n    useEffect(() => {\n        (async () => {\n           const response = await findTasks();\n           setTasks(response.data);\n        })();\n    }, []);\n\n    return (\n        <ul>\n            {tasks.map((task: Task) => <li key={task.id}>{task.label}</li>)}\n        </ul>\n    );\n}\n
\n\n

Now, the code is testable because we can easily replace the findTasks by stub in the test suite. We can easily set up a test because this new function does not use HTTP calls.

\n\n
it('render the todo list', () => {\n    render(\n        <ContainerContext.Provider value={\n            { findTasks: () => ({id: 1, label: 'label'}) }\n        }>\n            <TodoList/>\n        </ContainerContext.Provider>\n    )\n\n    // …\n});\n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/how-to-reduce-coupling-in-your-react-app.html","relative_path":"_posts/2023-03-06-how-to-reduce-coupling-in-your-react-app.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"How to use custom React hook to increase application testability","description":"Sometimes, we depend on libraries that provide components which cannot be well rendered in the test environment. That means we cannot test some parts of an application. Learn how to use a React hook to prevent that problem and increase the application testability in this new blog article.","date":"2023-04-04 00:00:00 -0500","image":"how-to-use-custom-react-hook-to-increase-application-testability.webp","alt":"How to use custom React hook to increase application testability","image_credit":"joetography","keywords":"react,reactjs,hook,javascript,typescript,coupling,software,testing","tags":["react","testing"],"slug":"how-to-use-custom-react-hook-to-increase-application-testability","ext":".md","excerpt":"

In my previous blog, I spoke about reducing coupling in a React app to improve testing. Now I will show you how a custom React hook can increase testability.

\n","content":"

In my previous blog, I spoke about reducing coupling in a React app to improve testing. Now I will show you how a custom React hook can increase testability.

\n\n

Note: I assume that you are comfortable with React hooks. If you aren’t, please have a look at the React documentation

\n\n

First of all, I will show you some code that is not testable. In my side project, I use react-map-gl to create maps with Mapbox. Unfortunately, I can’t render the map with the testing library because this library only works in a web browser. I might have done something wrong but I haven’t found any solution to solve this problem.

\n\n
export function MapPage() {\n   const {mapId} = useParams<{ mapId: string }>();\n   const [markers, setMarkers] = useState([]);\n   const [isMarkerOpened, setIsMarkerOpened] = useState(false);\n\n\n   useEffect(() => {\n       setMarkers(getMarkers(mapId));\n   }, [mapId]);\n\n\n   const openMarkerPopup = () => setIsMarkerOpened(true);\n   const closeMarkerPopup = () => setIsMarkerOpened(false);\n\n\n   return (\n       <>\n           <ReactMapGL>\n               {markers.map(\n                   (marker) => <Marker\n                       longitude={marker.longitude}\n                       latitude={marker.latitude}\n                   >\n                       <MarkerIcon onClick={openMarkerPopup} />\n                   </Marker>\n               )}\n           </ReactMapGL>\n           <MarkerPopup isOpened={isMarkerOpened} onClose={closeMarkerPopup} />\n       </>\n   )\n}\n
\n\n

MapPage is in charge of loading map data depending on the mapId and rendering a map with its markers. I can’t test the MapBoard component because the ReactMapGL component can’t be rendered through the test tooling. That’s sad because I still want to check if I can open the marker popup when a user clicks on a marker.

\n\n

React will help us to fix this issue! We need to refactor this component to extract the business logic into a hook. This way, the component will only be responsible for rendering things. Let’s begin by creating the hooks.

\n\n
export function useMapPage(mapId, {defaultIsMarkerOpened} = {defaultIsMarkerOpened: false}) {\n   const [markers, setMarkers] = useState([]);\n   const [isMarkerOpened, setIsMarkerOpened] = useState(defaultIsMarkerOpened);\n\n\n   useEffect(() => {\n       setMarkers(getMarkers(mapId));\n   }, [mapId]);\n\n\n   const openMarkerPopup = () => setIsMarkerOpened(true);\n   const closeMarkerPopup = () => setIsMarkerOpened(false);\n\n\n   return {\n       markers,\n       isMarkerOpened,\n       closeMarkerPopup,\n       openMarkerPopup,\n   }\n}\n
\n

The hook exposes two variables: markers which is an array of map’s markers and isMarkerOpened which is a boolean that indicates if the popup is opened or closed. It exposes two functions, openMarkerPopup and closeMarkerPopup that let us mutate the isMarkerOpened boolean.

\n\n

Note: We could only expose setIsMarkerOpened but I think openMarkerPopup and closeMarkerPopup function names are clearer and match the component logic.

\n\n

Now, we need to call the hook from the MapPage component and it will still work as before.

\n\n
export function MapPage() {\n   const {\n       markers,\n       isMarkerOpened,\n       closeMarkerPopup,\n       openMarkerPopup\n   } = useMapPage(mapId);\n\n\n   return (\n       <>\n           <ReactMapGL>\n               {markers.map(\n                   (marker) => <Marker\n                       longitude={marker.longitude}\n                       latitude={marker.latitude}\n                   >\n                       <MarkerIcon onClick={openMarkerPopup} />\n                   </Marker>\n               )}\n           </ReactMapGL>\n           <MarkerPopup isOpened={isMarkerOpened} onClose={closeMarkerPopup} />\n       </>\n   )\n}\n
\n\n

The MapPage is still untestable but we can start testing the hook to ensure hook logic matches business expectations. We can test if we can open a marker’s popup. That’s great because the testing library provides the renderHook helper that eases the hook testing.

\n\n

Note: If you want to know how renderHook works you should have a look at this blog post written by Kent C. Dodds.

\n\n
describe('Map Page', () => {\n   test('should open the marker popup', async () => {\n       const { result } = renderHook(() => useMapPage(\n           'mapId', {defaultIsMarkerOpened: false}\n       ));\n       \n       act(() => result.current.openMarkerPopup());\n       \n       expect(result.current.isMarkerOpened).toEqual(true);\n   });\n\n\n   test('should close the marker popup', async () => {\n       const { result } = renderHook(() => useMapPage(\n           'mapId', {defaultIsMarkerOpened: true}\n       ));\n       \n       act(() => result.current.closeMarkerPopup());\n\n       expect(result.current.isMarkerOpened).toEqual(false);\n   });\n});\n
\n\n

As I said at the beginning of this blog post I wrote a blog post to explain how to reduce coupling in a React application. Please, have a look at this blog post to understand how to make a dependency injection system.

\n\n

Now, we need to remove the getMarkers function call from the hooks if we want to test the map data loading. We don’t want to trigger side effects like HTTP calls in the unit test suite because we want to have the shortest feedback loop. We will get the getMarkers function to useServiceContainer which is a hook that provides any services.

\n\n
export function useMapPage(mapId, {defaultIsMarkerOpened} = {defaultIsMarkerOpened: false}) {\n   const {getMarkers} = useServiceContainer();\n   // ...\n  \n   useEffect(() => {\n       setMarkers(getMarkers(mapId));\n   }, [mapId]);\n   // ...\n}\n
\n\n

By default, the useServiceContainer hooks return the production services, we will need to replace the getMarkers service with a fake service for testing purposes. The useServiceContainer hooks can’t work without a React Provider. I like to create a factory that wraps components I test with all needed providers. It avoids a lot of noise in the test suites and makes tests more readable.

\n\n
export const createWrapper = (serviceContainer) => function Wrapper(\n   { children }: { children: ReactElement },\n) {\n   return (\n       <ContainerContext.Provider value={serviceContainer}>\n           {children}\n       </ContainerContext.Provider>\n   );\n};\n
\n\n

Note: the factory has a parameter which is the service container. It will let us define the services we want to override for testing.

\n\n

The renderHook has a wrapper option that lets you define the component that will wrap the hook you are testing. We will use the createWrapper factory to wrap the hook into the ContainerContext provider and we create a fake getMarkers service.

\n\n
describe('Map Page', () => {\n   test('should load the markers of the map', async () => {\n       const markers = [{id: 'makerId'}];\n       const { result } = renderHook(\n           () => useMapPage('mapId'),\n           {wrapper: createWrapper({getMarkers: () => markers})}\n       );\n       \n       expect(result.current.markers).toEqual(markers);\n   });\n});\n
\n\n

Now, the getMarkers is predictable. That means we can test the map loading because the getMarker function will return [{id: 'makerId'}] every time.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/how-to-use-custom-react-hook-to-increase-application-testability.html","relative_path":"_posts/2023-04-04-how-to-use-custom-react-hook-to-increase-application-testability.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Use composition instead of props drilling","description":"Adding too many props will make your components complex, hard to understand and maintain. Instead opt for several small components and apply composition. Learn how in this blog article.","date":"2023-05-22 00:00:00 -0500","image":"use-composition-instead-of-props-drilling.webp","alt":"Use composition instead of props drilling","image_credit":"xavi_cabrera","keywords":"react,reactjs,composition,javascript,typescript","tags":["react","testing"],"slug":"use-composition-instead-of-props-drilling","ext":".md","excerpt":"

In this blog post, I would like to speak about how composition can improve your React codebase. It’s easy to add a lot of props to your component to make them configurable but it’s not a good idea.

\n","content":"

In this blog post, I would like to speak about how composition can improve your React codebase. It’s easy to add a lot of props to your component to make them configurable but it’s not a good idea.

\n\n

Let’s take an example. You are working on an e-Commerce webshop. A ProductList is used in the shop and the shop administration displays a list of products. In the shop administration, the component displays the product information and some calls to action (like product deletion and categorization for example) to manage products. In the shop you only need to display the product information, so, you don’t want to display the calls to action.

\n\n

As we can see in the next example, most of the ProductList props are used to render and configure the checkbox or the button.

\n\n
export function ProductList({\n products,\n displayCheckbox,\n displayAction,\n actionLabel,\n onCheckboxClick,\n onActionClick,\n}) {\n return (\n   <ul>\n     {products.map(product => (\n       <li>\n         {displayCheckbox &&\n           <input type=\"checkbox\" onclick={onCheckboxClick} /> : null}\n         {product.label}\n         {displayAction &&\n           <button onclick={onActionClick}>{actionLabel}</button> : null}\n       </li>\n     )}\n   </ul>\n );\n}\n\n\n
\n\n

This component is used in the AdminShopand Shop pages to display the product list to the customer or the shop owner.

\n\n
// Display to shop owner\nexport function AdminShop() {\n const [products, setProducts] = useState([]);\n\n\n useEffect(() => {\n   setProducts(getAllProducts())\n }, []);\n\n\n return (\n   <ProductList\n     products={products}\n     displayCheckbox={true}\n     displayAction={true}\n     actionLabel=\"delete\"\n     onCheckboxClick={/* callback */}\n     onActionClick={/* callback */}\n   />\n );\n}\n\n\n// Display to customers\nexport function Shop() {\n const [products, setProducts] = useState([]);\n\n\n useEffect(() => {\n   setProducts(getProductsAvailableforSale())\n }, []);\n\n\n return (\n   <ProductList\n     products={products}\n     displayCheckbox={false}\n     displayAction={false}\n   />\n\n\n );\n}\n
\n\n

The ProductList has to display elements depending on the given props. This big component will help mutualize the code but it will introduce complexity. Adding too many props will make your components complex, and hard to understand and maintain. Composition will help us to get rid of those props.

\n\n

Note: The ProductList component only has 3 props because I wanted to keep the example simple but guess what happens when your components have tens of props to configure them?

\n\n

How can composition help us? It’s like playing Lego. You need several bricks from different sizes and colors to create something. The big ProductList component can be split into several small components used to build the product list depending on business cases.

\n\n
export function ProductList({children}) {\n return (\n   <ul>{children}</ul>\n );\n}\n\n\nexport function Product({label, checkbox, action}) {\n return (\n   <li>\n     {checkbox}\n     {label}\n     {action}\n   </li>\n );\n}\n\n\nexport function ProductCheckbox({onClick}) {\n return <input type=\"checkbox\" onClick={onClick}/>;\n}\n\n\nexport function ProductAction({onClick, actionLabel}) {\n return <button onClick={onClick}>{actionLabel}</button>;\n}\n
\n\n

In the previous code example, we created 4 new components: ProductList, Product, ProductCheckbox and ProductAction. They are like Lego bricks and we can assemble them to create the product list with or without the call to action.

\n\n

Note: It’s not mandatory to create a dedicated component for the checkbox and the button. It can be useful to wrap generic components into more business-oriented ones. It helps to make things clearer. It’s another way to apply composition.

\n\n
// Display to shop owner\nexport function AdminShop() {\n const [products, setProducts] = useState([]);\n\n\n useEffect(() => {\n   setProducts(getAllProducts())\n }, []);\n\n\n return (\n   <ProductList>\n     {products.map(product => \n       <Product\n         label={product.label}\n         checkbox={<ProductCheckbox onClick={/* callback */} />}\n         action={<ProductAction onClick={/* callback */} actionLabel={\"delete\"} />}\n       />\n     )}\n   </ProductList>\n );\n}\n\n\n// Display to customers\nexport function Shop() {\n const [products, setProducts] = useState([]);\n\n\n useEffect(() => {\n   setProducts(getProductAvailableforSale())\n }, []);\n\n\n return (\n   <ProductList>\n     {products.map(product => <Product label={product.label} />)}\n   </ProductList>\n );\n}\n
\n\n

Small components are easier to test. They help build more stable applications and are easier to maintain. Your codebase will be less complex to understand. It will decrease your and your teammates’ mental load because you won’t have any components with complex API and logic.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/use-composition-instead-of-props-drilling.html","relative_path":"_posts/2023-05-22-use-composition-instead-of-props-drilling.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Ease testing thanks to the dependency inversion design pattern","description":"The inversion design pattern is quite simple and super powerful. It makes your code more modular. It lets you change a class's dependency to another one depending on the context. It is a good way to decouple your code from IO to make it testable.","date":"2023-06-19 00:00:00 -0500","image":"inversion-dependency/ease-testing-thanks-to-the-dependency-inversion-design-pattern.webp","alt":"Ease testing thanks to the dependency inversion design pattern","image_credit":"mmayyer","keywords":"unit test,design pattern,pattern,software,dependency inversion,dependency injection,test,typescript","tags":["testing","design-pattern","OOP"],"slug":"ease-testing-thanks-to-the-dependency-inversion-design-pattern","ext":".md","excerpt":"

In this new blog post, I would like to speak about the dependency inversion design pattern. This pattern makes your code more modular and helps to improve codebase testability. It’s quite simple and super powerful.

\n

What does this design pattern say?

\n

A class should not depend on another one to avoid coupling them together. If a class is coupled with another one, it means you won’t be able to use the first one without the second one.

\n","content":"

In this new blog post, I would like to speak about the dependency inversion design pattern. This pattern makes your code more modular and helps to improve codebase testability. It’s quite simple and super powerful.

\n

What does this design pattern say?

\n

A class should not depend on another one to avoid coupling them together. If a class is coupled with another one, it means you won’t be able to use the first one without the second one.

\n\n

\"Concrete

\n\n

The classes should only depend on abstractions (e.g. interfaces). An interface can be implemented in several ways. It will make your code more modular because you can use a specific implementation depending on the context.

\n\n

\"Concrete

\n\n

The interfaces should not depend on concrete implementations to avoid coupling them to another class.

\n\n

\"Abstraction

\n\n

How does this pattern improve testability?

\n\n

Let’s see with a simple example how dependency inversion helps to make your code easily testable. The following class lets a cartographer add a marker on a map.

\n\n

Note: I wrote an article about unit testing to help you to understand the main mistakes that make your codebase less testable. Here is the link https://arnolanglade.github.io/why-unit-testing-can-be-hard.html.

\n\n
class AddMarkerToMap {\n  execute(marker) {\n    const repository = PosgresqlMaps.getInstance()\n    \n    const map = repository.get(marker.mapId)\n    \n    map.addMarker(\n      marker.name,\n      marker.longitude,\n      marker.latitude,\n    )\n\n    repository.save(map)\n  }\n}\n
\n\n

This class uses a singleton PosgresqlMaps.getInstance() to retrieve an instance of the PosgresqlMaps repository. This repository is in charge of saving map data into a PostgreSQL database. The problem is that we cannot run this code without a working database. This class is coupled to the PosgresqlMaps repository.

\n\n

We don’t want to use IO (your tools like a database) when we unit-test a piece of code because we want to avoid setting up any tools to a short feedback loop. We only want to check if a section of the application behaves as expected. We don’t want to test if the map data is well stored.

\n\n

Using the dependency inversion pattern will help us to remove the coupling between AddMarkerToMap and PosgresqlMaps and make it easy to unit test.

\n\n

First, we need to remove the coupling between both classes. We will create an abstraction to define how to retrieve and save maps in the application.

\n\n
interface Maps {\n  get(mapId: MapId): Promise<Map>;\n  save(map: Map);\n}\n
\n\n

Note: When I cannot use a business term to name a repository I pluralize the name of my aggregate to name it. That’s why I name it Maps because I want to handle map aggregate persistence.

\n\n

Now, we can create as many implementations as we need. We will create a dedicated implementation for testing purposes. It will only keep it in memory which will avoid using a database.

\n\n
class InMemoryMaps implements Maps {\n  private maps: Record<MapId, Map>;\n  \n  async get(mapId: MapId): Promise<Map> {\n    return this.maps[mapId];\n  }\n\n  async save(map: Map): Promise<void> {\n    this.maps[map.id()] = map;\n  }\n}\n
\n\n

Note: I name all implementations with a prefix depending on what they are. If a repository uses a database, I will prefix the class with the name of the database. When I create an implementation for testing purposes, I use the InMemory prefix.

\n\n

As we want to create a working application, we will create an implementation which uses a database for the production environment.

\n\n
class PosgresqlMaps implements Maps {\n  // …\n  async get(mapId: MapId): Promise<Map> {\n    const map = await this.client.query(\n      `SELECT * FROM maps WHERE id = ${mapId}`,\n    );\n\n\n    return new Map(map);\n  }\n  \n  async save(map: Map): Promise<void> {\n    await this.client.query(\n      `INSERT INTO maps VALUES (${map.toState()})`\n    );\n  }\n}\n
\n\n

We need to refactor a bit the AddMarkerToMap class to be able to inject an implementation of the Maps interface.

\n\n
class AddMarkerToMap {\n  constructor(private maps: Maps) {}\n  \n  execute(marker) {\n    const map = this.maps.get(marker.mapId)\n\n\n    map.addMarker(\n      marker.name, marker.latitude, marker.longitude\n    )\n    \n    this.maps.save(map)\n  }\n}\n
\n\n

Finally, we can test this class because we can instantiate the AddMarkerToMap class with the InMemoryMaps class. This implementation helps us to test this class because it does not use any IO. Here, we don’t want to test if the data are well persisted but we want to test the business logic of marker addition on a map.

\n\n
it('adds a new marker to the map', () => {\n  const maps = InMemoryMaps()\n  \n  new AddMarkerToMap(maps).execute({\n    mapId: 'mapId', name: 'Le Sunset',\n    latitude: 23.252353245, longitude: 43.5432563457\n  })\n  \n  expect(maps.get('mapId')).toEqual(\n    new Map(\n      new Marker('Le Sunset', 23.252353245, 43.5432563457)\n    )\n  )\n})\n
\n\n

Note: We don’t use a unit test to ensure the application uses its tools well. We use integration tests for this. For instance, if we want to ensure that a repository works as expected.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html","relative_path":"_posts/2023-06-19-ease-testing-thanks-to-the-dependency-inversion-design-pattern.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Don’t test private methods","description":"One of the first mistakes I made when I started to test my code was to test private methods. Spoiler alert: it was a bad idea! If you need to test a private method, it probably means that your code is not well designed. Private methods are implementation details of objects and we should not care about them. When you test public methods you also test the private ones.","date":"2023-07-17 00:00:00 -0500","image":"do-not-test-private-method/do-not-test-private-methods.webp","alt":"Don’t test private methods","image_credit":"dtopkin1","keywords":"unit test,design pattern,pattern,software,private method,single responsibility principle,test","tags":["testing","OOP"],"slug":"do-not-test-private-methods","ext":".md","excerpt":"

It is pretty easy to make mistakes when you start testing your code. One of the first mistakes I made was to test private methods. Spoiler alert: it was a bad idea because I had to use reflection to make them public to access them. If you need to test a private method, it probably means that your code is not well designed

\n","content":"

It is pretty easy to make mistakes when you start testing your code. One of the first mistakes I made was to test private methods. Spoiler alert: it was a bad idea because I had to use reflection to make them public to access them. If you need to test a private method, it probably means that your code is not well designed

\n\n

We don’t test private methods. Private methods are implementation details of objects and we should not care about them. Don’t worry! They are tested in the end. When you test public methods you also test the private ones as described in the next schema.

\n\n

\"Test

\n\n

I needed to test the private methods because my object was a God object (huge object). It did a lot of things. It had a few public methods and a lot of private ones because too many things happened behind the scenes.

\n\n

\"Object

\n\n

The problem with this design is this object did not follow the Single Responsibility Principle, but what is this principle?

\n\n
\n

There should never be more than one reason for a class to change. In other words, every class should have only one responsibility

\n\n

wikipedia

\n
\n\n

My object was super huge because it did too many things. It had too many responsibilities. Because of that, I could not test it easily. How can we avoid that?

\n\n

\"complicated

\n\n

It’s better to work on small problems than a big one. The solution would have been to identify each responsibility to extract them into dedicated objects. We don’t need magic tricks to test small objects. It is simple to test them because they do a simple thing, and we only need to use their public API (public method) to test them. We don’t need reflection anymore.

\n\n

\"split

\n\n

Then, we need to apply the composition pattern to assemble those classes to make them work as the God object. Composition is like playing Lego: we have many small bricks, and we put them together to make a big piece. Software is the same. You should work with small classes/functions to easily test them and piece them together to make your feature.

\n\n

Let’s take an example. The following class is in charge of importing products into an application as a PIM or an ERP. This class does several things, it gets product data from a CSV file and it imports them into a database. We need to test the whole class to ensure the product import works as expected. That’s a bit annoying because I can’t test the CSV file reading or the production saving.

\n\n
type Product = {\n  name: string\n  description: string\n};\n\nclass ProductImport {\n  constructor(private connection: Connection) {}\n    \n  async import(filePath: string): Promise<void> {\n    await this.loadProductFromCsvFile(filePath);\n  }\n  \n  private async loadProductFromCsvFile(file: string): Promise<void> {\n    const csvData: Product[] = [];\n    createReadStream(file)\n      .pipe(csvParser())\n      .on('data', (product: Product) => csvData.push(product))\n      .on('end', async () => {\n        for (const data of csvData) {\n          await this.saveProducts(data);\n        }\n      });\n  }\n\n  private async saveProducts(product: Product): Promise<void> {\n    await this.connection.execute(\n      'INSERT INTO products (name, description) VALUES (?, ?)',\n      [product.name, product.description],\n    );\n  }\n}\n
\n\n

We need to split this class into smaller ones to ease testing. We will extract both private methods into dedicated classes.

\n\n
class CsvProductLoader {\n  async loadProduct(file: string): Promise<Product[]> {\n    const products: Product[] = [];\n    createReadStream(file)\n      .pipe(csvParser())\n      .on('data', (product: Product) => products.push(product));\n    \n    return products;\n  }\n}\n\nclass MysqlProducts {\n  constructor(private connection: Connection) {}\n    \n  async save(product: Product): Promise<void> {\n    await this.connection.execute(\n      'INSERT INTO products (name, description) VALUES (?, ?)',\n      [product.name, product.description],\n    );\n  }\n}\n
\n

Now, we can test them stand-alone because these classes expose public methods. We don’t need a magic trick such as reflection to change their visibility to test them.

\n\n

We still need the ProductImport class. It will depend on both previous classes and act as a controller. It asks CsvProductLoader to get the product information from the CSV file and asks CsvProductLoader to save them into a database.

\n\n
class ProductImport {\n  constructor(\n    private productLoader: CsvProductLoader,\n    private products: MysqlProducts,\n  ) {}\n    \n  async import(filePath: string): Promise<void> {\n    const products = await this.productLoader.loadProduct(filePath);\n    products.forEach((product: Product) => this.products.save(product));\n  }\n}\n
\n\n

That’s great because we extract IO usage into new classes. Both MysqlProducts and CsvProductLoader need to be tested with integration/contract tests since ProductImport can be unit tested.

\n\n

We need to make a last change. We cannot rely on concrete classes. We need to introduce interfaces to avoid coupling between ProductImport and its dependencies (MysqlProducts and CsvProductLoader).

\n\n
interface ProductLoader {\n  loadProduct(file: string): Promise<Product[]>\n}\n\ninterface Products {\n  save(product: Product): Promise<void>\n}\n\nclass ProductImport {\n  constructor(\n    private productLoader: ProductLoader,\n    private products: Products,\n  ) {}\n}\n
\n\n

Note: I’ve written an article about how the inversion dependency design pattern will ease testing. Here is the link:

\n\n
\n \n \n \"Ease\n \n \n Ease testing thanks to the dependency inversion design pattern\n \n \n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/do-not-test-private-methods.html","relative_path":"_posts/2023-07-17-do-not-test-private-methods.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Why breaking encapsulation is not a good idea","description":"This principle restricts direct access to the state of the object from outside. This means that the internal implementation details of a class are hidden. Accessing the state of the object is only allowed through its public API (public methods). This concept helps to protect the data from outside interference and ensures controlled and secure data manipulation.","date":"2023-09-19 00:00:00 -0500","image":"why-breaking-encapsulation-is-not-a-good-idea/why-breaking-encapsulation-is-not-a-good-idea.webp","alt":"Why breaking encapsulation is not a good idea","image_credit":"mattseymour","keywords":"oop,encapsulation,object,tell don’t ask,object","tags":["testing","OOP"],"slug":"why-breaking-encapsulation-is-not-a-good-idea","ext":".md","excerpt":"

In this blog post, I would like to speak about an important concept in Oriented Object Programming which is the encapsulation principle.

\n","content":"

In this blog post, I would like to speak about an important concept in Oriented Object Programming which is the encapsulation principle.

\n\n

Before speaking about encapsulation let’s talk a bit about OOP. What is the object’s life cycle? The first step of the object’s life cycle is to be instantiated. We give everything an object needs to initialise its internal state. Then we use its public API (public methods) to communicate with it. An object exposes a public API (behaviour) that manipulates its internal state (data).

\n\n

\"Object

\n\n

So, what is encapsulation? This principle restricts direct access to the state of the object from outside. This means that the internal implementation details of a class are hidden. Accessing the state of the object is only allowed through its public API (public methods). This concept helps to protect the data from outside interference and ensures controlled and secured data manipulation.

\n\n

Note: An object that only has getters and setters is not an object! This is a data structure because it has no behaviour.

\n\n

I worked on many applications that used getters and setters. They are good examples of what is breaking encapsulation. It is easy to break encapsulation but it is not a good idea. It will make your code less maintainable and your applications less evolutive. Let’s take a simple example to understand why breaking encapsulation is a bad idea. I want to find the closest point of interest on a map close to a given location.

\n\n
type Location = {\n  latitude: number\n  longitude: number\n}\n\n\ntype PointOfInterest = {\n  name: string\n  location: Location\n}\n\nclass Map {\n  constructor(private pointOfInterests: PointOfInterest[]) {}\n\n\n  getPointOfInterests(): PointOfInterest[] {\n    return this.pointOfInterests\n  }\n}\n\nclass AClassWhereWeNeedToFindClosestPOI {\n  doSomething(map: Map) {\n    const pointOfInterest = map.getPointOfInterests()\n      .filter((pointOfInterest: PointOfInterest) => {\n        // ...\n      })[0]\n    // ...\n  }\n}\n
\n\n

The Map class has a getPointOfInterest getter that gets the class property with the same name. Then we can use this getter to access the list of points of interest to iterate them and find the closest one.

\n\n

The drawback with this getter is that we will need to copy/paste this piece of code if we have to look for the closest point of interest in several places. It won’t help you to mutualize code. At best, you can extract this piece of code into a dedicated class like the following example:

\n\n
class POIFinder {\n  find(map: Map): PointOfInterest {\n    return map.getPointOfInterests()\n      .filter((pointOfInterest: PointOfInterest) => {\n        // ...\n      })[0]\n  }\n}\n
\n\n

The problem with this code is that we extract the Map object behaviour into another class. We will turn the Map object into a data structure if we remove all methods that add a behaviour to it.

\n\n

Note: A class that ends with -ER (like in the previous example) is a good insight into how this class does the job of another class.

\n\n

What happens if we need to change the internal of the POI list? Now, we don’t want to use an array anymore, we want to manage the POI list with a custom class named PointOfInterestList. It might be a simple refactoring for small applications but it is super painful for huge ones. If the getter method is used hundreds of times, we will have to refactor each getPointOfInterest usage to make them compatible with the new signature.

\n\n

To avoid this problem, we only need to apply the “Tell, don’t ask” principle. This principle says that we should tell an object to do something instead of asking for its internal state to do something in his stead.

\n\n

The solution would be to add a findClosestPointOfInterest method to the Map object. The only purpose of this method is to find the closest POI no matter how the POI list is designed. This allows you to refactor the internal state of the object as many times you want.

\n\n
class ListOfPointOfInterest {\n  findClosest(location: Location) {\n    // ...\n  }\n}\n\nclass Map {\n  constructor(private pointOfInterests: ListOfPointOfInterest) {}\n\n\n  findClosestPointOfInterest(location: Location): PointOfInterest {\n    return this.pointOfInterests.findClosest(location)\n  }\n}\n
\n\n

Note: Breaking encapsulation to test your code is a bad idea too. I’ve written an article to present you with an alternative to the getter to prevent exposing the state of the objects. Here is the link:

\n\n
\n \n \n \"Why\n \n \n Why you should not expose objects' state to test them\n \n \n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/why-breaking-encapsulation-is-not-a-good-idea.html","relative_path":"_posts/2023-09-19-why-breaking-encapsulation-is-not-a-good-idea.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"The pitfalls of OOP's inheritance: Why simple isn't always better","description":"Discover the complexities of excessive inheritance in object-oriented programming (OOP) and understand why careful consideration is crucial to avoid potential problems and pitfalls.","date":"2023-10-23 00:00:00 -0500","image":"pitfalls-of-oop-inheritance/pitfalls-of-oop-inheritance.webp","alt":"The pitfalls of OOP's inheritance: Why simple isn't always better","image_credit":"gabrielsanchez","keywords":"OOP,OOP inheritance,OOP principles,composition,Open-Closed principle,OOP best practices,coding tips","tags":["OOP"],"slug":"oop-inheritance-pitfalls","ext":".md","excerpt":"

In OOP, the simplest way to change the behavior of a class A is to create a class B that extends class A. Extensions allow you to override any public and protected methods of the parent class. That‘s quite simple, right?

\n","content":"

In OOP, the simplest way to change the behavior of a class A is to create a class B that extends class A. Extensions allow you to override any public and protected methods of the parent class. That‘s quite simple, right?

\n\n

\"Simple

\n\n

Furthermore, you can extend a class multiple times with several levels of inheritance. In the following example, we can see that class B has two children, and the class hierarchy has four levels of inheritance. Now let’s explore why it is not a good idea and which problem can occur?

\n\n

\"Object

\n\n

Designing code like this won’t facilitate refactoring. Let’s consider a scenario where Class A has a method that is overridden in both Class B and Class E. What happens if we decide to change the signature of this method in Class A? We will need to rewrite this method in Class B and Class E to match the new signature. Another frustrating aspect is that we will have to modify all portions of the code that use this method. In a small codebase, this may be manageable, but in a large one, it’s a different story!

\n\n

\"Refactoring

\n\n

This code won’t ease team collaboration. Let’s consider another scenario: where we are working on a huge monolith shared with several other teams. What happens if team A needs to change class A? That means teams B, C, and D must also update their codebases. We have introduced coupling between these three teams because of the coupling between classes A, B, C, and D. That’s a shame. This design will slow down your delivery because team A will need to coordinate with three other teams if it needs to change class A.

\n\n

\"Refactoring

\n\n

I have worked on several codebases that heavily relied on inheritance, but now I barely use it due to the drawbacks I’ve described. Instead, I prefer to use composition. It is better to work with several small classes and assemble them, it’s like playing with Lego blocks. Moreover, it greatly simplifies testing.

\n\n

I try to apply the open-closed principle as much as possible to enhance code modularity and facilitate evolution. In a related blog post, I explain the principle and provide an example to illustrate how to refactor code that doesn’t follow this principle. Here is the link:

\n\n
\n \n \n \"Open-Closed\n \n \n Open-Closed principle: Enhancing code modularity\n \n \n
\n\n","url":"/oop-inheritance-pitfalls.html","relative_path":"_posts/2023-10-23-oop-inheritance-pitfalls.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Open-Closed principle: Enhancing code modularity","description":"Unlock the potential of the Open-Closed Principle in programming. Discover how to enhance code modularity and simplify maintenance using this SOLID concept. Learn to reduce complexity and write more flexible code.","date":"2023-11-13 00:00:00 -0600","image":"open-close-principle.webp","alt":"Open-Closed principle: Enhancing code modularity","image_credit":"madze","keywords":"open-closed principle,SOLID principles,software engineering,design patterns,strategy pattern,object-oriented programming,programming principles,development best practices","tags":["OOP","SOLID"],"slug":"open-close-principle","ext":".md","excerpt":"

Have you missed my last blog post about the pitfalls of inheritance? I explain how it could be a bad idea to use it too much. Applying composition prevents this problem; it is better to work with small classes to easily assemble. In this blog post, I will talk about the open-closed principle. This principle facilitates composition and helps avoid relying too much on inheritance.

\n","content":"

Have you missed my last blog post about the pitfalls of inheritance? I explain how it could be a bad idea to use it too much. Applying composition prevents this problem; it is better to work with small classes to easily assemble. In this blog post, I will talk about the open-closed principle. This principle facilitates composition and helps avoid relying too much on inheritance.

\n\n

This principle is one of the SOLID principles, and I think it is super important because it allows you to write more flexible code. I wanted to explain it because its definition is quite simple, but it is not necessarily easy to grasp.

\n\n
\n

The open closed principle states “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”; that is, such an entity can allow its behaviour to be extended without modifying its source code.

\n\n

Wikipedia

\n
\n\n

The first time I read the definition of this principle, I understood that I should not have to modify my code to add additional behavior. This part of the definition “open for extension” was a bit confusing. What did it mean? Does it refer to OOP inheritance? No, it doesn’t refer to OOP inheritance. I have written a blog post about OOP inheritance. It explains why extending a class to change its behavior may seem simple, but is it a good idea? It introduces a lot of coupling in your codebase and between your team.

\n\n

Before digging into the principle, let’s consider a scenario to illustrate the following example: a class called ‘DiscountCalculator’ is in charge of calculating discounts based on the products in the basket. We apply a 20% discount to products with the category ‘sport,’ a 50% discount to products with the category ‘home,’ and a 10% discount to products with the category ‘food.

\n\n
class Product {\n   constructor(\n       public name: string,\n       public category: string,\n       public price: number\n   ) {}\n}\n\nclass Basket {\n   constructor(public products: Product[]) {}\n}\n\nclass DiscountCalculator {\n   calculate(basket: Basket): number {\n       let totalDiscount = 0;\n\n\n       for (const product of basket.products) {\n           switch (product.category) {\n               case 'sport':\n                   totalDiscount += product.price * 0.2; // 20% discount\n                   break;\n               case 'home':\n                   totalDiscount += product.price * 0.5; // 50% discount\n                   break;\n               case 'food':\n                   totalDiscount += product.price * 0.1; // 10% discount\n                   break;\n           }\n       }\n       \n       return totalDiscount;\n   }\n}\n\n// Example usage:\nit.each([\n   ['Football', 'sport', 100, 20],\n   ['Couch', 'home', 200, 100],\n   ['Banana', 'food', 10, 1],\n])('calculates discounts for %s category', (productName, category, price, expectedDiscount) => {\n   const product = new Product(productName, category, price);\n   const basket = new Basket([product]);\n   \n   expect(new DiscountCalculator().calculate(basket)).toBe(expectedDiscount);\n});\n
\n\n

This code does not follow the open-close principle because we need to modify this DiscountCalculator class every time we want to add or remove a discount rule. The problem is thatDiscountCalculator may become really large if the business asks us to add a lot of discount rules. Large objects are hard to understand, so it won’t facilitate its maintenance and testability.

\n\n

Let’s refactor this code to enhance its modularity and align it with the Open-Closed principle. We will use the strategy pattern to rewrite the calculator to remove the hard-coded rules. First, we will introduce a new interface that specifies how a discount works. This interface has two methods: the first one is isApplicable, which determines if a discount can be applied to a product, while the second one calculate calculates the amount of the discount.

\n\n
interface Discount {\n   isApplicable(product: Product): boolean\n   calculate(product: Product): number;\n}\n\nclass SportCategoryDiscount implements Discount {\n   isApplicable(product: Product): boolean {\n       return product.category === 'sport';\n   }\n   \n   calculate(product: Product): number {\n       return product.price * 0.2;\n   }\n}\n\nclass HomeCategoryDiscount implements Discount {\n   isApplicable(product: Product): boolean {\n       return product.category === 'home';\n   }\n   \n   calculate(product: Product): number {\n       return product.price * 0.5;\n   }\n}\n\nclass FoodCategoryDiscount implements Discount {\n   isApplicable(product: Product): boolean {\n       return product.category === 'food';\n   }\n   \n   calculate(product: Product): number {\n       return product.price * 0.1;\n   }\n}\n
\n\n

Then, we need to update the calculator. It will determine whether a discount is applicable to a product and calculate the discount amount. With this approach, you can easily add or remove discount rules as needed.

\n\n
class DiscountCalculator {\n   constructor(private discounts: Discount[]) {}\n    \n   calculateDiscount(basket: Basket): number {\n       let totalDiscount = 0;\n       \n       basket.products.forEach((product) => {\n           this.discounts.forEach((discount) => {\n               if(discount.isApplicable(product)) {\n                   totalDiscount += discount.calculate(product);\n               }\n           });\n       });\n       \n       return totalDiscount;\n   }\n}\n\n// Example usage:\nit.each([\n   ['Football', 'sport', 100, 20],\n   ['Couch', 'home', 200, 100],\n   ['Banana', 'food', 10, 1],\n])('calculates discounts for %s category', (productName, category, price, expectedDiscount) => {\n   const product = new Product(productName, category, price);\n   const basket = new Basket([product]);\n   \n   expect(new DiscountCalculator([\n       new SportCategoryDiscount(),\n       new HomeCategoryDiscount(),\n       new FoodCategoryDiscount(),\n   ]).calculate(basket)).toBe(expectedDiscount);\n});\n
\n\n

We don’t need to over-engineer to apply the open-close principle. With the right design pattern, it is quite simple. Now, the discount calculator is more flexible. We didn’t introduce a lot of new code but we divided the class into smaller ones. Small classes are easier to test and understand, and it will facilitate the maintenance and the evolution of your application.

\n\n","url":"/open-close-principle.html","relative_path":"_posts/2023-11-13-open-close-principle.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"The Mikado Method: Small Steps, Big Improvements","description":"Enhance your codebase with the Mikado Method – a focused approach for incremental improvements without breaking your codebase. Tailored for brownfield development, ensure code stability and effortless feature integration. Collaborate effectively with MikadoApp and achieve rapid code enhancements through Trunk Based Development.","date":"2023-11-27 00:00:00 -0600","image":"mikado-method/mikado-method.webp","alt":"The Mikado Method: Small Steps, Big Improvements","image_credit":"tateisimikito","keywords":"mikado method, refactoring, small steps development, brownfield development, trunk based development, mikado graph, continuous code improvement","tags":["methodology"],"slug":"mikado-method","ext":".md","excerpt":"

In this blog post, I will introduce the Mikado Method. This method helps solve complex problems without breaking your codebase, even if you need to introduce significant changes.

\n","content":"

In this blog post, I will introduce the Mikado Method. This method helps solve complex problems without breaking your codebase, even if you need to introduce significant changes.

\n\n

It is common to work using PR (Pull Request), you can work on your task without breaking your application and disturbing the rest of the team. However, when you start working on a task without maintaining something that works, you end up adding too many changes that are not production-ready. The drawback of this approach is that your PRs will be large and hard to merge.

\n\n

It often happens when you refactor your codebase. You start refactoring something but it breaks another part of this application, then you fix it but it introduces a new problem elsewhere. As a result, you accumulate many changes without being able to merge them.

\n\n

Merging big PR is more complicated than simple changes. First, we need to ask for code reviews, but it can be challenging for your teammate to understand what you did when your PR includes too many things. Then, another drawback is the need to rebase your PR several times due to other PRs being pushed to the main branch.

\n\n

Now, you understand why it’s difficult to introduce big changes in your codebase. It is better to work on small steps that can be mergeable at any time. The Mikado method takes its name from the Mikado game, where the goal is to remove one stick without disturbing the others. The Mikado method has the same philosophy. It aims to make small incremental improvements to a project without breaking the existing codebase. This way, you can push your changes at any time and they won’t break your application even if you did not finish your task.

\n\n

This method simplifies refactoring. You can continuously improve your codebase instead of stacking changes in a huge PR which can’t be merged because the test suites are broken. It’s better to regularly merge small changes that improve your codebase quality. This method is ideal for brownfield development. It enables you to add new features or alter existing ones without breaking the rest of the application. Moreover, it facilitates the improvement of the application’s architecture while allowing the delivery of new features concurrently.

\n\n

How does it work? Let’s take an example: MySQL doesn’t match the project’s needs; we need to use PostgreSQL. First, we need to define a goal that is clear and understandable for everyone. In our case, it is “Migrate the application from MySQL to PostgreSQL,” as you can see in the following example.

\n\n

\"define

\n\n

Note: A goal can be what you want to improve in your application such as refactoring a section of the application to enhance its clarity or improving an existing feature.

\n\n

There are less chances that you can achieve your goal in a single attempt and quickly but we will try to solve it. Based on what we learn in this initial experimentation, we will split a big task (our goal) into smaller ones, which we call prerequisites. As mentioned earlier, this approach prevents ending up with a large pull request that is difficult to merge.

\n\n

To migrate the application to PostgreSQL, we first need to install the database. Then, we need to update our repositories because they use SQL queries specific to MySQL.

\n\n

\"add

\n\n

Now, you will start exploring all the prerequisites. Select a prerequisite from the list and start an experimentation to solve it. If you can easily achieve it, that’s excellent! Commit your changes, mark the prerequisite as completed, and proceed to the next one on the list.

\n\n

\"prerequisite

\n\n

If you cannot easily solve it, you need to revert your changes and define a sublist of prerequisites to achieve the original prerequisite. The purpose is to avoid making big changes but to focus on working on small steps while keeping the codebase stable. Reverting changes may not be natural to a developer, but it’s an important step in the process. It allows you to continue working in smaller steps, while the exploration helps you learn what is necessary to solve a prerequisite.

\n\n

\"add

\n\n

Continue to resolve all prerequisites until the end. When all prerequisites are done, your goal is completed!

\n\n

\"goal

\n\n

As you can see in the previous sections of the blog post, we can represent your progress as a graph. This is a useful way to communicate the progress of your task with the rest of the team. For example, you can show the mikado graph at the daily meeting to easily explain what you did. If, for any reason, you cannot complete your task, you can share the mikado graph with a colleague to explain what you’ve done and what remains to be done. Organizing your work becomes easier, especially when you are working on complex tasks. The Mikado graph is more visual than a simple to-do list because it allows you to see dependencies between prerequisites.

\n\n

I wrote a small application called MikadoApp to easily create and share your Mikado graphs. All the images in the blog posts are screenshots from the application. You can start using it thanks to this link, and you can find the source code on GitHub. Don’t hesitate to contribute to the application to improve it.

\n\n

Since I started using this method, my way of working has changed. I try to break down my work into small steps, and each commit can be pushed into production. If I refactor something, it’s great because I regularly push improvements. If I work on a feature, I can refactor what I need to create my feature without breaking the rest of the application.

\n\n

Now,I like working directly on the main branch, but I ensure that I only push stable commits. That’s what we call Trunk Based Development. This approach allows delivering small improvements to production quickly and frequently. Even though it can be practiced with PRs, I no longer prefer working with them due to the many associated processes that slow down the delivery.

\n","url":"/mikado-method.html","relative_path":"_posts/2023-11-27-mikado-method.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Testing a React application: Secure your tests from internationalization impact","description":"Learn how to prevent test suite breaks caused by translation changes through an innovative solution, ensuring resilience and flexibility in your testing approach.","date":"2023-12-11 00:00:00 -0600","image":"test-strategy-i18n-react-application/test-strategy-i18n-react-application.webp","alt":"Testing a React application: Secure your tests from internationalization impact","image_credit":"claybanks","keywords":"I18n,localization,React-Intl,internationalization,Lokalise,testing,React testing,Jest,React Context,React,Typescript,Javascript","tags":["react","testing"],"slug":"test-strategy-i18n-react-application","ext":".md","excerpt":"

In my previous company, we automated the translation process. We used Lokalise, a cloud-based localization and translation management system. The developers imported all translation keys into the system, while the OPS team was responsible for translating all the keys.

\n","content":"

In my previous company, we automated the translation process. We used Lokalise, a cloud-based localization and translation management system. The developers imported all translation keys into the system, while the OPS team was responsible for translating all the keys.

\n\n

\"translation

\n\n

This process is excellent because you don’t have to wait for translations. As a developer, you add the new translation key and provide the default language. The OPS team is notified when a new key is imported into the tool. They don’t need a developer to provide translations; they are highly autonomous. Afterward, the developers need to pull the translations into the codebase and deploy the application.

\n\n

Let’s consider an example: a React Application that uses the React-Intl as its internationalization system. This library provides a component called FormattedMessage that finds the translation for a given key and locale. This component must be used within a React Context called IntlProvider.

\n\n
const translations = { key: 'translation' };\n\n\n<IntlProvider locale=\"en\" messages={translations}>\n  <FormattedMessage id=\"key\" />\n</IntlProvider>;\n
\n\n

I like wrapping the IntlProvider in a custom provider that allows configuring React Intl for the entire application and provides additional features like locale switching. To keep this example simple, I hardcoded the locale.

\n\n
function AppIntlProvider({ children }: { children: ReactElement }) {\n  const translations = { key: 'translation' };\n \n  return (\n    <IntlProvider\n      messages={translations}\n      locale=\"en\"\n      defaultLocale=\"en\"\n    >\n      {children}\n    </IntlProvider>\n );\n}\n
\n\n

Now let’s go back to the testing problem. The following example is a test that checks if the onClick callback is called when the button with the label “OK” is clicked.`

\n\n
function MyComponent({ onClick }: { onClick: () => void }) {\n  return (\n    <div>\n      // ...\n      <Button onClick={onClick}>\n        <FormattedMessage id=\"validate\" />\n      </Button>\n    </div>\n  );\n}\n\n//const translations = { validate: 'OK' };\n\nit('validate something', () => {\n  const onClick = jest.fn();\n  render(\n    <MyComponent onClick={onClick} />,\n    {\n      wrapper: AppIntlProvider,\n    },\n  );\n \n  userEvent.click(screen.getByText('OK'));\n \n  expect(onClick).toHaveBeenCalled();\n});\n
\n\n

What happens if an OPS changes the translation of the ‘validate’ key from ‘OK’ to ‘GO’ for any reason? Your test will break even if the code and the test have not changed. That is a shame. Should translations break your test suites? I would like to answer this question with a no.\nThe solution that I use to prevent this problem is to override each translation that the test needs. I added an extra prop to the custom React Intl provider called overriddenTranslations that lets me override the translations my test needs.

\n\n
function AppIntlProvider(\n  { children, overriddenTranslations }:\n  { children: ReactElement, overriddenTranslations?: Partial<Translations> },\n) {\n  const translations: Translations = { key: 'translation' };\n \n  return (\n    <IntlProvider\n      messages={ { ...translations, ...overriddenTranslations } }\n      locale=\"en\"\n      defaultLocale=\"en\"\n    >\n      {children}\n    </IntlProvider>\n  );\n}\n
\n\n

Now, we only need to override the translation for the key ‘validate.’ Its value will remain ‘OK’ in the test context.

\n\n
// const translations = { validate: 'GO' };\n\nit('validate something', () => {\n  const onClick = jest.fn();\n  render(\n    <MyComponent onClick={onClick} />,\n    {\n      wrapper: (children) => (\n        <AppIntlProvider overriddenTranslations={ { validate: 'OK' } }>\n          {children}\n        </AppIntlProvider>\n      ),\n    },\n  );\n  \n  userEvent.click(screen.getByText('OK'));\n  \n  expect(onClick).toHaveBeenCalled();\n});\n
\n\n

Overriding a translation makes the test more resilient; even if you change the translation, the test will still pass (be green). In this specific context, it allows the OPS team to change any translation without breaking the test suite.

\n","url":"/test-strategy-i18n-react-application.html","relative_path":"_posts/2023-12-11-test-strategy-i18n-react-application.md","permalink":null}],"pages":[{"draft":false,"categories":[],"layout":"default","title":"About arnaud Langlade","content_blocks":[{"_bookshop_name":"page-heading","title":"About","description":null},{"_bookshop_name":"page-image","image":"/images/me-about.webp","image_alt":"Arnaud Langlade's picture"},{"_bookshop_name":"content","content":"I am a software architect, and technical coach with 15 years of experience. I am, what we call, a self-taught. I studied telecommunications and networks at school but my first job was in a small web agency as a developer. I learned on the job and improved my skills by myself for many years during my free time. I did not take the easiest path but I don’t have any regrets. I love my job!\n\nI worked with many service companies that allowed me to work on big projects for huge companies like [Prisma media](https://www.prismamedia.com), [Royal Canin](https://www.royalcanin.com) and [Groupe Sud Ouest](https://www.groupesudouest.com). Then, I worked for several startups like [Akeneo](https://www.akeneo.com), [Convelio](https://www.convelio.com) or [Sunday](https://sundayapp.com). Finally, I started my own enterprise in August 2022 after leaving Sunday.\n\n> It's not stakeholder knowledge but developers' ignorance that gets deployed into production.\n>\n> [Alberto Brandolini](https://www.linkedin.com/in/brando/)\n\nSoftware is valuable only if it is used and solves business's needs. That’s why I focus on understanding the business first. I organize and animate event storming and example mapping workshops. Both workshops aim to gather tech and non-tech in the same room and let them speak. Event storming helps to grasp the global picture and start thinking about the software design while example mapping helps to clarify user stories.\n\nI focus my technical watch on topics that let me build robust and maintainable software. I develop using TDD and the mikado method. Those methodologies help me to design features baby step by baby step while covering code with tests. I am not interested in the latest super cool technologies. I prefer learning architecture patterns such as hexagonal architecture, it lets me build software no matter the frameworks.\n\n> Do The Simplest Thing That Could Possibly Work\n>\n> [Kent Beck](https://www.linkedin.com/in/kentbeck/)\n\nI try to find the simplest solution that solves a business problem to ship it to production as quickly as possible. Any feedback is key in software development, it ensures we take the right decision. Agile, «This is the way».\n"},{"_bookshop_name":"blog-section","link_url":"/blog"},{"_bookshop_name":"newsletter"}],"slug":"about","ext":".html","tags":[],"excerpt":"","date":"2024-01-02 05:30:02 -0600","content":"","url":"/about/","relative_path":"_pages/about.html","permalink":null},{"draft":false,"categories":[],"layout":"default","title":"Arnaud Langlade's blog","description":"Welcome to my blog. I love sharing my knowledge about software engineering such as architectural design patterns, software testing, methodologies and so on.","keywords":"arnaud langlade,langlade,software engineer,architect,technical coach,software,oop,blog,tdd,bdd,ddd,event storming,example mapping,arnolanglade,hexagonal architecture,event sourcing,unit test","content_blocks":[{"_bookshop_name":"blog-header","title":"Welcome to my blog","description":"Hi, my name is Arnaud. I am a software architect, and technical coach. I love sharing my knowledge about software engineering such as architectural design patterns, software testing, methodologies and so on.","image":"/images/me-home.webp","image_alt":"Arnaud Langlade's picture"},{"_bookshop_name":"posts-list","show_posts":true},{"_bookshop_name":"newsletter"}],"slug":"blog","ext":".html","tags":[],"excerpt":"","date":"2024-01-02 05:30:02 -0600","content":"","url":"/blog/","relative_path":"_pages/blog.html","permalink":null},{"draft":false,"categories":[],"layout":"default","title":"Contact Arnaud Langlade","content_blocks":[{"_bookshop_name":"page-heading","title":"Contact me"},{"_bookshop_name":"mailchimp-contact-form"},{"_bookshop_name":"blog-section","link_url":"/blog"}],"slug":"contact","ext":".html","tags":[],"excerpt":"","date":"2024-01-02 05:30:02 -0600","content":"","url":"/contact/","relative_path":"_pages/contact.html","permalink":null},{"draft":false,"categories":[],"layout":"default","title":"Arnaud Langlade's experiences","content_blocks":[{"_bookshop_name":"page-heading","title":"Experiences"},{"_bookshop_name":"testimonials-list"},{"_bookshop_name":"experiences-list"},{"_bookshop_name":"blog-section","link_url":"/blog"},{"_bookshop_name":"newsletter"}],"slug":"experiences","ext":".html","tags":[],"excerpt":"","date":"2024-01-02 05:30:02 -0600","content":"","url":"/experiences/","relative_path":"_pages/experiences.html","permalink":null},{"draft":false,"categories":[],"layout":"xml-files","permalink":"/:title:output_ext","title":"Feed","slug":"feed","ext":".xml","tags":[],"excerpt":"\n\n \n Arnaud Langlade\n \n https://arnolanglade.github.io/\n \n Tue, 02 Jan 2024 05:30:02 -0600\n Tue, 02 Jan 2024 05:30:02 -0600\n Jekyll v4.2.1\n \n \n Testing a React application: Secure your tests from internationalization impact\n <p>In my previous company, we automated the translation process. We used Lokalise, a cloud-based localization and translation management system. The developers imported all translation keys into the system, while the OPS team was responsible for translating all the keys.</p>\n\n<p><img src="images/posts/test-strategy-i18n-react-application/translation-management-workflow.svg" alt="translation management workflow with lokalized" /></p>\n\n<p>This process is excellent because you don’t have to wait for translations. As a developer, you add the new translation key and provide the default language. The OPS team is notified when a new key is imported into the tool. They don’t need a developer to provide translations; they are highly autonomous. Afterward, the developers need to pull the translations into the codebase and deploy the application.</p>\n\n<p>Let’s consider an example: a React Application that uses the <a href="https://github.com/formatjs/formatjs">React-Intl</a> as its internationalization system. This library provides a component called <code class="language-plaintext highlighter-rouge">FormattedMessage</code> that finds the translation for a given key and locale. This component must be used within a React Context called <code class="language-plaintext highlighter-rouge">IntlProvider</code>.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">translations</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">translation</span><span class="dl">'</span> <span class="p">};</span>\n\n\n<span class="p">&lt;</span><span class="nc">IntlProvider</span> <span class="na">locale</span><span class="p">=</span><span class="s">"en"</span> <span class="na">messages</span><span class="p">=</span><span class="si">{</span><span class="nx">translations</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">FormattedMessage</span> <span class="na">id</span><span class="p">=</span><span class="s">"key"</span> <span class="p">/&gt;</span>\n<span class="p">&lt;/</span><span class="nc">IntlProvider</span><span class="p">&gt;;</span>\n</code></pre></div></div>\n\n<p>I like wrapping the <code class="language-plaintext highlighter-rouge">IntlProvider</code> in a custom provider that allows configuring React Intl for the entire application and provides additional features like locale switching. To keep this example simple, I hardcoded the locale.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">AppIntlProvider</span><span class="p">({</span> <span class="nx">children</span> <span class="p">}:</span> <span class="p">{</span> <span class="nl">children</span><span class="p">:</span> <span class="nx">ReactElement</span> <span class="p">})</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">translations</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">translation</span><span class="dl">'</span> <span class="p">};</span>\n \n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">IntlProvider</span>\n <span class="na">messages</span><span class="p">=</span><span class="si">{</span><span class="nx">translations</span><span class="si">}</span>\n <span class="na">locale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="na">defaultLocale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">IntlProvider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now let’s go back to the testing problem. The following example is a test that checks if the <code class="language-plaintext highlighter-rouge">onClick</code> callback is called when the button with the label “OK” is clicked.`</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">MyComponent</span><span class="p">({</span> <span class="nx">onClick</span> <span class="p">}:</span> <span class="p">{</span> <span class="nl">onClick</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="k">void</span> <span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>\n // ...\n <span class="p">&lt;</span><span class="nc">Button</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">FormattedMessage</span> <span class="na">id</span><span class="p">=</span><span class="s">"validate"</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">Button</span><span class="p">&gt;</span>\n <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n<span class="c1">//const translations = { validate: 'OK' };</span>\n\n<span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">validate something</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">onClick</span> <span class="o">=</span> <span class="nx">jest</span><span class="p">.</span><span class="nx">fn</span><span class="p">();</span>\n <span class="nx">render</span><span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">MyComponent</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span> <span class="p">/&gt;,</span>\n <span class="p">{</span>\n <span class="na">wrapper</span><span class="p">:</span> <span class="nx">AppIntlProvider</span><span class="p">,</span>\n <span class="p">},</span>\n <span class="p">);</span>\n \n <span class="nx">userEvent</span><span class="p">.</span><span class="nx">click</span><span class="p">(</span><span class="nx">screen</span><span class="p">.</span><span class="nx">getByText</span><span class="p">(</span><span class="dl">'</span><span class="s1">OK</span><span class="dl">'</span><span class="p">));</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">onClick</span><span class="p">).</span><span class="nx">toHaveBeenCalled</span><span class="p">();</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>What happens if an OPS changes the translation of the ‘validate’ key from ‘OK’ to ‘GO’ for any reason? Your test will break even if the code and the test have not changed. That is a shame. Should translations break your test suites? I would like to answer this question with a no.\nThe solution that I use to prevent this problem is to override each translation that the test needs. I added an extra prop to the custom React Intl provider called overriddenTranslations that lets me override the translations my test needs.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">AppIntlProvider</span><span class="p">(</span>\n <span class="p">{</span> <span class="nx">children</span><span class="p">,</span> <span class="nx">overriddenTranslations</span> <span class="p">}:</span>\n <span class="p">{</span> <span class="nl">children</span><span class="p">:</span> <span class="nx">ReactElement</span><span class="p">,</span> <span class="nx">overriddenTranslations</span><span class="p">?:</span> <span class="nb">Partial</span><span class="o">&lt;</span><span class="nx">Translations</span><span class="o">&gt;</span> <span class="p">},</span>\n<span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">translations</span><span class="p">:</span> <span class="nx">Translations</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">translation</span><span class="dl">'</span> <span class="p">};</span>\n \n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">IntlProvider</span>\n <span class="na">messages</span><span class="p">=</span><span class="si">{</span> <span class="p">{</span> <span class="p">...</span><span class="nx">translations</span><span class="p">,</span> <span class="p">...</span><span class="nx">overriddenTranslations</span> <span class="p">}</span> <span class="si">}</span>\n <span class="na">locale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="na">defaultLocale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">IntlProvider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, we only need to override the translation for the key ‘validate.’ Its value will remain ‘OK’ in the test context.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// const translations = { validate: 'GO' };</span>\n\n<span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">validate something</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">onClick</span> <span class="o">=</span> <span class="nx">jest</span><span class="p">.</span><span class="nx">fn</span><span class="p">();</span>\n <span class="nx">render</span><span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">MyComponent</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span> <span class="p">/&gt;,</span>\n <span class="p">{</span>\n <span class="na">wrapper</span><span class="p">:</span> <span class="p">(</span><span class="nx">children</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">AppIntlProvider</span> <span class="na">overriddenTranslations</span><span class="p">=</span><span class="si">{</span> <span class="p">{</span> <span class="na">validate</span><span class="p">:</span> <span class="dl">'</span><span class="s1">OK</span><span class="dl">'</span> <span class="p">}</span> <span class="si">}</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">AppIntlProvider</span><span class="p">&gt;</span>\n <span class="p">),</span>\n <span class="p">},</span>\n <span class="p">);</span>\n \n <span class="nx">userEvent</span><span class="p">.</span><span class="nx">click</span><span class="p">(</span><span class="nx">screen</span><span class="p">.</span><span class="nx">getByText</span><span class="p">(</span><span class="dl">'</span><span class="s1">OK</span><span class="dl">'</span><span class="p">));</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">onClick</span><span class="p">).</span><span class="nx">toHaveBeenCalled</span><span class="p">();</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>Overriding a translation makes the test more resilient; even if you change the translation, the test will still pass (be green). In this specific context, it allows the OPS team to change any translation without breaking the test suite.</p>\n\n Mon, 11 Dec 2023 00:00:00 -0600\n https://arnolanglade.github.io/test-strategy-i18n-react-application.html?s=feed\n https://arnolanglade.github.io/test-strategy-i18n-react-application.html\n \n react\n \n testing\n \n \n \n \n \n The Mikado Method: Small Steps, Big Improvements\n <p>In this blog post, I will introduce the Mikado Method. This method helps solve complex problems without breaking your codebase, even if you need to introduce significant changes.</p>\n\n<p>It is common to work using PR (Pull Request), you can work on your task without breaking your application and disturbing the rest of the team. However, when you start working on a task without maintaining something that works, you end up adding too many changes that are not production-ready. The drawback of this approach is that your PRs will be large and hard to merge.</p>\n\n<p>It often happens when you refactor your codebase. You start refactoring something but it breaks another part of this application, then you fix it but it introduces a new problem elsewhere. As a result, you accumulate many changes without being able to merge them.</p>\n\n<p>Merging big PR is more complicated than simple changes. First, we need to ask for code reviews, but it can be challenging for your teammate to understand what you did when your PR includes too many things. Then, another drawback is the need to rebase your PR several times due to other PRs being pushed to the main branch.</p>\n\n<p>Now, you understand why it’s difficult to introduce big changes in your codebase. It is better to work on small steps that can be mergeable at any time. The Mikado method takes its name from the Mikado game, where the goal is to remove one stick without disturbing the others. The Mikado method has the same philosophy. It aims to make small incremental improvements to a project without breaking the existing codebase. This way, you can push your changes at any time and they won’t break your application even if you did not finish your task.</p>\n\n<p>This method simplifies refactoring. You can continuously improve your codebase instead of stacking changes in a huge PR which can’t be merged because the test suites are broken. It’s better to regularly merge small changes that improve your codebase quality. This method is ideal for brownfield development. It enables you to add new features or alter existing ones without breaking the rest of the application. Moreover, it facilitates the improvement of the application’s architecture while allowing the delivery of new features concurrently.</p>\n\n<p>How does it work? Let’s take an example: MySQL doesn’t match the project’s needs; we need to use PostgreSQL. First, we need to define a goal that is clear and understandable for everyone. In our case, it is “Migrate the application from MySQL to PostgreSQL,” as you can see in the following example.</p>\n\n<p><img src="images/posts/mikado-method/define-goal.webp" alt="define a goal" /></p>\n\n<p><strong>Note:</strong> A goal can be what you want to improve in your application such as refactoring a section of the application to enhance its clarity or improving an existing feature.</p>\n\n<p>There are less chances that you can achieve your goal in a single attempt and quickly but we will try to solve it. Based on what we learn in this initial experimentation, we will split a big task (our goal) into smaller ones, which we call prerequisites. As mentioned earlier, this approach prevents ending up with a large pull request that is difficult to merge.</p>\n\n<p>To migrate the application to PostgreSQL, we first need to install the database. Then, we need to update our repositories because they use SQL queries specific to MySQL.</p>\n\n<p><img src="images/posts/mikado-method/add-prerequisites.webp" alt="add prerequisites to the mikado graph" /></p>\n\n<p>Now, you will start exploring all the prerequisites. Select a prerequisite from the list and start an experimentation to solve it. If you can easily achieve it, that’s excellent! Commit your changes, mark the prerequisite as completed, and proceed to the next one on the list.</p>\n\n<p><img src="images/posts/mikado-method/prerequisite-completed.webp" alt="prerequisite completed" /></p>\n\n<p>If you cannot easily solve it, you need to revert your changes and define a sublist of prerequisites to achieve the original prerequisite. The purpose is to avoid making big changes but to focus on working on small steps while keeping the codebase stable. Reverting changes may not be natural to a developer, but it’s an important step in the process. It allows you to continue working in smaller steps, while the exploration helps you learn what is necessary to solve a prerequisite.</p>\n\n<p><img src="images/posts/mikado-method/add-prerequisite-to-prerequisite.webp" alt="add prerequisite to prerequisite" /></p>\n\n<p>Continue to resolve all prerequisites until the end. When all prerequisites are done, your goal is completed!</p>\n\n<p><img src="images/posts/mikado-method/goal-completed.webp" alt="goal completed" /></p>\n\n<p>As you can see in the previous sections of the blog post, we can represent your progress as a graph. This is a useful way to communicate the progress of your task with the rest of the team. For example, you can show the mikado graph at the daily meeting to easily explain what you did. If, for any reason, you cannot complete your task, you can share the mikado graph with a colleague to explain what you’ve done and what remains to be done. Organizing your work becomes easier, especially when you are working on complex tasks. The Mikado graph is more visual than a simple to-do list because it allows you to see dependencies between prerequisites.</p>\n\n<p>I wrote a small application called MikadoApp to easily create and share your Mikado graphs. All the images in the blog posts are screenshots from the application. You can start using it thanks to this <a href="https://mikado-method-teal.vercel.app">link</a>, and you can find the source code on <a href="https://github.com/arnolanglade/mikado-app">GitHub</a>. Don’t hesitate to contribute to the application to improve it.</p>\n\n<p>Since I started using this method, my way of working has changed. I try to break down my work into small steps, and each commit can be pushed into production. If I refactor something, it’s great because I regularly push improvements. If I work on a feature, I can refactor what I need to create my feature without breaking the rest of the application.</p>\n\n<p>Now,I like working directly on the main branch, but I ensure that I only push stable commits. That’s what we call Trunk Based Development. This approach allows delivering small improvements to production quickly and frequently. Even though it can be practiced with PRs, I no longer prefer working with them due to the many associated processes that slow down the delivery.</p>\n\n Mon, 27 Nov 2023 00:00:00 -0600\n https://arnolanglade.github.io/mikado-method.html?s=feed\n https://arnolanglade.github.io/mikado-method.html\n \n methodology\n \n \n \n \n \n Open-Closed principle: Enhancing code modularity\n <p>Have you missed my last blog post about the <a href="/oop-inheritance-pitfalls.html">pitfalls of inheritance</a>? I explain how it could be a bad idea to use it too much. Applying composition prevents this problem; it is better to work with small classes to easily assemble. In this blog post, I will talk about the open-closed principle. This principle facilitates composition and helps avoid relying too much on inheritance.</p>\n\n<p>This principle is one of the SOLID principles, and I think it is super important because it allows you to write more flexible code. I wanted to explain it because its definition is quite simple, but it is not necessarily easy to grasp.</p>\n\n<blockquote>\n <p>The open closed principle states “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”; that is, such an entity can allow its behaviour to be extended without modifying its source code.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle">Wikipedia</a></p>\n</blockquote>\n\n<p>The first time I read the definition of this principle, I understood that I should not have to modify my code to add additional behavior. This part of the definition “open for extension” was a bit confusing. What did it mean? Does it refer to OOP inheritance? No, it doesn’t refer to OOP inheritance. I have written a blog post about OOP inheritance. It explains why extending a class to change its behavior may seem simple, but is it a good idea? It introduces a lot of coupling in your codebase and between your team.</p>\n\n<p>Before digging into the principle, let’s consider a scenario to illustrate the following example: a class called ‘DiscountCalculator’ is in charge of calculating discounts based on the products in the basket. We apply a 20% discount to products with the category ‘sport,’ a 50% discount to products with the category ‘home,’ and a 10% discount to products with the category ‘food.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">Product</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">public</span> <span class="nx">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span>\n <span class="k">public</span> <span class="nx">category</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span>\n <span class="k">public</span> <span class="nx">price</span><span class="p">:</span> <span class="kr">number</span>\n <span class="p">)</span> <span class="p">{}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">Basket</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">public</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[])</span> <span class="p">{}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">DiscountCalculator</span> <span class="p">{</span>\n <span class="nx">calculate</span><span class="p">(</span><span class="nx">basket</span><span class="p">:</span> <span class="nx">Basket</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="kd">let</span> <span class="nx">totalDiscount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>\n\n\n <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">product</span> <span class="k">of</span> <span class="nx">basket</span><span class="p">.</span><span class="nx">products</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">switch</span> <span class="p">(</span><span class="nx">product</span><span class="p">.</span><span class="nx">category</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">case</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">:</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.2</span><span class="p">;</span> <span class="c1">// 20% discount</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="k">case</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">:</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.5</span><span class="p">;</span> <span class="c1">// 50% discount</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="k">case</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">:</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.1</span><span class="p">;</span> <span class="c1">// 10% discount</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="p">}</span>\n <span class="p">}</span>\n \n <span class="k">return</span> <span class="nx">totalDiscount</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="c1">// Example usage:</span>\n<span class="nx">it</span><span class="p">.</span><span class="nx">each</span><span class="p">([</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Football</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">20</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Couch</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">100</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Banana</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>\n<span class="p">])(</span><span class="dl">'</span><span class="s1">calculates discounts for %s category</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">,</span> <span class="nx">expectedDiscount</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">product</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Product</span><span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">basket</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Basket</span><span class="p">([</span><span class="nx">product</span><span class="p">]);</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="k">new</span> <span class="nx">DiscountCalculator</span><span class="p">().</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">basket</span><span class="p">)).</span><span class="nx">toBe</span><span class="p">(</span><span class="nx">expectedDiscount</span><span class="p">);</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>This code does not follow the open-close principle because we need to modify this <code class="language-plaintext highlighter-rouge">DiscountCalculator</code> class every time we want to add or remove a discount rule. The problem is that<code class="language-plaintext highlighter-rouge">DiscountCalculator</code> may become really large if the business asks us to add a lot of discount rules. Large objects are hard to understand, so it won’t facilitate its maintenance and testability.</p>\n\n<p>Let’s refactor this code to enhance its modularity and align it with the Open-Closed principle. We will use the strategy pattern to rewrite the calculator to remove the hard-coded rules. First, we will introduce a new interface that specifies how a discount works. This interface has two methods: the first one is <code class="language-plaintext highlighter-rouge">isApplicable</code>, which determines if a discount can be applied to a product, while the second one <code class="language-plaintext highlighter-rouge">calculate</code> calculates the amount of the discount.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span>\n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span><span class="p">;</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">SportCategoryDiscount</span> <span class="k">implements</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">category</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">;</span>\n <span class="p">}</span>\n \n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.2</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">HomeCategoryDiscount</span> <span class="k">implements</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">category</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">;</span>\n <span class="p">}</span>\n \n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.5</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">FoodCategoryDiscount</span> <span class="k">implements</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">category</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">;</span>\n <span class="p">}</span>\n \n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.1</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then, we need to update the calculator. It will determine whether a discount is applicable to a product and calculate the discount amount. With this approach, you can easily add or remove discount rules as needed.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">DiscountCalculator</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">discounts</span><span class="p">:</span> <span class="nx">Discount</span><span class="p">[])</span> <span class="p">{}</span>\n \n <span class="nx">calculateDiscount</span><span class="p">(</span><span class="nx">basket</span><span class="p">:</span> <span class="nx">Basket</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="kd">let</span> <span class="nx">totalDiscount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>\n \n <span class="nx">basket</span><span class="p">.</span><span class="nx">products</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">discounts</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">discount</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">if</span><span class="p">(</span><span class="nx">discount</span><span class="p">.</span><span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">))</span> <span class="p">{</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">discount</span><span class="p">.</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="p">});</span>\n <span class="p">});</span>\n \n <span class="k">return</span> <span class="nx">totalDiscount</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="c1">// Example usage:</span>\n<span class="nx">it</span><span class="p">.</span><span class="nx">each</span><span class="p">([</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Football</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">20</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Couch</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">100</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Banana</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>\n<span class="p">])(</span><span class="dl">'</span><span class="s1">calculates discounts for %s category</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">,</span> <span class="nx">expectedDiscount</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">product</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Product</span><span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">basket</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Basket</span><span class="p">([</span><span class="nx">product</span><span class="p">]);</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="k">new</span> <span class="nx">DiscountCalculator</span><span class="p">([</span>\n <span class="k">new</span> <span class="nx">SportCategoryDiscount</span><span class="p">(),</span>\n <span class="k">new</span> <span class="nx">HomeCategoryDiscount</span><span class="p">(),</span>\n <span class="k">new</span> <span class="nx">FoodCategoryDiscount</span><span class="p">(),</span>\n <span class="p">]).</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">basket</span><span class="p">)).</span><span class="nx">toBe</span><span class="p">(</span><span class="nx">expectedDiscount</span><span class="p">);</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>We don’t need to over-engineer to apply the open-close principle. With the right design pattern, it is quite simple. Now, the discount calculator is more flexible. We didn’t introduce a lot of new code but we divided the class into smaller ones. Small classes are easier to test and understand, and it will facilitate the maintenance and the evolution of your application.</p>\n\n\n Mon, 13 Nov 2023 00:00:00 -0600\n https://arnolanglade.github.io/open-close-principle.html?s=feed\n https://arnolanglade.github.io/open-close-principle.html\n \n OOP\n \n SOLID\n \n \n \n \n \n The pitfalls of OOP's inheritance: Why simple isn't always better\n <p>In OOP, the simplest way to change the behavior of a class A is to create a class B that extends class A. Extensions allow you to override any public and protected methods of the parent class. That‘s quite simple, right?</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/simple-inheritance.svg" alt="Simple object inheritance" /></p>\n\n<p>Furthermore, you can extend a class multiple times with several levels of inheritance. In the following example, we can see that class B has two children, and the class hierarchy has four levels of inheritance. Now let’s explore why it is not a good idea and which problem can occur?</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/inheritance-with-several-levels.svg" alt="Object inheritance with several levels" /></p>\n\n<p>Designing code like this won’t facilitate refactoring. Let’s consider a scenario where Class A has a method that is overridden in both Class B and Class E. What happens if we decide to change the signature of this method in Class A? We will need to rewrite this method in Class B and Class E to match the new signature. Another frustrating aspect is that we will have to modify all portions of the code that use this method. In a small codebase, this may be manageable, but in a large one, it’s a different story!</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/refactoring-inheritance-with-several-levels.svg" alt="Refactoring with object inheritance with several levels" /></p>\n\n<p>This code won’t ease team collaboration. Let’s consider another scenario: where we are working on a huge monolith shared with several other teams. What happens if team A needs to change class A? That means teams B, C, and D must also update their codebases. We have introduced coupling between these three teams because of the coupling between classes A, B, C, and D. That’s a shame. This design will slow down your delivery because team A will need to coordinate with three other teams if it needs to change class A.</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/refactoring-inheritance-with-several-teams.svg" alt="Refactoring with object inheritance with several teams" /></p>\n\n<p>I have worked on several codebases that heavily relied on inheritance, but now I barely use it due to the drawbacks I’ve described. Instead, I prefer to use composition. It is better to work with several small classes and assemble them, it’s like playing with Lego blocks. Moreover, it greatly simplifies testing.</p>\n\n<p>I try to apply the open-closed principle as much as possible to enhance code modularity and facilitate evolution. In a related blog post, I explain the principle and provide an example to illustrate how to refactor code that doesn’t follow this principle. Here is the link:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/open-close-principle.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/open-close-principle.webp" alt="Open-Closed principle: Enhancing code modularity" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Open-Closed principle: Enhancing code modularity</span>\n </span>\n </a>\n</div>\n\n\n Mon, 23 Oct 2023 00:00:00 -0500\n https://arnolanglade.github.io/oop-inheritance-pitfalls.html?s=feed\n https://arnolanglade.github.io/oop-inheritance-pitfalls.html\n \n OOP\n \n \n \n \n \n Why breaking encapsulation is not a good idea\n <p>In this blog post, I would like to speak about an important concept in Oriented Object Programming which is the encapsulation principle.</p>\n\n<p>Before speaking about encapsulation let’s talk a bit about OOP. What is the object’s life cycle? The first step of the object’s life cycle is to be instantiated. We give everything an object needs to initialise its internal state. Then we use its public API (public methods) to communicate with it. An object exposes a public API (behaviour) that manipulates its internal state (data).</p>\n\n<p><img src="images/posts/why-breaking-encapsulation-is-not-a-good-idea/object-life-cycle.svg" alt="Object life cycle" /></p>\n\n<p>So, what is encapsulation? This principle restricts direct access to the state of the object from outside. This means that the internal implementation details of a class are hidden. Accessing the state of the object is only allowed through its public API (public methods). This concept helps to protect the data from outside interference and ensures controlled and secured data manipulation.</p>\n\n<p><strong>Note:</strong> An object that only has getters and setters is not an object! This is a data structure because it has no behaviour.</p>\n\n<p>I worked on many applications that used getters and setters. They are good examples of what is breaking encapsulation. It is easy to break encapsulation but it is not a good idea. It will make your code less maintainable and your applications less evolutive. Let’s take a simple example to understand why breaking encapsulation is a bad idea. I want to find the closest point of interest on a map close to a given location.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Location</span> <span class="o">=</span> <span class="p">{</span>\n <span class="na">latitude</span><span class="p">:</span> <span class="kr">number</span>\n <span class="na">longitude</span><span class="p">:</span> <span class="kr">number</span>\n<span class="p">}</span>\n\n\n<span class="kd">type</span> <span class="nx">PointOfInterest</span> <span class="o">=</span> <span class="p">{</span>\n <span class="na">name</span><span class="p">:</span> <span class="kr">string</span>\n <span class="na">location</span><span class="p">:</span> <span class="nx">Location</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nb">Map</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">pointOfInterests</span><span class="p">:</span> <span class="nx">PointOfInterest</span><span class="p">[])</span> <span class="p">{}</span>\n\n\n <span class="nx">getPointOfInterests</span><span class="p">():</span> <span class="nx">PointOfInterest</span><span class="p">[]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">pointOfInterests</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">AClassWhereWeNeedToFindClosestPOI</span> <span class="p">{</span>\n <span class="nx">doSomething</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">pointOfInterest</span> <span class="o">=</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getPointOfInterests</span><span class="p">()</span>\n <span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">pointOfInterest</span><span class="p">:</span> <span class="nx">PointOfInterest</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">})[</span><span class="mi">0</span><span class="p">]</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">Map</code> class has a <code class="language-plaintext highlighter-rouge">getPointOfInterest</code> getter that gets the class property with the same name. Then we can use this getter to access the list of points of interest to iterate them and find the closest one.</p>\n\n<p>The drawback with this getter is that we will need to copy/paste this piece of code if we have to look for the closest point of interest in several places. It won’t help you to mutualize code. At best, you can extract this piece of code into a dedicated class like the following example:</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">POIFinder</span> <span class="p">{</span>\n <span class="nx">find</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">):</span> <span class="nx">PointOfInterest</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getPointOfInterests</span><span class="p">()</span>\n <span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">pointOfInterest</span><span class="p">:</span> <span class="nx">PointOfInterest</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">})[</span><span class="mi">0</span><span class="p">]</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The problem with this code is that we extract the <code class="language-plaintext highlighter-rouge">Map</code> object behaviour into another class. We will turn the <code class="language-plaintext highlighter-rouge">Map</code> object into a data structure if we remove all methods that add a behaviour to it.</p>\n\n<p><strong>Note:</strong> A class that ends with -ER (like in the previous example) is a good insight into how this class does the job of another class.</p>\n\n<p>What happens if we need to change the internal of the POI list? Now, we don’t want to use an array anymore, we want to manage the POI list with a custom class named <code class="language-plaintext highlighter-rouge">PointOfInterestList</code>. It might be a simple refactoring for small applications but it is super painful for huge ones. If the getter method is used hundreds of times, we will have to refactor each <code class="language-plaintext highlighter-rouge">getPointOfInterest</code> usage to make them compatible with the new signature.</p>\n\n<p>To avoid this problem, we only need to apply the “Tell, don’t ask” principle. This principle says that we should tell an object to do something instead of asking for its internal state to do something in his stead.</p>\n\n<p>The solution would be to add a <code class="language-plaintext highlighter-rouge">findClosestPointOfInterest</code> method to the <code class="language-plaintext highlighter-rouge">Map</code> object. The only purpose of this method is to find the closest POI no matter how the POI list is designed. This allows you to refactor the internal state of the object as many times you want.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">ListOfPointOfInterest</span> <span class="p">{</span>\n <span class="nx">findClosest</span><span class="p">(</span><span class="nx">location</span><span class="p">:</span> <span class="nx">Location</span><span class="p">)</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nb">Map</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">pointOfInterests</span><span class="p">:</span> <span class="nx">ListOfPointOfInterest</span><span class="p">)</span> <span class="p">{}</span>\n\n\n <span class="nx">findClosestPointOfInterest</span><span class="p">(</span><span class="nx">location</span><span class="p">:</span> <span class="nx">Location</span><span class="p">):</span> <span class="nx">PointOfInterest</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">pointOfInterests</span><span class="p">.</span><span class="nx">findClosest</span><span class="p">(</span><span class="nx">location</span><span class="p">)</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> Breaking encapsulation to test your code is a bad idea too. I’ve written an article to present you with an alternative to the getter to prevent exposing the state of the objects. Here is the link:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/you-should-not-expose-objects-state-to-test-them.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/test-comparison.webp" alt="Why you should not expose objects' state to test them" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Why you should not expose objects' state to test them</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 19 Sep 2023 00:00:00 -0500\n https://arnolanglade.github.io/why-breaking-encapsulation-is-not-a-good-idea.html?s=feed\n https://arnolanglade.github.io/why-breaking-encapsulation-is-not-a-good-idea.html\n \n testing\n \n OOP\n \n \n \n \n \n Don’t test private methods\n <p>It is pretty easy to make mistakes when you start testing your code. One of the first mistakes I made was to test private methods. Spoiler alert: it was a bad idea because I had to use reflection to make them public to access them. If you need to test a private method, it probably means that your code is not well designed</p>\n\n<p>We don’t test private methods. Private methods are implementation details of objects and we should not care about them. Don’t worry! They are tested in the end. When you test public methods you also test the private ones as described in the next schema.</p>\n\n<p><img src="images/posts/do-not-test-private-method/test-private-methods-through-public-ones.svg" alt="Test private methods through public ones" /></p>\n\n<p>I needed to test the private methods because my object was a God object (huge object). It did a lot of things. It had a few public methods and a lot of private ones because too many things happened behind the scenes.</p>\n\n<p><img src="images/posts/do-not-test-private-method/object-with-too-many-private-methods.svg" alt="Object with too many private methods" /></p>\n\n<p>The problem with this design is this object did not follow the <strong>S</strong>ingle <strong>R</strong>esponsibility <strong>P</strong>rinciple, but what is this principle?</p>\n\n<blockquote>\n <p>There should never be more than one reason for a class to change. In other words, every class should have only one responsibility</p>\n\n <p><a href="https://en.wikipedia.org/wiki/SOLID">wikipedia</a></p>\n</blockquote>\n\n<p>My object was super huge because it did too many things. It had too many responsibilities. Because of that, I could not test it easily. How can we avoid that?</p>\n\n<p><img src="images/posts/do-not-test-private-method/complicated-to-test-objects-with-many-responsibilities.svg" alt="complicated to test objects with many responsibilities" /></p>\n\n<p>It’s better to work on small problems than a big one. The solution would have been to identify each responsibility to extract them into dedicated objects. We don’t need magic tricks to test small objects. It is simple to test them because they do a simple thing, and we only need to use their public API (public method) to test them. We don’t need reflection anymore.</p>\n\n<p><img src="images/posts/do-not-test-private-method/split-good-objects-into-small-classes.svg" alt="split good objects into small classes" /></p>\n\n<p>Then, we need to apply the composition pattern to assemble those classes to make them work as the God object. Composition is like playing Lego: we have many small bricks, and we put them together to make a big piece. Software is the same. You should work with small classes/functions to easily test them and piece them together to make your feature.</p>\n\n<p>Let’s take an example. The following class is in charge of importing products into an application as a PIM or an ERP. This class does several things, it gets product data from a CSV file and it imports them into a database. We need to test the whole class to ensure the product import works as expected. That’s a bit annoying because I can’t test the CSV file reading or the production saving.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Product</span> <span class="o">=</span> <span class="p">{</span>\n <span class="na">name</span><span class="p">:</span> <span class="kr">string</span>\n <span class="na">description</span><span class="p">:</span> <span class="kr">string</span>\n<span class="p">};</span>\n\n<span class="kd">class</span> <span class="nx">ProductImport</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">connection</span><span class="p">:</span> <span class="nx">Connection</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">async</span> <span class="k">import</span><span class="p">(</span><span class="nx">filePath</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">loadProductFromCsvFile</span><span class="p">(</span><span class="nx">filePath</span><span class="p">);</span>\n <span class="p">}</span>\n \n <span class="k">private</span> <span class="k">async</span> <span class="nx">loadProductFromCsvFile</span><span class="p">(</span><span class="nx">file</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="na">csvData</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>\n <span class="nx">createReadStream</span><span class="p">(</span><span class="nx">file</span><span class="p">)</span>\n <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">csvParser</span><span class="p">())</span>\n <span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">data</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="na">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">csvData</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">product</span><span class="p">))</span>\n <span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">end</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">data</span> <span class="k">of</span> <span class="nx">csvData</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">saveProducts</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="p">});</span>\n <span class="p">}</span>\n\n <span class="k">private</span> <span class="k">async</span> <span class="nx">saveProducts</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">execute</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">INSERT INTO products (name, description) VALUES (?, ?)</span><span class="dl">'</span><span class="p">,</span>\n <span class="p">[</span><span class="nx">product</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">product</span><span class="p">.</span><span class="nx">description</span><span class="p">],</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>We need to split this class into smaller ones to ease testing. We will extract both private methods into dedicated classes.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">CsvProductLoader</span> <span class="p">{</span>\n <span class="k">async</span> <span class="nx">loadProduct</span><span class="p">(</span><span class="nx">file</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nx">Product</span><span class="p">[]</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="na">products</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>\n <span class="nx">createReadStream</span><span class="p">(</span><span class="nx">file</span><span class="p">)</span>\n <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">csvParser</span><span class="p">())</span>\n <span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">data</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="na">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">products</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">product</span><span class="p">));</span>\n \n <span class="k">return</span> <span class="nx">products</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">MysqlProducts</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">connection</span><span class="p">:</span> <span class="nx">Connection</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">async</span> <span class="nx">save</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">execute</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">INSERT INTO products (name, description) VALUES (?, ?)</span><span class="dl">'</span><span class="p">,</span>\n <span class="p">[</span><span class="nx">product</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">product</span><span class="p">.</span><span class="nx">description</span><span class="p">],</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n<p>Now, we can test them stand-alone because these classes expose public methods. We don’t need a magic trick such as reflection to change their visibility to test them.</p>\n\n<p>We still need the <code class="language-plaintext highlighter-rouge">ProductImport</code> class. It will depend on both previous classes and act as a controller. It asks <code class="language-plaintext highlighter-rouge">CsvProductLoader</code> to get the product information from the CSV file and asks <code class="language-plaintext highlighter-rouge">CsvProductLoader</code> to save them into a database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">ProductImport</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">productLoader</span><span class="p">:</span> <span class="nx">CsvProductLoader</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">MysqlProducts</span><span class="p">,</span>\n <span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">async</span> <span class="k">import</span><span class="p">(</span><span class="nx">filePath</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">products</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">productLoader</span><span class="p">.</span><span class="nx">loadProduct</span><span class="p">(</span><span class="nx">filePath</span><span class="p">);</span>\n <span class="nx">products</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="na">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">products</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span><span class="nx">product</span><span class="p">));</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>That’s great because we extract IO usage into new classes. Both <code class="language-plaintext highlighter-rouge">MysqlProducts</code> and <code class="language-plaintext highlighter-rouge">CsvProductLoader</code> need to be tested with integration/contract tests since <code class="language-plaintext highlighter-rouge">ProductImport</code> can be unit tested.</p>\n\n<p>We need to make a last change. We cannot rely on concrete classes. We need to introduce interfaces to avoid coupling between <code class="language-plaintext highlighter-rouge">ProductImport</code> and its dependencies (<code class="language-plaintext highlighter-rouge">MysqlProducts</code> and <code class="language-plaintext highlighter-rouge">CsvProductLoader</code>).</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">ProductLoader</span> <span class="p">{</span>\n <span class="nx">loadProduct</span><span class="p">(</span><span class="nx">file</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nx">Product</span><span class="p">[]</span><span class="o">&gt;</span>\n<span class="p">}</span>\n\n<span class="kr">interface</span> <span class="nx">Products</span> <span class="p">{</span>\n <span class="nx">save</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">ProductImport</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">productLoader</span><span class="p">:</span> <span class="nx">ProductLoader</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">Products</span><span class="p">,</span>\n <span class="p">)</span> <span class="p">{}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note</strong>: I’ve written an article about how the inversion dependency design pattern will ease testing. Here is the link:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/inversion-dependency/ease-testing-thanks-to-the-dependency-inversion-design-pattern.webp" alt="Ease testing thanks to the dependency inversion design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Ease testing thanks to the dependency inversion design pattern</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 17 Jul 2023 00:00:00 -0500\n https://arnolanglade.github.io/do-not-test-private-methods.html?s=feed\n https://arnolanglade.github.io/do-not-test-private-methods.html\n \n testing\n \n OOP\n \n \n \n \n \n Ease testing thanks to the dependency inversion design pattern\n <p>In this new blog post, I would like to speak about the dependency inversion design pattern. This pattern makes your code more modular and helps to improve codebase testability. It’s quite simple and super powerful.</p>\n<h2 id="what-does-this-design-pattern-say">What does this design pattern say?</h2>\n<p>A class should not depend on another one to avoid coupling them together. If a class is coupled with another one, it means you won’t be able to use the first one without the second one.</p>\n\n<p><img src="images/posts/inversion-dependency/concrete-class-should-not-use-concrete-class.svg" alt="Concrete class should not use concrete class" /></p>\n\n<p>The classes should only depend on abstractions (e.g. interfaces). An interface can be implemented in several ways. It will make your code more modular because you can use a specific implementation depending on the context.</p>\n\n<p><img src="images/posts/inversion-dependency/depend-on-abstraction.svg" alt="Concrete class should depend on abstraction" /></p>\n\n<p>The interfaces should not depend on concrete implementations to avoid coupling them to another class.</p>\n\n<p><img src="images/posts/inversion-dependency/abstraction-should-not-use-concrete-class.svg" alt="Abstraction should not use concrete class" /></p>\n\n<h2 id="how-does-this-pattern-improve-testability">How does this pattern improve testability?</h2>\n\n<p>Let’s see with a simple example how dependency inversion helps to make your code easily testable. The following class lets a cartographer add a marker on a map.</p>\n\n<p><strong>Note:</strong> I wrote an article about unit testing to help you to understand the main mistakes that make your codebase less testable. Here is the link https://arnolanglade.github.io/why-unit-testing-can-be-hard.html.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">AddMarkerToMap</span> <span class="p">{</span>\n <span class="nx">execute</span><span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">repository</span> <span class="o">=</span> <span class="nx">PosgresqlMaps</span><span class="p">.</span><span class="nx">getInstance</span><span class="p">()</span>\n \n <span class="kd">const</span> <span class="nx">map</span> <span class="o">=</span> <span class="nx">repository</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="nx">marker</span><span class="p">.</span><span class="nx">mapId</span><span class="p">)</span>\n \n <span class="nx">map</span><span class="p">.</span><span class="nx">addMarker</span><span class="p">(</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span><span class="p">,</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="p">,</span>\n <span class="p">)</span>\n\n <span class="nx">repository</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">)</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>This class uses a singleton <code class="language-plaintext highlighter-rouge">PosgresqlMaps.getInstance()</code> to retrieve an instance of the <code class="language-plaintext highlighter-rouge">PosgresqlMaps</code> repository. This repository is in charge of saving map data into a PostgreSQL database. The problem is that we cannot run this code without a working database. This class is coupled to the <code class="language-plaintext highlighter-rouge">PosgresqlMaps</code> repository.</p>\n\n<p>We don’t want to use IO (your tools like a database) when we unit-test a piece of code because we want to avoid setting up any tools to a short feedback loop. We only want to check if a section of the application behaves as expected. We don’t want to test if the map data is well stored.</p>\n\n<p>Using the dependency inversion pattern will help us to remove the coupling between <code class="language-plaintext highlighter-rouge">AddMarkerToMap</code> and <code class="language-plaintext highlighter-rouge">PosgresqlMaps</code> and make it easy to unit test.</p>\n\n<p>First, we need to remove the coupling between both classes. We will create an abstraction to define how to retrieve and save maps in the application.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">Maps</span> <span class="p">{</span>\n <span class="kd">get</span><span class="p">(</span><span class="nx">mapId</span><span class="p">:</span> <span class="nx">MapId</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nb">Map</span><span class="o">&gt;</span><span class="p">;</span>\n <span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> When I cannot use a business term to name a repository I pluralize the name of my aggregate to name it. That’s why I name it <code class="language-plaintext highlighter-rouge">Maps</code> because I want to handle map aggregate persistence.</p>\n\n<p>Now, we can create as many implementations as we need. We will create a dedicated implementation for testing purposes. It will only keep it in memory which will avoid using a database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">InMemoryMaps</span> <span class="k">implements</span> <span class="nx">Maps</span> <span class="p">{</span>\n <span class="k">private</span> <span class="nx">maps</span><span class="p">:</span> <span class="nb">Record</span><span class="o">&lt;</span><span class="nx">MapId</span><span class="p">,</span> <span class="nb">Map</span><span class="o">&gt;</span><span class="p">;</span>\n \n <span class="k">async</span> <span class="kd">get</span><span class="p">(</span><span class="nx">mapId</span><span class="p">:</span> <span class="nx">MapId</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nb">Map</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">[</span><span class="nx">mapId</span><span class="p">];</span>\n <span class="p">}</span>\n\n <span class="k">async</span> <span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">[</span><span class="nx">map</span><span class="p">.</span><span class="nx">id</span><span class="p">()]</span> <span class="o">=</span> <span class="nx">map</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> I name all implementations with a prefix depending on what they are. If a repository uses a database, I will prefix the class with the name of the database. When I create an implementation for testing purposes, I use the <code class="language-plaintext highlighter-rouge">InMemory</code> prefix.</p>\n\n<p>As we want to create a working application, we will create an implementation which uses a database for the production environment.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">PosgresqlMaps</span> <span class="k">implements</span> <span class="nx">Maps</span> <span class="p">{</span>\n <span class="c1">// …</span>\n <span class="k">async</span> <span class="kd">get</span><span class="p">(</span><span class="nx">mapId</span><span class="p">:</span> <span class="nx">MapId</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nb">Map</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">map</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span>\n <span class="s2">`SELECT * FROM maps WHERE id = </span><span class="p">${</span><span class="nx">mapId</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span>\n <span class="p">);</span>\n\n\n <span class="k">return</span> <span class="k">new</span> <span class="nb">Map</span><span class="p">(</span><span class="nx">map</span><span class="p">);</span>\n <span class="p">}</span>\n \n <span class="k">async</span> <span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span>\n <span class="s2">`INSERT INTO maps VALUES (</span><span class="p">${</span><span class="nx">map</span><span class="p">.</span><span class="nx">toState</span><span class="p">()}</span><span class="s2">)`</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>We need to refactor a bit the <code class="language-plaintext highlighter-rouge">AddMarkerToMap</code> class to be able to inject an implementation of the <code class="language-plaintext highlighter-rouge">Maps</code> interface.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">AddMarkerToMap</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">maps</span><span class="p">:</span> <span class="nx">Maps</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="nx">execute</span><span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">map</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="nx">marker</span><span class="p">.</span><span class="nx">mapId</span><span class="p">)</span>\n\n\n <span class="nx">map</span><span class="p">.</span><span class="nx">addMarker</span><span class="p">(</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="p">,</span> <span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span>\n <span class="p">)</span>\n \n <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">)</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Finally, we can test this class because we can instantiate the <code class="language-plaintext highlighter-rouge">AddMarkerToMap</code> class with the <code class="language-plaintext highlighter-rouge">InMemoryMaps</code> class. This implementation helps us to test this class because it does not use any IO. Here, we don’t want to test if the data are well persisted but we want to test the business logic of marker addition on a map.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">adds a new marker to the map</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">maps</span> <span class="o">=</span> <span class="nx">InMemoryMaps</span><span class="p">()</span>\n \n <span class="k">new</span> <span class="nx">AddMarkerToMap</span><span class="p">(</span><span class="nx">maps</span><span class="p">).</span><span class="nx">execute</span><span class="p">({</span>\n <span class="na">mapId</span><span class="p">:</span> <span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">,</span> <span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Le Sunset</span><span class="dl">'</span><span class="p">,</span>\n <span class="na">latitude</span><span class="p">:</span> <span class="mf">23.252353245</span><span class="p">,</span> <span class="na">longitude</span><span class="p">:</span> <span class="mf">43.5432563457</span>\n <span class="p">})</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">maps</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span>\n <span class="k">new</span> <span class="nb">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nx">Marker</span><span class="p">(</span><span class="dl">'</span><span class="s1">Le Sunset</span><span class="dl">'</span><span class="p">,</span> <span class="mf">23.252353245</span><span class="p">,</span> <span class="mf">43.5432563457</span><span class="p">)</span>\n <span class="p">)</span>\n <span class="p">)</span>\n<span class="p">})</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> We don’t use a unit test to ensure the application uses its tools well. We use integration tests for this. For instance, if we want to ensure that a repository works as expected.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 19 Jun 2023 00:00:00 -0500\n https://arnolanglade.github.io/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html?s=feed\n https://arnolanglade.github.io/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html\n \n testing\n \n design-pattern\n \n OOP\n \n \n \n \n \n Use composition instead of props drilling\n <p>In this blog post, I would like to speak about how composition can improve your React codebase. It’s easy to add a lot of props to your component to make them configurable but it’s not a good idea.</p>\n\n<p>Let’s take an example. You are working on an e-Commerce webshop. A <code class="language-plaintext highlighter-rouge">ProductList</code> is used in the shop and the shop administration displays a list of products. In the shop administration, the component displays the product information and some calls to action (like product deletion and categorization for example) to manage products. In the shop you only need to display the product information, so, you don’t want to display the calls to action.</p>\n\n<p>As we can see in the next example, most of the <code class="language-plaintext highlighter-rouge">ProductList</code> props are used to render and configure the checkbox or the button.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductList</span><span class="p">({</span>\n <span class="nx">products</span><span class="p">,</span>\n <span class="nx">displayCheckbox</span><span class="p">,</span>\n <span class="nx">displayAction</span><span class="p">,</span>\n <span class="nx">actionLabel</span><span class="p">,</span>\n <span class="nx">onCheckboxClick</span><span class="p">,</span>\n <span class="nx">onActionClick</span><span class="p">,</span>\n<span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">products</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">product</span> <span class="o">=&gt;</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">displayCheckbox</span> <span class="o">&amp;&amp;</span>\n <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="p">=</span><span class="s">"checkbox"</span> <span class="na">onclick</span><span class="p">=</span><span class="si">{</span><span class="nx">onCheckboxClick</span><span class="si">}</span> <span class="p">/&gt;</span> <span class="p">:</span> <span class="kc">null</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">product</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">displayAction</span> <span class="o">&amp;&amp;</span>\n <span class="p">&lt;</span><span class="nt">button</span> <span class="na">onclick</span><span class="p">=</span><span class="si">{</span><span class="nx">onActionClick</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">actionLabel</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> <span class="p">:</span> <span class="kc">null</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n</code></pre></div></div>\n\n<p>This component is used in the <code class="language-plaintext highlighter-rouge">AdminShop</code>and <code class="language-plaintext highlighter-rouge">Shop</code> pages to display the product list to the customer or the shop owner.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Display to shop owner</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">AdminShop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getAllProducts</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span>\n <span class="na">products</span><span class="p">=</span><span class="si">{</span><span class="nx">products</span><span class="si">}</span>\n <span class="na">displayCheckbox</span><span class="p">=</span><span class="si">{</span><span class="kc">true</span><span class="si">}</span>\n <span class="na">displayAction</span><span class="p">=</span><span class="si">{</span><span class="kc">true</span><span class="si">}</span>\n <span class="na">actionLabel</span><span class="p">=</span><span class="s">"delete"</span>\n <span class="na">onCheckboxClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span>\n <span class="na">onActionClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span>\n <span class="p">/&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="c1">// Display to customers</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">Shop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getProductsAvailableforSale</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span>\n <span class="na">products</span><span class="p">=</span><span class="si">{</span><span class="nx">products</span><span class="si">}</span>\n <span class="na">displayCheckbox</span><span class="p">=</span><span class="si">{</span><span class="kc">false</span><span class="si">}</span>\n <span class="na">displayAction</span><span class="p">=</span><span class="si">{</span><span class="kc">false</span><span class="si">}</span>\n <span class="p">/&gt;</span>\n\n\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">ProductList</code> has to display elements depending on the given props. This big component will help mutualize the code but it will introduce complexity. Adding too many props will make your components complex, and hard to understand and maintain. Composition will help us to get rid of those props.</p>\n\n<p><strong>Note:</strong> The <code class="language-plaintext highlighter-rouge">ProductList</code> component only has 3 props because I wanted to keep the example simple but guess what happens when your components have tens of props to configure them?</p>\n\n<p>How can composition help us? It’s like playing Lego. You need several bricks from different sizes and colors to create something. The big <code class="language-plaintext highlighter-rouge">ProductList</code> component can be split into several small components used to build the product list depending on business cases.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductList</span><span class="p">({</span><span class="nx">children</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">children</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">Product</span><span class="p">({</span><span class="nx">label</span><span class="p">,</span> <span class="nx">checkbox</span><span class="p">,</span> <span class="nx">action</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">checkbox</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">label</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">action</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductCheckbox</span><span class="p">({</span><span class="nx">onClick</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="p">=</span><span class="s">"checkbox"</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span><span class="p">/&gt;;</span>\n<span class="p">}</span>\n\n\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductAction</span><span class="p">({</span><span class="nx">onClick</span><span class="p">,</span> <span class="nx">actionLabel</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">&lt;</span><span class="nt">button</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">actionLabel</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>In the previous code example, we created 4 new components: <code class="language-plaintext highlighter-rouge">ProductList</code>, <code class="language-plaintext highlighter-rouge">Product</code>, <code class="language-plaintext highlighter-rouge">ProductCheckbox</code> and <code class="language-plaintext highlighter-rouge">ProductAction</code>. They are like Lego bricks and we can assemble them to create the product list with or without the call to action.</p>\n\n<p><strong>Note:</strong> It’s not mandatory to create a dedicated component for the checkbox and the button. It can be useful to wrap generic components into more business-oriented ones. It helps to make things clearer. It’s another way to apply composition.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Display to shop owner</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">AdminShop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getAllProducts</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">products</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">product</span> <span class="o">=&gt;</span> \n <span class="p">&lt;</span><span class="nc">Product</span>\n <span class="na">label</span><span class="p">=</span><span class="si">{</span><span class="nx">product</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span>\n <span class="na">checkbox</span><span class="p">=</span><span class="si">{</span><span class="p">&lt;</span><span class="nc">ProductCheckbox</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span> <span class="p">/&gt;</span><span class="si">}</span>\n <span class="na">action</span><span class="p">=</span><span class="si">{</span><span class="p">&lt;</span><span class="nc">ProductAction</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span> <span class="na">actionLabel</span><span class="p">=</span><span class="si">{</span><span class="dl">"</span><span class="s2">delete</span><span class="dl">"</span><span class="si">}</span> <span class="p">/&gt;</span><span class="si">}</span>\n <span class="p">/&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="c1">// Display to customers</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">Shop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getProductAvailableforSale</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">products</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">product</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nc">Product</span> <span class="na">label</span><span class="p">=</span><span class="si">{</span><span class="nx">product</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span> <span class="p">/&gt;)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Small components are easier to test. They help build more stable applications and are easier to maintain. Your codebase will be less complex to understand. It will decrease your and your teammates’ mental load because you won’t have any components with complex API and logic.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 22 May 2023 00:00:00 -0500\n https://arnolanglade.github.io/use-composition-instead-of-props-drilling.html?s=feed\n https://arnolanglade.github.io/use-composition-instead-of-props-drilling.html\n \n react\n \n testing\n \n \n \n \n \n How to use custom React hook to increase application testability\n <p>In my previous blog, I spoke about reducing coupling in a React app to improve testing. Now I will show you how a custom React hook can increase testability.</p>\n\n<p><strong>Note:</strong> I assume that you are comfortable with React hooks. If you aren’t, please have a look at the <a href="https://reactjs.org/docs/hooks-intro.html">React documentation</a></p>\n\n<p>First of all, I will show you some code that is not testable. In my <a href="https://mymaps.world">side project</a>, I use <code class="language-plaintext highlighter-rouge">react-map-gl</code> to create maps with <a href="https://www.mapbox.com/">Mapbox</a>. Unfortunately, I can’t render the map with the testing library because this library only works in a web browser. I might have done something wrong but I haven’t found any solution to solve this problem.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">MapPage</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span><span class="nx">mapId</span><span class="p">}</span> <span class="o">=</span> <span class="nx">useParams</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">mapId</span><span class="p">:</span> <span class="kr">string</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">();</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">markers</span><span class="p">,</span> <span class="nx">setMarkers</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">isMarkerOpened</span><span class="p">,</span> <span class="nx">setIsMarkerOpened</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setMarkers</span><span class="p">(</span><span class="nx">getMarkers</span><span class="p">(</span><span class="nx">mapId</span><span class="p">));</span>\n <span class="p">},</span> <span class="p">[</span><span class="nx">mapId</span><span class="p">]);</span>\n\n\n <span class="kd">const</span> <span class="nx">openMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">closeMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;&gt;</span>\n <span class="p">&lt;</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">markers</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span>\n <span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nc">Marker</span>\n <span class="na">longitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span><span class="si">}</span>\n <span class="na">latitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="si">}</span>\n <span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerIcon</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">openMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">Marker</span><span class="p">&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerPopup</span> <span class="na">isOpened</span><span class="p">=</span><span class="si">{</span><span class="nx">isMarkerOpened</span><span class="si">}</span> <span class="na">onClose</span><span class="p">=</span><span class="si">{</span><span class="nx">closeMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/&gt;</span>\n <span class="p">)</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><code class="language-plaintext highlighter-rouge">MapPage</code> is in charge of loading map data depending on the <code class="language-plaintext highlighter-rouge">mapId</code> and rendering a map with its markers. I can’t test the <code class="language-plaintext highlighter-rouge">MapBoard</code> component because the <code class="language-plaintext highlighter-rouge">ReactMapGL</code> component can’t be rendered through the test tooling. That’s sad because I still want to check if I can open the marker popup when a user clicks on a marker.</p>\n\n<p>React will help us to fix this issue! We need to refactor this component to extract the business logic into a hook. This way, the component will only be responsible for rendering things. Let’s begin by creating the hooks.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="nx">mapId</span><span class="p">,</span> <span class="p">{</span><span class="nx">defaultIsMarkerOpened</span><span class="p">}</span> <span class="o">=</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">false</span><span class="p">})</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">markers</span><span class="p">,</span> <span class="nx">setMarkers</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">isMarkerOpened</span><span class="p">,</span> <span class="nx">setIsMarkerOpened</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="nx">defaultIsMarkerOpened</span><span class="p">);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setMarkers</span><span class="p">(</span><span class="nx">getMarkers</span><span class="p">(</span><span class="nx">mapId</span><span class="p">));</span>\n <span class="p">},</span> <span class="p">[</span><span class="nx">mapId</span><span class="p">]);</span>\n\n\n <span class="kd">const</span> <span class="nx">openMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">closeMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n\n\n <span class="k">return</span> <span class="p">{</span>\n <span class="nx">markers</span><span class="p">,</span>\n <span class="nx">isMarkerOpened</span><span class="p">,</span>\n <span class="nx">closeMarkerPopup</span><span class="p">,</span>\n <span class="nx">openMarkerPopup</span><span class="p">,</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n<p>The hook exposes two variables: <code class="language-plaintext highlighter-rouge">markers</code> which is an array of map’s markers and <code class="language-plaintext highlighter-rouge">isMarkerOpened</code> which is a boolean that indicates if the popup is opened or closed. It exposes two functions, <code class="language-plaintext highlighter-rouge">openMarkerPopup</code> and <code class="language-plaintext highlighter-rouge">closeMarkerPopup</code> that let us mutate the <code class="language-plaintext highlighter-rouge">isMarkerOpened</code> boolean.</p>\n\n<p><strong>Note:</strong> We could only expose <code class="language-plaintext highlighter-rouge">setIsMarkerOpened</code> but I think <code class="language-plaintext highlighter-rouge">openMarkerPopup</code> and <code class="language-plaintext highlighter-rouge">closeMarkerPopup</code> function names are clearer and match the component logic.</p>\n\n<p>Now, we need to call the hook from the <code class="language-plaintext highlighter-rouge">MapPage</code> component and it will still work as before.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">MapPage</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span>\n <span class="nx">markers</span><span class="p">,</span>\n <span class="nx">isMarkerOpened</span><span class="p">,</span>\n <span class="nx">closeMarkerPopup</span><span class="p">,</span>\n <span class="nx">openMarkerPopup</span>\n <span class="p">}</span> <span class="o">=</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="nx">mapId</span><span class="p">);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;&gt;</span>\n <span class="p">&lt;</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">markers</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span>\n <span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nc">Marker</span>\n <span class="na">longitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span><span class="si">}</span>\n <span class="na">latitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="si">}</span>\n <span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerIcon</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">openMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">Marker</span><span class="p">&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerPopup</span> <span class="na">isOpened</span><span class="p">=</span><span class="si">{</span><span class="nx">isMarkerOpened</span><span class="si">}</span> <span class="na">onClose</span><span class="p">=</span><span class="si">{</span><span class="nx">closeMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/&gt;</span>\n <span class="p">)</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">MapPage</code> is still untestable but we can start testing the hook to ensure hook logic matches business expectations. We can test if we can open a marker’s popup. That’s great because the testing library provides the <code class="language-plaintext highlighter-rouge">renderHook</code> helper that eases the hook testing.</p>\n\n<p><strong>Note:</strong> If you want to know how <code class="language-plaintext highlighter-rouge">renderHook</code> works you should have a look at this <a href="https://kentcdodds.com/blog/how-to-test-custom-react-hooks">blog post</a> written by <a href="https://twitter.com/kentcdodds">Kent C. Dodds</a>.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">describe</span><span class="p">(</span><span class="dl">'</span><span class="s1">Map Page</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">should open the marker popup</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span> <span class="nx">result</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">renderHook</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">useMapPage</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">false</span><span class="p">}</span>\n <span class="p">));</span>\n \n <span class="nx">act</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">openMarkerPopup</span><span class="p">());</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">isMarkerOpened</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n <span class="p">});</span>\n\n\n <span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">should close the marker popup</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span> <span class="nx">result</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">renderHook</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">useMapPage</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">true</span><span class="p">}</span>\n <span class="p">));</span>\n \n <span class="nx">act</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">closeMarkerPopup</span><span class="p">());</span>\n\n <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">isMarkerOpened</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n <span class="p">});</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>As I said at the beginning of this blog post I wrote a blog post to explain how to reduce coupling in a React application. Please, have a look at this <a href="/how-to-reduce-coupling-in-your-react-app.html">blog post</a> to understand how to make a dependency injection system.</p>\n\n<p>Now, we need to remove the <code class="language-plaintext highlighter-rouge">getMarkers</code> function call from the hooks if we want to test the map data loading. We don’t want to trigger side effects like HTTP calls in the unit test suite because we want to have the shortest feedback loop. We will get the <code class="language-plaintext highlighter-rouge">getMarkers</code> function to <code class="language-plaintext highlighter-rouge">useServiceContainer</code> which is a hook that provides any services.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="nx">mapId</span><span class="p">,</span> <span class="p">{</span><span class="nx">defaultIsMarkerOpened</span><span class="p">}</span> <span class="o">=</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">false</span><span class="p">})</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span><span class="nx">getMarkers</span><span class="p">}</span> <span class="o">=</span> <span class="nx">useServiceContainer</span><span class="p">();</span>\n <span class="c1">// ...</span>\n \n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setMarkers</span><span class="p">(</span><span class="nx">getMarkers</span><span class="p">(</span><span class="nx">mapId</span><span class="p">));</span>\n <span class="p">},</span> <span class="p">[</span><span class="nx">mapId</span><span class="p">]);</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>By default, the <code class="language-plaintext highlighter-rouge">useServiceContainer</code> hooks return the production services, we will need to replace the <code class="language-plaintext highlighter-rouge">getMarkers</code> service with a fake service for testing purposes. The <code class="language-plaintext highlighter-rouge">useServiceContainer</code> hooks can’t work without a React Provider. I like to create a factory that wraps components I test with all needed providers. It avoids a lot of noise in the test suites and makes tests more readable.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">const</span> <span class="nx">createWrapper</span> <span class="o">=</span> <span class="p">(</span><span class="nx">serviceContainer</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="kd">function</span> <span class="nx">Wrapper</span><span class="p">(</span>\n <span class="p">{</span> <span class="nx">children</span> <span class="p">}:</span> <span class="p">{</span> <span class="nl">children</span><span class="p">:</span> <span class="nx">ReactElement</span> <span class="p">},</span>\n<span class="p">)</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span> <span class="na">value</span><span class="p">=</span><span class="si">{</span><span class="nx">serviceContainer</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">};</span>\n</code></pre></div></div>\n\n<p>Note: the factory has a parameter which is the service container. It will let us define the services we want to override for testing.</p>\n\n<p>The <code class="language-plaintext highlighter-rouge">renderHook</code> has a <code class="language-plaintext highlighter-rouge">wrapper</code> option that lets you define the component that will wrap the hook you are testing. We will use the <code class="language-plaintext highlighter-rouge">createWrapper</code> factory to wrap the hook into the <code class="language-plaintext highlighter-rouge">ContainerContext</code> provider and we create a fake <code class="language-plaintext highlighter-rouge">getMarkers</code> service.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">describe</span><span class="p">(</span><span class="dl">'</span><span class="s1">Map Page</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">should load the markers of the map</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">markers</span> <span class="o">=</span> <span class="p">[{</span><span class="na">id</span><span class="p">:</span> <span class="dl">'</span><span class="s1">makerId</span><span class="dl">'</span><span class="p">}];</span>\n <span class="kd">const</span> <span class="p">{</span> <span class="nx">result</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">renderHook</span><span class="p">(</span>\n <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">),</span>\n <span class="p">{</span><span class="na">wrapper</span><span class="p">:</span> <span class="nx">createWrapper</span><span class="p">({</span><span class="na">getMarkers</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">markers</span><span class="p">})}</span>\n <span class="p">);</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">markers</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="nx">markers</span><span class="p">);</span>\n <span class="p">});</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>Now, the <code class="language-plaintext highlighter-rouge">getMarkers</code> is predictable. That means we can test the map loading because the <code class="language-plaintext highlighter-rouge">getMarker</code> function will return <code class="language-plaintext highlighter-rouge">[{id: 'makerId'}]</code> every time.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 04 Apr 2023 00:00:00 -0500\n https://arnolanglade.github.io/how-to-use-custom-react-hook-to-increase-application-testability.html?s=feed\n https://arnolanglade.github.io/how-to-use-custom-react-hook-to-increase-application-testability.html\n \n react\n \n testing\n \n \n \n \n \n How to reduce coupling in your React app\n <p>Today, I would like to cover dependency injection in React. I worked with several frameworks using tools to build and inject dependencies. It is pretty convenient if you apply the dependency inversion principle because you can easily change a dependency with another one.</p>\n\n<p>I will start by briefly introducing what is a React Context and I will then show you how to solve coupling problems in a React application.</p>\n\n<h2 id="what-is-a-react-context">What is a React Context?</h2>\n\n<blockquote>\n <p>Context provides a way to pass data through the component tree without having to pass props down manually at every level.</p>\n\n <p><a href="https://reactjs.org/docs/context.html">React documentation</a></p>\n</blockquote>\n\n<p>Let’s take an example: several components display the username of the user who is connected. We have to pass the username as props to every application component that needs this information. It is annoying, but React context can help for this specific use case.</p>\n\n<p>First, we need to create a context:</p>\n\n<p>```ts self-taught\nconst UserContext = React.createContext<string>();</string></p>\n<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\nThen, we need to wrap our components using a context provider and give it a value. The value is the data we want to share with the provider’s children components.\n\n```tsx\nfunction App() {\n return (\n &lt;UserContext.Provider value={'arn0'}&gt;\n &lt;Toolbar /&gt;\n &lt;OtherComponent /&gt;\n &lt;/UserContext.Provider&gt;\n );\n}\n</code></pre></div></div>\n\n<p>Finally, we can get this value (the username) from the context thanks to the useContext hooks.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">Toolbar</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">username</span> <span class="o">=</span> <span class="nx">useContext</span><span class="p">(</span><span class="nx">UserContext</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>\n Welcome <span class="si">{</span><span class="nx">username</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n</code></pre></div></div>\n<h2 id="which-problems-coupling-brings">Which problems coupling brings?</h2>\n\n<blockquote>\n <p>Coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)">Wikipedia</a></p>\n</blockquote>\n\n<p>The developer’s worst enemy is <strong>coupling</strong> because it makes your code less testable. To illustrate what I am saying we will take an example: a to-do list application. The <code class="language-plaintext highlighter-rouge">TodoList</code> component is responsible for retrieving data from the server and building the list of tasks to do.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">findTasks</span> <span class="o">=</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/tasks</span><span class="dl">'</span><span class="p">);</span>\n<span class="p">}</span>\n\n<span class="kd">function</span> <span class="nx">TodoList</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">setTasks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="o">&lt;</span><span class="nx">Task</span><span class="p">[]</span><span class="o">&gt;</span><span class="p">([]);</span>\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="p">(</span><span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">findTasks</span><span class="p">();</span>\n <span class="nx">setTasks</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>\n <span class="p">})();</span>\n <span class="p">},</span> <span class="p">[]);</span>\n \n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">task</span><span class="p">:</span> <span class="nx">Task</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nt">li</span> <span class="na">key</span><span class="p">=</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The problem with the <code class="language-plaintext highlighter-rouge">TodoList</code> component is that it depends on the <code class="language-plaintext highlighter-rouge">axios</code> library to get data from the server. It does not ease testing because we need to set up the server to make this component work. Unit testing requires a short feedback loop! We need to find a way to get rid of this HTTP call. It would be great to be able to do HTTP calls in production but using stub for testing.</p>\n\n<h2 id="how-react-context-reduces-coupling">How React Context reduces coupling?</h2>\n\n<p>The problem with the <code class="language-plaintext highlighter-rouge">TodoList</code> component is that we should be able to use several implementations of the <code class="language-plaintext highlighter-rouge">findTasks</code>, but we can’t with its design. We need an implementation for the production that will make an HTTP call and another one for testing that will return stub.</p>\n\n<p>The <code class="language-plaintext highlighter-rouge">findTasks</code> function should not be hardcoded but it should be injected as a component dependency. A React Context will help us to solve that issue.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">ServiceContainer</span> <span class="o">=</span> <span class="p">{</span><span class="na">findTasks</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nx">Task</span><span class="o">&gt;</span><span class="p">};</span>\n\n<span class="kd">const</span> <span class="nx">ContainerContext</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createContext</span><span class="o">&lt;</span><span class="nx">ServiceContainer</span><span class="o">&gt;</span><span class="p">({}</span> <span class="k">as</span> <span class="nx">ServiceContainer</span><span class="p">);</span>\n\n<span class="k">export</span> <span class="kd">const</span> <span class="nx">useServiceContainer</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">useContext</span><span class="p">(</span><span class="nx">ContainerContext</span><span class="p">);</span>\n\n<span class="kd">const</span> <span class="nx">findTasks</span> <span class="o">=</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/tasks</span><span class="dl">'</span><span class="p">);</span>\n<span class="p">}</span>\n\n<span class="kd">function</span> <span class="nx">App</span><span class="p">()</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span> <span class="na">value</span><span class="p">=</span><span class="si">{</span><span class="nx">findTasks</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">TodoList</span><span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">ServiceContainer</code> type represents all services we want to register in our application. The <code class="language-plaintext highlighter-rouge">ContainerContext</code> will share those services with <code class="language-plaintext highlighter-rouge">ContainerContext.Provider</code> children.</p>\n\n<p>Then, we only need to get the <code class="language-plaintext highlighter-rouge">findTasks</code> function from the React Context.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">TodoList</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span><span class="nx">findTasks</span><span class="p">}</span> <span class="o">=</span> <span class="nx">useServiceContainer</span><span class="p">();</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">setTasks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="o">&lt;</span><span class="nx">Task</span><span class="p">[]</span><span class="o">&gt;</span><span class="p">([]);</span>\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="p">(</span><span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">findTasks</span><span class="p">();</span>\n <span class="nx">setTasks</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>\n <span class="p">})();</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">task</span><span class="p">:</span> <span class="nx">Task</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nt">li</span> <span class="na">key</span><span class="p">=</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, the code is testable because we can easily replace the <code class="language-plaintext highlighter-rouge">findTasks</code> by stub in the test suite. We can easily set up a test because this new function does not use HTTP calls.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">render the todo list</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">render</span><span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span> <span class="na">value</span><span class="p">=</span><span class="si">{</span>\n <span class="p">{</span> <span class="na">findTasks</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">({</span><span class="na">id</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="na">label</span><span class="p">:</span> <span class="dl">'</span><span class="s1">label</span><span class="dl">'</span><span class="p">})</span> <span class="p">}</span>\n <span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">TodoList</span><span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span><span class="p">&gt;</span>\n <span class="p">)</span>\n\n <span class="c1">// …</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 06 Mar 2023 00:00:00 -0600\n https://arnolanglade.github.io/how-to-reduce-coupling-in-your-react-app.html?s=feed\n https://arnolanglade.github.io/how-to-reduce-coupling-in-your-react-app.html\n \n react\n \n design-patterns\n \n \n \n \n \n What is the difference between CQS and CQRS patterns?\n <p>I recently found out that I did not grasp those design patterns. There are a lot of resources on the Internet about them but they are not always accurate. That’s a shame because they are pretty simple. I will share my understanding of them with you.</p>\n\n<h2 id="what-is-command-query-segregation-cqs">What is Command Query Segregation (CQS)?</h2>\n\n<blockquote>\n <p>The fundamental idea is that we should divide an object’s methods into two sharply separated categories:</p>\n <ul>\n <li>Queries: Return a result and do not change the observable state of the system (are free of side effects).</li>\n <li>Commands: Change the state of a system but do not return a value.</li>\n </ul>\n\n <p><a href="https://martinfowler.com/bliki/CommandQuerySeparation.html">Martin Fowler</a></p>\n</blockquote>\n\n<p>This concept is not specific to Object Oriented Programming but improves the object’s design. The object methods only have a single purpose: reading or changing the object state. We can see an object as a living entity. We can ask a question to someone because we need information. For example, we can ask someone what time it is. This is a query. We can ask someone to do something, we don’t expect an answer but we want to get the job done. For example, we can ask a child to finish his/her spinach. This is a command.</p>\n\n<p>We can apply this pattern to any object: like an aggregate. Let’s take an example! I would like to add markers on a map and then I would like to find which markers are the closest to a specific location (GPS Coordinates).\nk</p>\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nb">Map</span> <span class="p">{</span>\n <span class="nx">addMarker</span><span class="p">(</span><span class="nx">label</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">latitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="k">void</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n\n <span class="nx">findClosestMarkers</span><span class="p">(</span><span class="nx">location</span><span class="p">:</span> <span class="nx">Location</span><span class="p">):</span> <span class="nx">Marker</span><span class="p">[]</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">addMarker</code> method is in charge of mutating the object state without returning any result, while the ‘findClosestMarkers’ method finds the right markers without changing the object’s state. This object follows the CQS definition.</p>\n\n<p>Let’s go further. If we design our aggregates following the CQS pattern, we should apply it to the classes that handle use cases.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">MapService</span> <span class="p">{</span>\n <span class="nx">addMarkerToTheMap</span><span class="p">(</span><span class="nx">label</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">latitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">);</span> <span class="k">void</span>\n <span class="nx">findAllMarkersCloseToLocation</span><span class="p">():</span> <span class="nx">Marker</span><span class="p">[]</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>This ensures there is no inconsistency in the codebase. The business services use and manipulate the aggregates. For example, if the <code class="language-plaintext highlighter-rouge">MapService.addMarkerToTheMap</code> method returns a result, it might mean that the <code class="language-plaintext highlighter-rouge">Map.addMarker</code> method will need to return the expected result.</p>\n\n<h2 id="what-is-command-query-responsibility-segregation-cqrs">What is Command Query Responsibility Segregation (CQRS)?</h2>\n\n<blockquote>\n <p>Starting with CQRS, CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).</p>\n\n <p><a href="https://web.archive.org/web/20190211113420/http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-sourcing-agh/">Greg young</a></p>\n</blockquote>\n\n<p><strong>Note:</strong> Greg Young’s blog does not exist anymore but his blog posts are still available thanks to archived.org.</p>\n\n<p>CQRS is the separation of command and query into two different objects instead of only one. MapService does not follow the CQRS pattern because it has a query and a command. We need to cut this object in half.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">MapReadService</span> <span class="p">{</span>\n <span class="nx">addMarkerToTheMap</span><span class="p">(</span><span class="nx">label</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">latitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">);</span> <span class="k">void</span>\n<span class="p">}</span>\n\n<span class="kr">interface</span> <span class="nx">MapWriteService</span> <span class="p">{</span>\n <span class="nx">findAllMarkersCloseToLocation</span><span class="p">():</span> <span class="nx">Marker</span><span class="p">[]</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>That’s pretty simple, right? Anyway, we don’t need to introduce complicated things in our application to use this tactical design pattern. We don’t need a write and a read model,\na command and query bus, an event sourcing architecture or multiple databases. Greg Young published this blog post in 2012 to explain what CQRS was not about.</p>\n\n<blockquote>\n <p>CQRS is not a silver bullet\nCQRS is not a top level architecture\nCQRS is not new\nCQRS is not shiny\nCQRS will not make your jump shot any better\nCQRS is not intrinsically linked to DDD\nCQRS is not Event Sourcing\nCQRS does not require a message bus\nCQRS is not a guiding principle / CQS is\nCQRS is not a good wife\nCQRS is learnable in 5 minutes\nCQRS is a small tactical pattern\nCQRS can open many doors.</p>\n</blockquote>\n\n<p><strong>Note:</strong> This blog does not exist anymore but it has been archived by archived.org. The post is available <a href="https://web.archive.org/web/20160729165044/https://goodenoughsoftware.net/2012/03/02/cqrs/">here</a></p>\n\n<p>Depending on the number of use cases the service classes can become really huge. CQRS helps to decrease their size but I am a big fan of them. I like to separate each use case into a dedicated class.</p>\n\n<p>I’ve written a blog post to explain what is a commands and we can apply it to query too:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-handler-patterns.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-handler/command-handler.webp" alt="Command and command handler design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Command and command handler design pattern</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 06 Feb 2023 00:00:00 -0600\n https://arnolanglade.github.io/what-is-the-difference-between-cqs-and-cqrs-patterns.html?s=feed\n https://arnolanglade.github.io/what-is-the-difference-between-cqs-and-cqrs-patterns.html\n \n software-architecture\n \n design-patterns\n \n \n \n \n \n Hexagonal architecture by example\n <p>In this blog post, I would like to explain the basics of hexagonal architecture thanks to a simple example: a product catalogue. The catalogue manager can add new products through a user interface and the nightly cron task imports new products from the ERP.</p>\n\n<p>Before going deeper into hexagonal architecture, let’s see what we need to create the product management application. We need two entry points: the first one will be consumed by the graphical client and the other one will be used by the cron task. Then, we will need another piece of code which will be in charge of persisting product data into storage.</p>\n\n<p><img src="images/posts/hexagonal-architecture/application-architecture.svg" alt="Application architecture" /></p>\n\n<h2 id="what-is-hexagonal-architecture">What is hexagonal architecture?</h2>\n\n<blockquote>\n <p>The hexagonal architecture, or ports and adapters architecture, is an architectural pattern used in software design. It aims at creating loosely coupled application components that can be easily connected to their software environment by means of ports and adapters. This makes components exchangeable at any level and facilitates test automation.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Hexagonal_architecture_(software)">Wikipedia</a></p>\n</blockquote>\n\n<p>There are three main areas in the hexagonal architecture:\nThe <strong>primary adapters (user interface)</strong> are the whole application entry points that can be consumed by clients like a UI or a CLI.\nThe <strong>secondary adapters (infrastructure)</strong> connect the application to tools like the database, file system, etc.\nThe <strong>domain</strong> is all pieces of code that represent the problem we are solving. This part must be side-effect free (it must not use any tools).</p>\n\n<h2 id="domain">Domain</h2>\n\n<p>The domain is the area where we solve our business problems no matter the technical constraints. We can start by designing the product aggregate.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Name</span> <span class="o">=</span> <span class="kr">string</span><span class="p">;</span>\n<span class="kd">type</span> <span class="nx">Description</span> <span class="o">=</span> <span class="kr">string</span><span class="p">;</span>\n\n<span class="k">export</span> <span class="kd">class</span> <span class="nx">Product</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">name</span><span class="p">:</span> <span class="nx">Name</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">description</span><span class="p">:</span> <span class="nx">Description</span>\n <span class="p">)</span> <span class="p">{}</span>\n\n <span class="nx">toState</span><span class="p">():</span> <span class="kr">string</span><span class="p">[]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">description</span><span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>As I said, we need to save products into the database but we don’t mind if the database is PostgreSQL, MySQL or whatever in the domain. We will define an <strong>abstraction (an interface)</strong> to avoid accessing any technical asset from the domain. This interface which is called a <strong>port</strong> will specify how to store a new product from a business point of view. This is nothing more than applying the dependency inversion design pattern.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kr">interface</span> <span class="nx">ProductCatalog</span> <span class="p">{</span>\n <span class="nx">add</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="k">void</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h3 id="what-about-testing">What about testing?</h3>\n\n<p>Moving IO as far as possible from your domain code is really convenient because it eases unit testing. We will mainly test this part of the application with unit testing. It offers a very short feedback loop, it will help you to design your domain step by step without setting up the whole application.</p>\n\n<p><strong>Tip:</strong> I’ve written a blog post about unit testing that explains why testing can be hard. It mainly gives you tips to move IO outside your code to make it testable.</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="why-unit-testing-can-be-hard.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/why-unit-testing-can-be-hard.webp" alt="Why unit testing can be hard?" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Why unit testing can be hard?</span>\n </span>\n </a>\n</div>\n\n<h3 id="coupling-rules">Coupling rules</h3>\n\n<p>The domain code must not use any IO: any tools like your database, randomness, or actual datetime, nor depend on the primary and the secondary adapters. We will explain what they are in the next sections.</p>\n\n<h2 id="secondary-adapters-infrastructure">Secondary adapters (Infrastructure)</h2>\n\n<p>The secondary or driven adapters implement the ports defined in the domain. In our example, the adapter will be a <code class="language-plaintext highlighter-rouge">PostgresProductCatalog</code> class that implements the <code class="language-plaintext highlighter-rouge">ProductCatalog</code> interface (port). Its purpose will be to store product data in a database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">PostgresProductCatalog</span> <span class="k">implements</span> <span class="nx">ProductCatalog</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">pg</span><span class="p">:</span> <span class="nx">Client</span><span class="p">)</span> <span class="p">{}</span>\n\n <span class="nx">add</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">pg</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">INSERT INTO product (name, properties) VALUES ($1, $2)</span><span class="dl">'</span><span class="p">,</span>\n <span class="nx">product</span><span class="p">.</span><span class="nx">toState</span><span class="p">()</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>An advantage of this architecture is that we can simply delay choices. At the beginning of a project, it may be hard to choose the right tools because you still need to learn and understand the business. In that case, you can implement an in-memory adapter, it will work the same way as the previous one but it will only keep product aggregate in memory.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">InMemoryProductCatalog</span> <span class="k">implements</span> <span class="nx">ProductCatalog</span> <span class="p">{</span>\n <span class="k">private</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[];</span>\n\n <span class="nx">add</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">products</span> <span class="o">=</span> <span class="p">[</span><span class="nx">product</span><span class="p">,</span> <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">products</span><span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> This adapter can be used in your test suites because it lets you bypass your tools constraints like foreign key constraints when we use a database, for instance.</p>\n\n<h3 id="what-about-testing-1">What about testing?</h3>\n\n<p>The part of the application is mainly covered by “integration” or “contract” tests. Those tests ensure that the tools used by the application work as expected. For example, you are able to save and query your database.</p>\n\n<p><strong>Tip:</strong> I encourage you to test all implementations of a given port with the same test because it will ensure they work the same way.</p>\n\n<h3 id="coupling-rules-1">Coupling rules</h3>\n\n<p>The infrastructure code only depends on the domain code.</p>\n\n<h2 id="primary-adapters-user-interface">Primary adapters (User interface)</h2>\n\n<p>The primary adapters or driving adapters are entry points that describe how the application is consumed by the clients. Their purpose is to tell the domain what to do. Actually, it can be a Web controller or CLI command for instance.</p>\n\n<p>In our example, we need two adapters: a web controller and a CLI command. Both of them will execute the same action, they will save product data but they have different input and output. The first one takes JSON and returns an HTTP response and the second one takes input and returns code status.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">try</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">productCatalog</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="k">new</span> <span class="nx">Product</span><span class="p">(</span>\n <span class="nx">request</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">),</span> <span class="c1">// get name argument for cli command</span>\n <span class="nx">request</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">description</span><span class="dl">'</span><span class="p">),</span> <span class="c1">// get description argument for cli command</span>\n <span class="p">))</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">HttpResponse</span><span class="p">(</span><span class="mi">201</span><span class="p">);</span> <span class="c1">// return 0 for cli command</span>\n<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nb">Error</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nx">HttpResponse</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span> <span class="c1">// return 1 for cli command</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>As you see, the only differences are the input and output of the adapter. We need to refactor this code to avoid duplication between both primary adapters. It should be extracted into a dedicated business service.</p>\n\n<p><strong>Tip:</strong> These business services can be written using the command and command handler patterns. I’ve written a blog post that explains these design patterns:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-handler-patterns.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-handler/command-handler.webp" alt="Command and command handler design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Command and command handler design pattern</span>\n </span>\n </a>\n</div>\n\n<p>I’ve written a bunch of articles about how to handle a command, validate its data, handle user permissions, and so on. Take a look at these articles:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/tag/command-bus">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/data-validation.webp" alt="See all blog posts about command handling." />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">See all blog posts about command handling.</span>\n </span>\n </a>\n</div>\n\n<h3 id="what-about-testing-2">What about testing?</h3>\n\n<p>There are several ways to test primary adapters.</p>\n\n<p>First option: the easiest one, your application only has one primary adapter. I advise you to write an acceptance test that boots the application and checks that the whole application works for each business use case.</p>\n\n<p>Second option: the complex one, your application has several primary adapters like our example (web and CLI). I advise you to check that your command handler works as expected thanks to an acceptance. That way you ensure your handler will work as expected for both adapters. Thus, you can write a test to ensure that the adapters return the right output (HTTP response or code status) depending on the case.</p>\n\n<h3 id="coupling-rules-2">Coupling rules</h3>\n\n<p>The user interface code only depends on the domain code.</p>\n\n<h2 id="flow-of-control">Flow of control</h2>\n\n<p><img src="images/posts/hexagonal-architecture/hexgonal-architecture-flow-control.svg" alt="Hexgonal architecture: flow control" /></p>\n\n<p>The application flow goes from the user interface <strong>(1)</strong> through the domain <strong>(2)</strong> to the infrastructure <strong>(3)</strong> then goes back through the domain <strong>(2)</strong> to the user interface <strong>(4)</strong>.</p>\n\n<p>Example: The UI sends data to an HTTP controller <strong>(1)</strong>, then a product aggregate is created <strong>(2)</strong>, then the repository saves data into the database <strong>(3)</strong>, and finally the web controller sends a 200 HTTP response <strong>(4)</strong>. We don’t need step <strong>(2)</strong> because nothing happens in the domain after the product creation.</p>\n\n<h2 id="code-organization">Code organization</h2>\n\n<p>The <strong>domain</strong> contains the aggregates, ports, business services and so on. Most importantly, they must not use IO and must be business oriented.</p>\n\n<p>The <strong>infrastructure</strong> contains all secondary adapters that use external tools (IO) like your database.</p>\n\n<p>The <strong>user interface</strong> contains all primary adapters that are the application entry points. Users and machines use them to interact with the application.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>src\n├── domain\n│ ├── ProductCatalog.ts\n│ └── Product.ts\n├── infra\n│ ├── InMemoryProductCatalog.ts\n│ └── PostgresProductCatalog.ts\n└── user-interface\n ├── CliCreateProduct.ts\n └── WebCreateProduct.ts\n</code></pre></div></div>\n\n<p><strong>Note:</strong> I decided to split each class/interface into a dedicated module because I wanted to show you where things are. Feel free to organize your module as you wish.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 09 Jan 2023 00:00:00 -0600\n https://arnolanglade.github.io/hexagonal-architect-by-example.html?s=feed\n https://arnolanglade.github.io/hexagonal-architect-by-example.html\n \n software-architecture\n \n \n \n \n \n What is the event sourcing pattern?\n <p>Event sourcing consists in storing all changes that happened to an application as a sequence of events instead of only storing the current state of the application. The sum of all events is the current application state. When I heard about this pattern a few years ago, I was really confused. I used to only persist the current application state in a database and that was fine! So I asked myself do I need that?</p>\n\n<p>I will show you an example to help you understand what this pattern stands for. People used to explain it with a bank account but I wanted to find something funnier: a table soccer game. A complete example is available on a Github repository:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="https://github.com/arnolanglade/table-soccer">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/github-logo.png" alt="Have a look at the GitHub repository" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Have a look at the GitHub repository</span>\n </span>\n </a>\n</div>\n\n<p>Let’s start! A group of developers who are fans of table soccer wants to create an application to see who’s the best player. They decided to save the results of matches and rank themselves.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">redTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">blueTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">gameScore</span><span class="p">:</span> <span class="nx">Score</span><span class="p">,</span>\n <span class="p">)</span> <span class="p">{}</span>\n\n <span class="k">public</span> <span class="nx">recordScore</span><span class="p">(</span><span class="nx">redPlayerScore</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">bluePlayerScore</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">,</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">,</span>\n <span class="k">new</span> <span class="nx">Score</span><span class="p">(</span><span class="nx">redPlayerScore</span><span class="p">,</span> <span class="nx">bluePlayerScore</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n\n <span class="c1">// example: ['arn0', 'momos', 'Popeye', 'coco', 10, 1]</span>\n <span class="k">public</span> <span class="nx">toState</span><span class="p">():</span> <span class="p">[</span><span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">,</span> <span class="kr">number</span><span class="p">,</span> <span class="kr">number</span><span class="p">]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">[</span>\n <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">.</span><span class="nx">toState</span><span class="p">(),</span>\n <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">.</span><span class="nx">toState</span><span class="p">(),</span>\n <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">gameScore</span><span class="p">.</span><span class="nx">toState</span><span class="p">()</span>\n <span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">Game</code> Aggregate has a <code class="language-plaintext highlighter-rouge">recordScore</code> method to record the score at the end of the game. Then we get the current state of <code class="language-plaintext highlighter-rouge">Game</code> with the <code class="language-plaintext highlighter-rouge">toState</code> method to save it in the database.</p>\n\n<p>That works perfectly for the one versus one games but what happens for two versus two games? Let’s focus on one of the players, we will call him Popeye. Actually, Popeye is not a really good player even if he is full of goodwill. He is smart, he always wants to play with the best player to have more chances to win. We cannot know who is the best player with only the result of the game. Who has really scored? Popeye or its teammate?</p>\n\n<p>Event sourcing is the solution. Instead of saving the score of the game, we will store what really happens. We will refactor the <code class="language-plaintext highlighter-rouge">Game</code> aggregate to make it compliant with the event sourcing pattern.</p>\n\n<p>First, we will rework the aggregate construction. We still want to encapsulate its current state but we want to record all events that happened too. In the following example, we added an <code class="language-plaintext highlighter-rouge">events</code> argument to the primary constructor and a named constructor (secondary construct) called <code class="language-plaintext highlighter-rouge">start</code> to the <code class="language-plaintext highlighter-rouge">Game</code> class. From a business point of view, its goal is to initialize the game and from a technical point of view, it lets us record the <code class="language-plaintext highlighter-rouge">GameStarted</code> event.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">redTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">blueTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">gameScore</span><span class="p">:</span> <span class="nx">Score</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">events</span><span class="p">:</span> <span class="nx">Event</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[]</span>\n <span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">public</span> <span class="k">static</span> <span class="nx">start</span><span class="p">(</span>\n <span class="nx">redAttacker</span><span class="p">:</span> <span class="nx">Player</span><span class="p">,</span>\n <span class="nx">redDefender</span><span class="p">:</span> <span class="nx">Player</span><span class="p">,</span>\n <span class="nx">blueAttacker</span><span class="p">:</span> <span class="nx">Player</span><span class="p">,</span>\n <span class="nx">blueDefender</span><span class="p">:</span> <span class="nx">Player</span>\n <span class="p">):</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">redTeam</span> <span class="o">=</span> <span class="nx">Team</span><span class="p">.</span><span class="nx">ofTwoPlayer</span><span class="p">(</span><span class="nx">redAttacker</span><span class="p">,</span> <span class="nx">redDefender</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">blueTeam</span> <span class="o">=</span> <span class="nx">Team</span><span class="p">.</span><span class="nx">ofTwoPlayer</span><span class="p">(</span><span class="nx">blueAttacker</span><span class="p">,</span> <span class="nx">blueDefender</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span>\n <span class="nx">redTeam</span><span class="p">,</span>\n <span class="nx">blueTeam</span><span class="p">,</span>\n <span class="nx">Score</span><span class="p">.</span><span class="nx">playersHaveNotScored</span><span class="p">(),</span>\n <span class="p">[</span><span class="k">new</span> <span class="nx">GameStarted</span><span class="p">(</span><span class="nx">redTeam</span><span class="p">,</span> <span class="nx">blueTeam</span><span class="p">)],</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then we will add a new method to <code class="language-plaintext highlighter-rouge">Game</code> to record all goals scored by any players. That will let us know who is the best striker in the game. In the following example, we record two events: <code class="language-plaintext highlighter-rouge">GoalScored</code> and <code class="language-plaintext highlighter-rouge">GameEnded</code>. The first one is recorded every time a player scores and the second one is recorded when the first team has 10 points meaning the game is over.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span> \n <span class="c1">// …</span>\n <span class="k">public</span> <span class="nx">goalScoredBy</span><span class="p">(</span><span class="nx">player</span><span class="p">:</span> <span class="nx">Player</span><span class="p">):</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">teamColor</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">.</span><span class="nx">isTeammate</span><span class="p">(</span><span class="nx">player</span><span class="p">)</span> <span class="p">?</span> <span class="nx">TeamColor</span><span class="p">.</span><span class="nx">Red</span> <span class="p">:</span> <span class="nx">TeamColor</span><span class="p">.</span><span class="nx">Blue</span><span class="p">;</span>\n <span class="kd">const</span> <span class="nx">gameScore</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">gameScore</span><span class="p">.</span><span class="nx">increase</span><span class="p">(</span><span class="nx">teamColor</span><span class="p">);</span>\n\n <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">GoalScored</span><span class="p">(</span><span class="nx">teamColor</span><span class="p">,</span> <span class="nx">player</span><span class="p">,</span> <span class="nx">gameScore</span><span class="p">))</span>\n\n <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">gameScore</span><span class="p">.</span><span class="nx">canIncrease</span><span class="p">(</span><span class="nx">teamColor</span><span class="p">))</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">GameEnded</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">,</span> <span class="nx">gameScore</span><span class="p">))</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">,</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">,</span>\n <span class="nx">gameScore</span><span class="p">,</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">,</span>\n <span class="p">);</span>\n <span class="p">}</span>\n <span class="c1">// …</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> We can drop the <code class="language-plaintext highlighter-rouge">recordScore</code> method because we won’t want to only record the score of the game at the end of the game.</p>\n\n<p>Finally, the last thing to refactor is the persistence mechanism. We need to rework the <code class="language-plaintext highlighter-rouge">toState</code> because we won’t store a snapshot of the <code class="language-plaintext highlighter-rouge">Game</code> state but we want to save all events raised during the game. This method will return all serialized events and metadata like the name of the aggregate. Normally, we should persist some extra metadata like the aggregate id or the date when the event has been raised. Then, those data will be used in the <code class="language-plaintext highlighter-rouge">Game</code> repository to persist changes in the database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span> \n <span class="c1">// …</span>\n <span class="k">public</span> <span class="nx">toState</span><span class="p">():</span> <span class="p">[[</span><span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">]]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">event</span><span class="p">:</span> <span class="nx">Event</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="dl">'</span><span class="s1">Game</span><span class="dl">'</span><span class="p">,</span> <span class="nx">event</span><span class="p">.</span><span class="nx">toState</span><span class="p">()]);</span>\n <span class="p">}</span>\n <span class="c1">// …</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Last thing, we will add a named constructor to be able to build the object from the persisted state (a list of events). The <code class="language-plaintext highlighter-rouge">fromEvents</code> will iterate on all events to compute and set the current state of a game.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span> \n <span class="c1">// …</span>\n <span class="k">public</span> <span class="k">static</span> <span class="nx">fromEvents</span><span class="p">(</span><span class="nx">events</span><span class="p">:</span> <span class="nx">Event</span><span class="p">[]):</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">let</span> <span class="nx">redTeam</span><span class="p">,</span> <span class="nx">blueTeam</span><span class="p">,</span> <span class="nx">score</span><span class="p">;</span>\n <span class="nx">events</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">event</span><span class="p">:</span> <span class="nx">Event</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">switch</span> <span class="p">(</span><span class="kc">true</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">case</span> <span class="nx">event</span> <span class="k">instanceof</span> <span class="na">GameStarted</span><span class="p">:</span>\n <span class="nx">redTeam</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">;</span>\n <span class="nx">blueTeam</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">;</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="k">case</span> <span class="nx">event</span> <span class="k">instanceof</span> <span class="na">GameEnded</span><span class="p">:</span>\n <span class="nx">score</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">score</span><span class="p">;</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="p">});</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span><span class="nx">redTeam</span><span class="p">,</span> <span class="nx">blueTeam</span><span class="p">,</span> <span class="nx">score</span><span class="p">,</span> <span class="nx">events</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="c1">// …</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, we have all the data we need to know if Popeye really helps his teammate. In the following code example, we can see that Momos and arn0 were not in a good shape. Coco and Popeye won easily but we can see that Popeye did not score. Perhaps, he is a good defender, who knows?</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">game</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">startTwoVersusTwo</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Popeye</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n</code></pre></div></div>\n\n<p>I explained to you how to save <code class="language-plaintext highlighter-rouge">Game</code> aggregate events and create the aggregate from events in the previous sections of the blog post. The last missing feature is the leaderboard! How to create it? It won’t be as simple as querying a SQL table in the database because we need to get all game events for each game and compute them to know who is the better striker. Even though it can be fast in the beginning, the more games you have, the longer it will be.</p>\n\n<p>To prevent this problem, we need to create data projections. That means we will compute a representation of the data we want to query from the event stream. We will compute the new projection of the leaderboard each time a game ends.</p>\n\n<p>Last but not least, We often associate CQRS with the event sourcing pattern even if there are two different patterns.</p>\n\n<p>Don’t forget that a complete example is available on a Github repository.</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="https://github.com/arnolanglade/table-soccer">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/github-logo.webp" alt="Have a look at the GitHub repository" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Have a look at the GitHub repository</span>\n </span>\n </a>\n</div>\n\n<p>Any resemblance to real and actual names is purely coincidental!</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 28 Nov 2022 00:00:00 -0600\n https://arnolanglade.github.io/what-is-the-event-sourcing-pattern.html?s=feed\n https://arnolanglade.github.io/what-is-the-event-sourcing-pattern.html\n \n software-architecture\n \n \n \n \n \n My feedback about example mapping\n <p>Example mapping is a workshop that gathers tech and non-tech people to ensure everyone has the same understanding of the domain problem. It also helps clarify the acceptance criteria for a given story. Because it’s always better to understand what is expected and raise all bottlenecks before developing a story.</p>\n\n<p>Disclaimer! I won’t explain how to run such a workshop, you can easily find a bunch of articles on the web. You can also have a look at <a href="/agile-tour-rennes-example-mapping.html">these slides</a>, they come from one of my talks about example mapping if you’re not familiar with it. In this blog article, I want to share with you my experience on Example Mapping and how it helps me to prepare and organize the team’s work.</p>\n\n<p><strong>Caution:</strong> A little while ago, I got feedback from <a href="https://twitter.com/brunoboucard">Bruno Boucard</a> about using sticky notes. He advised me to use index cards instead of sticky notes. The workshop attendees can put them on a table and easily move them, unlike stick notes. I speak about sticky notes in this blog post because I only practiced this workshop remotely using tools like <a href="https://www.miro.com">Miro</a>.</p>\n\n<h2 id="who-will-attend-the-workshop">Who will attend the workshop?</h2>\n\n<p>The methodology recommends to involve at least the product managers, developers and testers. The goal of example mapping is that the product manager shares the problem with the person(s) who will solve it. I will go further, you can invite anyone who wants to understand what you are doing. It is a good way to share knowledge.</p>\n\n<p>During my last year at Akeneo, I worked on a new product called Shared Catalogs. All my teammates including devs, product manager, and engineering managers were newcomers. Even if they were really well onboarded on Akeneo’s products, they had a micro vision of what Akeneo PIM did, and the software’s functional perimeter was pretty huge. At this time, I was working at Akeneo for 4 years, andI had a good understanding of the product. During the example mapping sessions I shared as much knowledge as possible with my teammates, it helped the team to quickly improve their functional skills.</p>\n\n<h2 id="when-do-we-plan-it">When do we plan it?</h2>\n\n<p>From my experience, a 30-minute slot is a good tradeoff. It’s not too long and you can easily illustrate the main business rules of the story and detect all bottlenecks. With a 30-minute meeting, you’re sure that your teammates will stay focused, especially when you work remotely. Having regular and short workshops is better than doing a big and long one.</p>\n\n<p>Depending on their roles, some team members can be really busy. For instance, I worked with several PMs who were often in meetings and it was really hard to catch them. To be sure that everyone can be available, each team member booked a 30 minutes slot after the daily meeting. Doing an example mapping was not mandatory, we only did the workshop if we needed to prepare stories.</p>\n\n<h2 id="how-organize-the-team">How organize the team</h2>\n\n<p>The attendees can have different roles: onek person writes sticky notes, another animates the workshop and the others ask questions and drive the person who writes sticky notes. I think it is important to switch his/her role each session to keep everyone involved during the workshop.</p>\n\n<p>I worked with some product managers and domain experts who wanted to contribute and write sticky notes. It is not a good idea because they should focus on sharing the knowledge and let the rest of the team grasp the business expectations. You won’t help someone if you do his/her job.</p>\n\n<h2 id="how-to-start">How to start</h2>\n\n<p>Writing the title of a story on a yellow sticky note is pretty simple but I sometimes had difficulties getting the business rules and the examples listed. Especially, when you are doing this workshop with a team for the first time. I found out that it was easier to sometimes start by writing the example first or sometimes by writing the business rules first.</p>\n\n<p>First option: start by writing the business rules and then write the examples if your team is comfortable with the exercise and your product manager has a clear vision of what is expected.</p>\n\n<p>Second option: start by writing examples and then extract business rules from examples if your team is not comfortable with the workshop or if your product manager needs to explore a topic and he/she waits for your feedback. It will let you and your teammates speak, and understand what is going on. When you have enough examples and your understanding of business is better you can extract the business rules.</p>\n\n<p>Don’t be afraid if it is a bit complicated to be efficient in the beginning. One day, my teammates and I prepared a story about exporting a CSV file, quite simple, right? We only needed to “take data from the DB and build a file” but it wasn’t that simple! We turned this “simple” story into at least 15 stories. We discovered a lot of “hidden” business rules. We thought it was a story but it was an epic…</p>\n\n<h2 id="how-to-write-example">How to write example</h2>\n\n<p>Don’t try to write gherkins scenarios at all costs because it can be time-consuming. The goal of this workshop is to ensure all teammates grasp what the business expects and it is the right time to raise all problems and incomprehension.</p>\n\n<p>The simplest format I used to define the example looked like the Given / When / Then but a really simplified version.</p>\n\n<p><img src="images/posts/example-mapping/write-simple-exmaple.webp" alt="Simplified gherkins" /></p>\n\n<p>Sometimes it can be more readable to draw something.</p>\n\n<p><img src="images/posts/example-mapping/draw-example.webp" alt="Draw examples" /></p>\n\n<p>Don’t limit yourself, if you prefer another format, use it. The most important thing is that everyone understands what is expected.</p>\n\n<h2 id="dont-forget-red-sticky-notes">Don’t forget red sticky notes</h2>\n\n<p>Avoid endless debates! Don’t hesitate to use red sticky notes if your teammates disagree on something. Keep in mind that your product manager can’t answer all questions during the workshops. It’s normal, the product manager is not a super(wo)man! Thus, add a red sticky note and take time to think about it, he/she’ll answer all questions in the next session.</p>\n\n<h2 id="have-small-stories">Have small stories</h2>\n\n<p>I like to talk with the PM when the story is ready to be developed (when there are no more red stickies and when all teammates are OK with it). I usually challenge him/her to know which business rules are really mandatory and which ones are nice-to-have. It ensures your stories are really small and it eases the prioritization. You can focus on what is really important and keep what is nice-to-have for later.</p>\n\n<p><strong>Tip:</strong> If your story has too many business rules, it’s a smell! That means you should split it into small ones. It will be easier to ship several small stories than a big one. If a business rule has too many examples, that’s a smell too. You might have missed some business rules.</p>\n\n<p><img src="images/posts/example-mapping/split-story.webp" alt="Split story into small ones" /></p>\n\n<p>I am not a big fan of estimates, it’s a waste of time. We should focus on understanding the problem we want to solve, instead of giving figures that will probably be wrong. Having a really small story will help you to be more predictive. You can count the stories done during a time frame and easily forecast what your team will be able to do during the next iteration.</p>\n\n<h2 id="final-thoughts">Final thoughts</h2>\n\n<p>The first example mapping workshop can be complex but don’t give up. The more you practice, the more comfortable your team will be with the workshop. Example mapping is a good way to align the team’s understanding with the stakeholders expectations. It will help your team to better collaborate and break all silos between all kinds of positions in your team. Last but not least, it will help you refine your stories and improve your backlog prioritization.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 31 Oct 2022 00:00:00 -0500\n https://arnolanglade.github.io/my-feedback-about-example-mapping.html?s=feed\n https://arnolanglade.github.io/my-feedback-about-example-mapping.html\n \n BDD\n \n methodology\n \n \n \n \n \n How I have learned programming by myself\n <p>I am, what we call, a self-taught. I studied telecommunications and networks at school, unfortunately, I only learned the basics of programming. I had to learn and improve my skills by myself for many years during my free time. I did not take the easiest path to learn! That’s why I wanted to share with you my own experience and what I did to learn software development. I hope this post will help some of you.</p>\n\n<h2 id="find-a-mentor">Find a mentor</h2>\n\n<p>In the beginning, even though I knew some basics of programming I was a bit lost. I wasn’t able to build an application end to end and I did not know which subject I had to study to solve that. That’s why I advise junior engineers to find at least one mentor. A mentor can teach you what is important like how to test, design patterns, software architecture, and so on. A mentor will help you focus on the right topics like how to build robust applications instead of focusing on hype technologies.</p>\n\n<p><strong>Tip:</strong> If you’re a junior, I would recommend you focus on testing: TDD will help you to design your code step by step. Architectural patterns like hexagonal architecture will help you to decouple your code from IO. Agile: eXtreme programming will help you to reduce the cost of changes by having multiple short development cycles rather than a long one.</p>\n\n<h2 id="play-and-have-fun-with-a-side-project">Play and have fun with a side project</h2>\n\n<p>You can have strong constraints at work, so it can be really hard to try new things because of bad processes, bad code quality, impossible deadlines etc. I have worked on several side projects for the last 10 years. I tried twice to release an application for a French NGO to manage their volunteer data. Then I tried to make an application to organize my trips. The last one is about making maps to remember places I have been. I learned a lot from those projects, they let me try what I read in blog posts, books or what I saw in conferences without any pressure of production. The funny thing is that I learned more from failures. Only my last side project <a href="https://mymaps.world">“mymaps”</a> is live, I did not release the other ones! This is because they were only playgrounds rather than real projects. They helped me understand why being pragmatic is important, focusing only on technical aspects does not help to build an application. Keep in mind that a good codebase is not the only thing you need to make a successful project.</p>\n\n<h2 id="contribute-to-an-open-source-project">Contribute to an open-source project</h2>\n\n<p>I worked on <a href="https://sylius.com">Sylius</a> which is an open-source e-commerce framework. The community of Sylius is great. I learned a lot of good practices like testing, code review and behaviour-driven development for instance. I mainly worked on the <code class="language-plaintext highlighter-rouge">SyliusResourceBundle</code> which is a library that eases CRUD management. During this period, I was working for a web agency, it helped me to be more efficient at work and ship projects faster.</p>\n\n<p><strong>Caution:</strong> Many companies use open-source projects but they don’t contribute to them. I was happy to contribute to this project during my free time, but you should negotiate allocated time with your company to help those projects if they help you deliver value to your customers.</p>\n\n<p>I would like to thank <a href="https://pjedrzejewski.com">Pawel</a> for making me a core team member. Contributing to Sylius has opened many doors to me.</p>\n\n<p>Thanks to what I have done in that library, I had the chance to do my first conference (<a href="https://live.symfony.com/2015-paris">Symfony live</a>) as a speaker. That was so great! I was so excited and terrified at the same time. Then I got hired by a french startup <a href="https://www.akeneo.com/">Akeneo</a> to work on an open-source PIM (Product Information Management). I only worked for service companies before Akeneo, this experience made me discover what was software edition.</p>\n\n<h2 id="attend-conferences-and-meetups">Attend conferences and meetups</h2>\n\n<p>Attending conferences is a great way to learn and open your mind to new things. You can have a chat with other attendees during breaks as well. It is a good way to meet new people and to have interesting talks. One of my favourite conferences is <a href="http://www.ncrafts.io">newcraft</a>, its local edition at <a href="https://bordeaux.ncrafts.io/">Bordeaux</a> was really great too.</p>\n\n<p>When you will be comfortable the next step will be to do a presentation. Preparing a talk is good to dive into the topic you will present and formalize your ideas. Even if you know this topic, it may not be that easy to clearly explain it to someone else. Don’t be shy, submit your talks! A lot of conference organizations help new speakers. I did not think too much when I submitted my first talk. I thought it wouldn’t be selected but I received an email that said my talk was accepted. I was so happy and excited! I realized what happened and I really started to panic (true story, a little panic attack) so I started to work on my talk to be ready for D-day. You can have a look at <a href="http://arnolanglade.github.io/talks.html">my talks</a>.</p>\n\n<h2 id="read-books">Read books</h2>\n\n<p>Another way to learn is through books. This is a good way to shut down your computer while still learning new things about software engineering.</p>\n\n<p><strong>Tip:</strong> Some books in my library: <a href="https://www.oreilly.com/library/view/accelerate/9781457191435/">Accelerate</a>, <a href="https://www.oreilly.com/library/view/extreme-programming-explained/0201616416/">Extreme Programming Explained</a>, <a href="https://www.oreilly.com/library/view/domain-driven-design-distilled/9780134434964/">Domain-Driven Design Distilled</a>, <a href="https://www.oreilly.com/library/view/patterns-principles-and/9781118714706/">Patterns, Principles, and Practices of Domain-Driven Design</a>, <a href="https://www.yegor256.com/elegant-objects.html">Elegant Objects</a> and so on.</p>\n\n<h2 id="final-thoughts">Final thoughts</h2>\n\n<p>A few weeks ago, I saw some software engineers saying on social media that we should self-train in our free time. Learning in your free time will help you progress faster but it can be time and energy consuming. Don’t forget that burnouts are real. One of my friends experienced burnout and couldn’t do anything for almost a year, he was completely out of energy.</p>\n\n<p>I also had to take several breaks in my learning process to avoid going to the dark side of the force. <strong>Only do things when you want in your free time! Don’t put pressure on yourself!</strong> And keep in mind that learning should be fun!</p>\n\n<p>Learning is a part of your job. Companies should let you learn during business hours. On a day-to-day basis, pair and mob programming is a good way to learn and challenge your ideas. Your company should train you as well. For instance, <a href="https://matthiasnoback.nl">Mathias Noback</a> gave us some training when I was at Akeneo. I learned a lot from him, and I definitely recommend him!</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 17 Oct 2022 00:00:00 -0500\n https://arnolanglade.github.io/how-I-have-learned-programming-by-myself.html?s=feed\n https://arnolanglade.github.io/how-I-have-learned-programming-by-myself.html\n \n learning\n \n \n \n \n \n Increase your test quality thanks to builders or factories\n <p>In a previous <a href="http://arnolanglade.github.io/you-should-not-expose-objects-state-to-test-them.html">blog post</a>, I explained why it’s better to compare object instances instead of exposing their state to test them. This avoids breaking encapsulation and it does not have any impact on their design.</p>\n\n<p>Let’s take an example! My side project allows me to create maps to remember places I have been. A map has a name and, as a cartographer, I am allowed to rename it. Real basic use case but more than enough! The following test ensures I can rename this map:</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="s1">'Pepito'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="s1">'Bordeaux city'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="s1">'Good places in Anglet'</span><span class="p">),</span>\n <span class="nc">Tag</span><span class="o">::</span><span class="nf">city</span><span class="p">(),</span>\n <span class="nc">MarkerList</span><span class="o">::</span><span class="nb">empty</span><span class="p">(),</span>\n<span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">);</span>\n\n<span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span>\n <span class="nv">$map</span><span class="p">,</span>\n <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="s1">'Pepito'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="s1">'Good places in Anglet'</span><span class="p">),</span>\n <span class="nc">Tag</span><span class="o">::</span><span class="nf">city</span><span class="p">(),</span>\n <span class="nc">MarkerList</span><span class="o">::</span><span class="nb">empty</span><span class="p">(),</span>\n <span class="p">)</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p>We can see that comparing object instances is great for encapsulation because we don’t expose the object’s state but this makes the test less readable. Here, the only thing we want to focus on is the value of <code class="language-plaintext highlighter-rouge">MapName</code>. The values of the other value object are only noise because they are not useful for this test. But, this is not the only drawback of this test. What happens if you want to add an extra property to the <code class="language-plaintext highlighter-rouge">Map</code> object? In this case, we will need to refactor all the tests that create a map object. It might be easily doable in small projects but it can become messy for big ones.</p>\n\n<p>Now, let’s show how we can improve this test. The title of my blogpost can give you a huge hint on the solution. We will add a named constructor called <code class="language-plaintext highlighter-rouge">whatever</code> to the <code class="language-plaintext highlighter-rouge">Map</code> object to centralize the object construction. Named constructors are static factories that build the object itself.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Map</span> \n<span class="p">{</span>\n <span class="cd">/** @internal */</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">whatever</span><span class="p">(</span>\n <span class="kt">string</span> <span class="nv">$mapId</span> <span class="o">=</span> <span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$addedBy</span> <span class="o">=</span> <span class="s1">'Pepito'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$name</span> <span class="o">=</span> <span class="s1">'Anglet city'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$description</span> <span class="o">=</span> <span class="s1">'Good places in Anglet'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$tag</span> <span class="o">=</span> <span class="s1">'city'</span><span class="p">,</span>\n <span class="kt">array</span> <span class="nv">$markers</span> <span class="o">=</span> <span class="p">[],</span>\n <span class="p">):</span> <span class="kt">self</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="nv">$mapId</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$addedBy</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$name</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="nv">$description</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Tag</span><span class="p">(</span><span class="nv">$tag</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MarkerList</span><span class="p">(</span><span class="nv">$markers</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> I like to add a <code class="language-plaintext highlighter-rouge">@internal</code> annotation to remind all teammates that the object constructor should only be used in tests.</p>\n\n<p>The value object instantiation is delegated to the <code class="language-plaintext highlighter-rouge">whatever</code> constructor. I try to use primitive data types like arguments as much as possible, it makes me write less code and it’s easier to read. All constructor arguments have a default value, then I can override a given value depending on the needs thanks to the named argument feature.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">whatever</span><span class="p">(</span><span class="n">name</span><span class="o">:</span> <span class="s1">'Bordeaux city'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">);</span>\n\n<span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span>\n <span class="nv">$map</span><span class="p">,</span>\n <span class="nc">Map</span><span class="o">::</span><span class="nf">whatever</span><span class="p">(</span><span class="n">name</span><span class="o">:</span> <span class="s1">'Anglet city'</span><span class="p">)</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p>Now, the test is clear and focuses on the right thing. Everyone can easily understand it, and it will help your teammates to grasp the code you wrote. Refactoring will be simplified as you only have to rewrite the <code class="language-plaintext highlighter-rouge">whatever</code> constructor if the signature of the primary constructor of <code class="language-plaintext highlighter-rouge">Map</code> changes.</p>\n\n<p>I know that some people won’t like the idea of adding a method to objects only for testing purposes. If you don’t like that, you can replace this static factory with a builder.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MapBuilder</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$mapId</span> <span class="o">=</span> <span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$addedBy</span> <span class="o">=</span> <span class="s1">'Pepito'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$name</span> <span class="o">=</span> <span class="s1">'Anglet city'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$description</span> <span class="o">=</span> <span class="s1">'Good places in Anglet'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$tag</span> <span class="o">=</span> <span class="s1">'city'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">array</span> <span class="nv">$markers</span> <span class="o">=</span> <span class="p">[];</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">identifiedBy</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span> <span class="o">=</span> <span class="nv">$mapId</span><span class="p">;</span>\n \n <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">named</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$name</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>\n\n <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="c1">// ... other setters ....</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">build</span><span class="p">():</span> <span class="kt">Map</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">addedBy</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">description</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Tag</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">tag</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MarkerList</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markers</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then your test will look like this:</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="p">(</span><span class="k">new</span> <span class="nc">MapBuilder</span><span class="p">())</span><span class="o">-&gt;</span><span class="nf">named</span><span class="p">(</span><span class="s1">'Bordeaux city'</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">();</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">);</span>\n\n<span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span>\n <span class="nv">$map</span><span class="p">,</span>\n <span class="p">(</span><span class="k">new</span> <span class="nc">MapBuilder</span><span class="p">())</span><span class="o">-&gt;</span><span class="nf">named</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">()</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> Read or anemic models don’t have logic to ensure they are built in a good way. If you use this method for them you can add some logic to your builder/factories to ensure they are created with consistent data. It will make your tests stronger.</p>\n\n<h2 id="final-thought">Final thought</h2>\n\n<p>Builders or factories ease test refactoring and make tests more readable. Don’t forget that bad test suites are a nightmare to maintain and can drastically slow down your delivery. Taking care of your test quality will help you to ship fast. Moreover, good tests are free documentation.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 10 Oct 2022 00:00:00 -0500\n https://arnolanglade.github.io/increase-your-test-quality-thanks-to-builders-or-factories.html?s=feed\n https://arnolanglade.github.io/increase-your-test-quality-thanks-to-builders-or-factories.html\n \n testing\n \n \n \n \n \n How to handle user permissions through command bus middleware\n <p>Applying user permissions might be very complex and can lead to introducing a lot of accidental complexity to your application. In this blog post, I want to share with you how to do it by simply adding a middleware to your command bus.</p>\n\n<p><strong>Note:</strong> If you’re not familiar with this pattern, please have a look at this <a href="http://arnolanglade.github.io/command-bus-design-pattern.html">blog post</a>, it explains what a command bus and a middleware are.</p>\n\n<p>Let’s imagine a basic use case: an application with two kinds of users: regular ones and admins. We want to allow certain actions only to admin users.</p>\n\n<p>First, I will introduce an interface <code class="language-plaintext highlighter-rouge">OnlyPerformedByAdministrator</code> that will be implemented by the command restricted to the admin users.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">interface</span> <span class="nc">OnlyPerformedByAdministrator</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">username</span><span class="p">():</span> <span class="kt">string</span><span class="p">;</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">CreateNewProduct</span> <span class="kd">implements</span> <span class="nc">OnlyPerformedByAdministrator</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">username</span><span class="p">():</span> <span class="kt">string</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then, we will add a <code class="language-plaintext highlighter-rouge">CheckAccessPermission</code> middleware to the command bus that will check if the user can execute an action. If he/she can’t, an <code class="language-plaintext highlighter-rouge">AccessDenied</code> exception will be thrown. It will be caught later in the execution flow to be turned into something that will be understandable to the user.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">AccessDenied</span> <span class="k">extends</span> <span class="err">\\</span><span class="nc">Exception</span>\n<span class="p">{</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">CheckAccessPermission</span> <span class="kd">implements</span> <span class="nc">Middleware</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">private</span> <span class="nc">Users</span> <span class="nv">$users</span><span class="p">)</span> <span class="p">{}</span>\n\n <span class="k">final</span> <span class="k">public</span> <span class="k">function</span> <span class="n">handle</span><span class="p">(</span><span class="kt">Command</span> <span class="nv">$command</span><span class="p">,</span> <span class="kt">Middleware</span> <span class="nv">$next</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$user</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">users</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">username</span><span class="p">()));</span>\n <span class="k">if</span> <span class="p">(</span><span class="nv">$command</span> <span class="k">instanceof</span> <span class="nc">OnlyPerformedByAdministrator</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="nf">isAdmin</span><span class="p">())</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">AccessDenied</span><span class="p">();</span>\n <span class="p">}</span>\n\n <span class="nv">$next</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nv">$command</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>This middleware will stop the command processing if an error is raised. We need to catch this exception to return a 403 HTTP response in the web controller, or to return a status code greater than 0 in the CLI command.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">WebToggleCartographerPremiumStatus</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">private</span> <span class="nc">CommandBus</span> <span class="nv">$commandBus</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">Request</span> <span class="nv">$request</span><span class="p">):</span> <span class="kt">Response</span>\n <span class="p">{</span>\n <span class="k">try</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">commandBus</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="k">new</span> <span class="nc">CreateNewProduct</span><span class="p">(</span><span class="cd">/** ... */</span><span class="p">));</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">AccessDenied</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">Response</span><span class="p">(</span><span class="mi">403</span><span class="p">,</span> <span class="s1">'Access denied'</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">Response</span><span class="p">(</span><span class="mi">200</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h2 id="why-do-i-handle-permissions-with-a-middleware">Why do I handle permissions with a middleware?</h2>\n\n<p>I decided to add a middleware to the command bus because it ensures that permissions are checked no matter where commands are dispatched. For example: from the web controller or a CLI command. Moreover, I don’t depend on a security library or any framework configuration. All permission business rules are coded in the domain.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 26 Sep 2022 00:00:00 -0500\n https://arnolanglade.github.io/how-to-handle-user-permissions-through-command-bus-middleware.html?s=feed\n https://arnolanglade.github.io/how-to-handle-user-permissions-through-command-bus-middleware.html\n \n command-bus\n \n \n \n \n \n The command bus design pattern\n <p><strong>Note:</strong> Before reading this blog post, if you don’t know what a command and a command handler are, I advise you to first read the blog post I’ve written about those design patterns. It will help you to understand this new article:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-handler-patterns.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-handler/command-handler.webp" alt="Command and command handler design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Command and command handler design pattern</span>\n </span>\n </a>\n</div>\n\n<h2 id="what-is-a-bus">What is a bus?</h2>\n\n<p>Let’s start with the basics, what is a bus? In computer science, a bus is a system that connects several components and transfers data between them. In software, those components are called middleware. A middleware processes an incoming request and returns a response. As you can see in the schema below, the main advantage of a bus is that it is highly customizable as you can add as many middleware as you want.</p>\n\n<p><img src="images/posts/command-bus/bus.svg" alt="A bus" /></p>\n\n<p>In the next sections, we will speak about the command bus which is often associated with an event bus. Using an event bus is not mandatory but we will see how it will make your application more modular and evolutive. Their goal is to deliver a command or an event to their handler(s). Events and commands are objects used to encapsulate information needed to achieve an action (a command) or to tell what happened in the system (an event).</p>\n\n<h2 id="the-command-bus">The command bus</h2>\n\n<p><strong>Quick reminder about command and command handler:</strong> A command represents a user’s intent. The data carried by the command has to be valid. It can be only handled by only one handler that is just a callable that will perform the user action.</p>\n\n<p>Now, we will build a command bus following the same architecture that I described in the previous section. The only difference is that the command bus will return void. As commands canmight be handled asynchronously, we don’t want to wait for the result of the command processing.</p>\n\n<p><img src="images/posts/command-bus/command-bus.svg" alt="A command bus" /></p>\n\n<p>Let’s see the most common middleware used to build a command bus. The first one is probably the “logging middleware”. It helps to make your application observable and it is really useful for bug hunting. Then the “validation middleware” ensures that the command is valid before giving it to the handler. Its purpose is to stop the command processing if data is invalid. It is pretty convenient because it avoids validating them manually. When your application uses a database, the “transaction middleware” wraps the handler execution into a SQL transaction. It makes sure all database changes are done, otherwise it rollbacks the transaction. Finally, the last middleware is responsible for finding and executing the handler that matches the command.</p>\n\n<h2 id="the-event-bus">The event bus</h2>\n\n<p>An event represents something that happened in the application. Unlike a command, an event can be handled by several handlers. Listening to events allows us to enhance existing features or add new ones very quickly. Several teams can listen to the same event to perform additional tasks depending on business needs. It makes applications more evolutive without adding accidental complexity and lets your team work isolated from each other.</p>\n\n<p><strong>Tip:</strong> I would like to encourage you to mainly use business-oriented events instead of technical ones. They clearly describe what happened from a business point of view. For example, <code class="language-plaintext highlighter-rouge">NewAccountHasBeenCreated</code> is more understandable than <code class="language-plaintext highlighter-rouge">ResourceCreated</code> with a resource property equal to ‘Account’</p>\n\n<p>Even if the event bus is built the same way as the command bus we don’t need all the different middleware. We don’t need the validation middleware because events are generated by the aggregates with value objects. Those objects ensure domain invariant which means they are always valid. We also don’t need the transactional middleware because the event will be processed into the transaction begun during the command processing. Moreover, depending on your business needs you may not want to process events into this transaction. Let’s take a simple example. After creating an account, an event <code class="language-plaintext highlighter-rouge">AccountCreated</code> is dispatched, then a welcome email is sent during <code class="language-plaintext highlighter-rouge">AccountCreated</code> processing. If the email sending fails, do we want to roll back the account creation? Not sure! In that case, you need to speak with your product manager to decide how to process this event.</p>\n\n<p>As I said previously, events are recorded by aggregates and they should be business oriented. I will share with you two ways to dispatch events into the event bus.</p>\n\n<p><img src="images/posts/command-bus/event-bus.svg" alt="A event bus" /></p>\n\n<p><strong>Solution 1:</strong> You can collect them from your repository if no errors have been raised during the aggregate persisting and then dispatch them.</p>\n\n<p><strong>Solution 2:</strong> The other solution is to collect events from the command handler. The handler can return them, and then the “handle command” middleware catches and dispatches them.</p>\n\n<p><strong>Note:</strong> My previous <a href="http://arnolanglade.github.io/command-handler-patterns.html">blog post</a> about the command and command handler pattern said that a command handler should return void. Here, the idea is that the command bus should return void only the “handle command” should be aware of the result of the handler execution.</p>\n\n<p>I’ve written a bunch of articles about how to handle a command, validate its data, handle user permissions, and so on. Take a look at these articles:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/tag/command-bus">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/data-validation.webp" alt="See all blog posts about command handling." />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">See all blog posts about command handling.</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 12 Sep 2022 00:00:00 -0500\n https://arnolanglade.github.io/command-bus-design-pattern.html?s=feed\n https://arnolanglade.github.io/command-bus-design-pattern.html\n \n command-bus\n \n design-patterns\n \n \n \n \n \n Objective: set up your projects more easily\n <p>For the last decade I worked on several more or less complex projects. I often had problems with their installation. Sometimes, the project was not documented or the existing documentation was not up to date. I had to run commands but I did not understand all of them. When I got errors it was hard to understand what happened. That was not always simple.</p>\n\n<p>During my last projects, I used makefile to provide an abstraction to simplify their installation and hide complexity. It let me install projects with a single command and provided a minimal set of targets which made my daily work easier.</p>\n\n<h2 id="how-does-makefile-work">How does makefile work?</h2>\n\n<p>A makefile is a set of “rules” that looks like:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>target: prerequisites prerequisites\n recipe\n recipe\n ...\n</code></pre></div></div>\n\n<p>A <strong>target</strong> is the name of a file (or a folder) that is generated by <code class="language-plaintext highlighter-rouge">make</code>. It could also be the name of an action to perform but you need to declare it as PHONY.</p>\n\n<p>A <strong>prerequisite</strong> are the files (or folders) needed to create the target, you can see them as target dependencies.</p>\n\n<p>A <strong>recipe</strong> are all actions executed when the target is run. <strong>Caution:</strong> you need to indent all recipes using a “real” tab character otherwise you will get errors.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.env:\n <span class="nb">cp</span> .env.dist .env\n</code></pre></div></div>\n\n<p>If the <code class="language-plaintext highlighter-rouge">.env</code> file does not exist, the recipe will be carried out, but if it does exist the recipe won’t be executed #magic.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: cache\ncache: .env\n bin/console c:c\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">cache</code> target does not target a file. Declaring this target as PHONY allows having a file named <code class="language-plaintext highlighter-rouge">cache</code> in the same directory as the Makefile.</p>\n\n<p><strong>Note:</strong> If the <code class="language-plaintext highlighter-rouge">.env</code> file does not exist the <code class="language-plaintext highlighter-rouge">.env</code> target will be performed before the <code class="language-plaintext highlighter-rouge">cache</code> target.</p>\n\n<h2 id="lets-take-an-example">Let’s take an example</h2>\n\n<p>For instance, a project orchestrated by docker-compose having:</p>\n<ul>\n <li>a front application written in JS using React framework,</li>\n <li>a back application written in PHP using Symfony framework,</li>\n <li>a PostgreSQL database managed by Doctrine DBAL and Doctrine migration</li>\n</ul>\n\n<p><strong>Caution:</strong> I will only speak about projects setup for dev purposes. I won’t talk about making docker images ready for production.</p>\n\n<p>Let’s start installing the project dependencies. The following targets install project dependencies if they have not been downloaded yet. They can guess if they are outdated to upgrade them thanks to target prerequisites. Another interesting thing is that nothing will be done if dependencies are already installed and up to date.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Front</span>\nweb/yarn.lock: web/package.json\n docker-compose run <span class="nt">--rm</span> node yarn <span class="nb">install\n\n</span>web/node_modules: web/yarn.lock\n docker-compose run <span class="nt">--rm</span> node yarn <span class="nb">install</span> <span class="nt">--frozen-lockfile</span>\n docker-compose run <span class="nt">--rm</span> node yarn check <span class="nt">--integrity</span>\n\n<span class="c"># back</span>\napi/composer.lock: api/composer.json\n docker-compose run <span class="nt">--rm</span> fpm composer update\n\napi/vendor: api/composer.lock\n docker-compose run <span class="nt">--rm</span> fpm composer <span class="nb">install</span>\n\n</code></pre></div></div>\n\n<p>Then, we need to “up” all docker-compose services: the web server, the PHP process manager, the datatable, and the node to run the front application in development mode.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: up\nup:\n docker-compose up <span class="nt">-d</span>\n</code></pre></div></div>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker-compose ps \n Name Command State Ports \n<span class="nt">---------------------------------------------------------------------------------------------------------------------------------------------</span> \nmy-maps-node docker-entrypoint.sh yarn ... Up \nmy-maps-web nginx <span class="nt">-g</span> daemon off<span class="p">;</span> Up 80/tcp \nmy-maps_database_1 docker-entrypoint.sh postgres Up 5432/tcp \nmy-maps_fpm_1 php-fpm <span class="nt">-F</span> Up \n</code></pre></div></div>\n\n<p>The last thing to do is to create the database schema using Doctrine migration.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: db-migration\ndb-migration: api/vendor\n docker-compose run <span class="nt">--rm</span> fpm bin/console doctrine:migrations:migrate <span class="nt">--no-interaction</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> To ease my daily work, I like introducing other targets like <code class="language-plaintext highlighter-rouge">db</code> target that resets database quickly or <code class="language-plaintext highlighter-rouge">fixture</code> to load some data fixtures.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: db\ndb: api/vendor\n docker-compose run <span class="nt">--rm</span> fpm bin/console doctrine:database:drop <span class="nt">--force</span> <span class="nt">--no-interaction</span>\n docker-compose run <span class="nt">--rm</span> fpm bin/console doctrine:database:create <span class="nt">--no-interaction</span>\n\n.PHONY: fixtures\nfixtures: api/vendor\n docker-compose run <span class="nt">--rm</span> fpm bin/console project:fixtures:load\n</code></pre></div></div>\n\n<p>Now, we have all atomic targets to set up all parts of the application. Another interesting thing with make, is that it can run several targets within a single command <code class="language-plaintext highlighter-rouge">make up api/vendor web/node_modules</code>.This is pretty useful to create scenarios. For instance, to set up and run the project I only need to run the following command:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>make up api/vendor web/node_modules db db-migration fixtures\n</code></pre></div></div>\n\n<p>But it works with everything:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>make db db-migration fixtures\nmake api/vendor web/node_modules\n</code></pre></div></div>\n\n<p>To make your day-to-day basis, you can introduce targets that run those scenarios.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># It builds and runs the application</span>\n.PHONY: app-dev\napp-dev: up api/vendor web/node_modules db db-migration fixtures\n\n<span class="c"># It resets the database</span>\n.PHONY: db-reset\ndb-reset: db db-migration fixtures\n\n<span class="c"># It resets the database</span>\n.PHONY: dependencies\ndependencies: api/vendor web/node_modules\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> I advise you to introduce the minimum set of targets into the makefile. Keep it simple! Don’t forget that everyone uses it! To let developers have their custom targets you may want to include custom makefiles using <a href="https://www.gnu.org/software/make/manual/html_node/Include.html">include</a>. Don’t forget to add an entry into <code class="language-plaintext highlighter-rouge">.ignore</code> to avoid committing those files. Now, developers can create their own makefile with their personal targets.</p>\n\n<h2 id="one-last-word">One last word</h2>\n\n<p>Makefile is only a solution, this is not THE solution. The important thing to keep in mind is that you should be able to easily run your project to reduce the developer’s mental load and let them focus on the right thing. It will improve the day-to-day basis and make newcomers’ onboarding easier.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Wed, 02 Jun 2021 00:00:00 -0500\n https://arnolanglade.github.io/objective-set-up-your-projects-more-easily.html?s=feed\n https://arnolanglade.github.io/objective-set-up-your-projects-more-easily.html\n \n makefile\n \n \n \n \n \n Why unit testing can be hard?\n <blockquote>\n <p>Unit tests are typically automated tests written and run by software developers to ensure that a section of an application (known as the “unit”) meets its design and behaves as intended</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Unit_testing">Wikipedia</a></p>\n</blockquote>\n\n<p>I remember when I started to test my code it was really hard! It was mainly because I misunderstood some basics like what testing was about and the need of well-designed code. Unit tests ensure your code works as expected, but we often forget that unit testing is also the simplest way to have quick feedback during development phase.</p>\n\n<p>In this blog post, I will share what I learned to easily unit test my codebases.</p>\n\n<h2 id="test-your-public-methods">Test your public methods</h2>\n\n<p>Objects should be seen as black boxes. Public methods are the only way to interact with objects, while private and protected methods are implementation details. We should not pay attention to how objects work internally. That’s why we don’t test private and protected methods. If you need to test them, that’s a design smell! Your objects might do too many things and they probably do not respect the <strong>S</strong>ingle <strong>R</strong>esponsibility <strong>P</strong>rinciple.</p>\n\n<blockquote>\n <p>The single-responsibility principle (SRP) is a computer-programming principle that states that every class in a computer program should have responsibility over a single part of that program’s functionality, which it should encapsulate.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Single-responsibility_principle">Wikipedia</a></p>\n</blockquote>\n\n<p>Actually, it is better to have several small objects solving simple problems instead of having god objects that are doing everything the wrong way. If your objects become too big, split them into smaller ones because they are easier to maintain and to test.</p>\n\n<h2 id="do-not-unit-test-code-that-uses-ios">Do not unit test code that uses IOs</h2>\n\n<blockquote>\n <p>Input/output (I/O, or informally io or IO) is the communication between an information processing system, such as a computer, and the outside world, possibly a human or another information processing system.</p>\n\n <p><a href="https://press.rebus.community/programmingfundamentals/chapter/input-and-output/">Wikipedia</a></p>\n</blockquote>\n\n<p>For example, IO are side effects like: network calls, database queries, filesystem operations, actual timestamps or randomness.</p>\n\n<h3 id="do-not-deal-with-the-outside">Do not deal with the outside</h3>\n\n<p>The code covered by unit tests should not depend on the outside world like databases, external services and so on. Unit tests should not require any application setup, they have to remain as simple as possible. Their goal is to give you quick feedback by checking that a small piece of code (a unit) matches a business expectation. If you want to be sure that all application parts are well integrated with the outside world, you have to use an integration test.</p>\n\n<p>The following example shows a piece of code that depends on the external service. Here, we can’t build the <code class="language-plaintext highlighter-rouge">Map</code> object without a working database.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HandleMarkerAddition</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nv">$connection</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">AddMarkerToMap</span> <span class="nv">$command</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$mapState</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="s1">'SELECT ... FROM ...'</span><span class="p">,</span> <span class="p">[</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">mapId</span><span class="p">()]);</span>\n\n <span class="nv">$map</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">fromState</span><span class="p">(</span><span class="nv">$mapState</span><span class="p">);</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">name</span><span class="p">(),</span> <span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">location</span><span class="p">());</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="s1">'INSERT INTO ...'</span><span class="p">,</span> <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">toState</span><span class="p">()]);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The goal of this piece of code is to add a marker to a <code class="language-plaintext highlighter-rouge">Map</code> object, no matter how the object is stored. Tests that cover this class should focus on business use cases instead of technical details. A solution would be to use a repository design pattern to hide the map storage logic. The class will better follow the <strong>S</strong>ingle <strong>R</strong>esponsable <strong>P</strong>rinciple because it will only handle the marker addition use case whereas the map repository will be in charge of storing data.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HandleMarkerAddition</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Maps</span> <span class="nv">$maps</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Maps</span> <span class="nv">$maps</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">maps</span> <span class="o">=</span> <span class="nv">$maps</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">AddMarkerToMap</span> <span class="nv">$command</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$map</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">maps</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">mapId</span><span class="p">());</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">name</span><span class="p">(),</span> <span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">location</span><span class="p">());</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">maps</span><span class="o">-&gt;</span><span class="nf">add</span><span class="p">(</span><span class="nv">$map</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>With this new design, it is easier to test this class. Thanks to the <code class="language-plaintext highlighter-rouge">Maps</code> interface , we are able to simply create test doubles for the map repository.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// `PostgreSQLMaps` is the implementation used by default on the production</span>\n<span class="nv">$maps</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PostgreSQLMaps</span><span class="p">();</span>\n<span class="p">(</span><span class="k">new</span> <span class="nc">HandleMarkerAddition</span><span class="p">(</span><span class="nv">$postgreSQLMaps</span><span class="p">)(</span><span class="nv">$command</span><span class="p">);</span>\n\n<span class="c1">// `InMemoryMaps` is an implementation that keeps map objects in memory for testing </span>\n<span class="nv">$maps</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">InMemoryMaps</span><span class="p">();</span>\n<span class="p">(</span><span class="k">new</span> <span class="nc">HandleMarkerAddition</span><span class="p">(</span><span class="nv">$inMemoryMaps</span><span class="p">)(</span><span class="nv">$command</span><span class="p">);</span>\n\n<span class="c1">// In both cases we can retrieve the Map object from the repository to check the map has the new marker.</span>\n<span class="nv">$map</span> <span class="o">=</span> <span class="nv">$maps</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">mapId</span><span class="p">());</span>\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">hasSameState</span><span class="p">(</span><span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best place'</span><span class="p">,</span> <span class="k">new</span> <span class="nc">Marker</span><span class="p">(</span><span class="cm">/* … */</span><span class="p">)))</span> <span class="c1">// should return true;</span>\n\n</code></pre></div></div>\n\n<h3 id="do-not-deal-with-randomness">Do not deal with randomness</h3>\n\n<p>Randomness makes your code unpredictable. To simply test a piece of code you should be able to predict its result. To ease unit testing your code should avoid using randomness as much as possible.</p>\n\n<p>The following example shows a piece of code that uses randomness.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HashedPassword</span>\n<span class="p">{</span>\n <span class="c1">// ... </span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$hash</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">hash</span> <span class="o">=</span> <span class="nv">$hash</span><span class="p">;</span>\n <span class="p">}</span>\n\n\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">fromString</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$hash</span> <span class="o">=</span> <span class="err">\\</span><span class="nb">password_hash</span><span class="p">(</span><span class="nv">$password</span><span class="p">,</span> <span class="no">PASSWORD_BCRYPT</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span><span class="nv">$hash</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="c1">// ...</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">HashedPasswordTest</span> <span class="kd">extends</span> <span class="nc">TestCase</span>\n<span class="p">{</span>\n <span class="cd">/** @test */</span>\n <span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">builds</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="n">password</span><span class="err"> </span><span class="n">from</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="nf">string</span><span class="p">()</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">assertEquals</span><span class="p">(</span>\n <span class="nv">$this</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="s1">'Password1'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">HashedPassword</span><span class="p">(</span><span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span><span class="p">)</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>When we run <code class="language-plaintext highlighter-rouge">HashedPasswordTest</code> we get an error because the <code class="language-plaintext highlighter-rouge">password_hash</code> generates a random salt to hash the password. The problem is that the <code class="language-plaintext highlighter-rouge">password_hash</code> function cannot return the same hash for a given password. Each time you call this function a different hash will be returned.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">-Password</span> Object &amp;000000006e7168e60000000023b11bb2 <span class="o">(</span>\n- <span class="s1">'hash'</span> <span class="o">=&gt;</span> <span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span>\n+Password Object &amp;000000006e7168210000000023b11bb2 <span class="o">(</span>\n+ <span class="s1">'hash'</span> <span class="o">=&gt;</span> <span class="s1">'$2y$10$b/9GX4grnt4gH5cm8FzzSuUNGGQUiA/w.5HdKNEsW3dHtSUeTMXgK'</span>\n</code></pre></div></div>\n\n<p>The simplest solution would be to hardcode the salt to make sure the <code class="language-plaintext highlighter-rouge">hash_password</code> returns the same hash every time but this is not a good design. This would weaken the password generation because we need to test it. Another way would be to extract the hash generation in another place.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HashedPassword</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">fromString</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">,</span> <span class="kt">PasswordEncryptor</span> <span class="nv">$passwordEncryptor</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$hash</span> <span class="o">=</span> <span class="nv">$passwordEncryptor</span><span class="o">-&gt;</span><span class="nb">hash</span><span class="p">(</span><span class="nv">$password</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span><span class="nv">$hash</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">PasswordEncryptor</code> interface makes test doubles creation possible. Now, we just need to create a fake object to test this method.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">FakePasswordEncryptor</span> <span class="kd">implements</span> <span class="nc">PasswordEncryptor</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">hash</span><span class="p">():</span> <span class="kt">string</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span><span class="p">;</span>\n <span class="p">}</span>\n\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">HashedPasswordTest</span> <span class="kd">extends</span> <span class="nc">TestCase</span>\n<span class="p">{</span>\n <span class="cd">/** @test */</span>\n <span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">builds</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="n">password</span><span class="err"> </span><span class="n">from</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="nf">string</span><span class="p">()</span>\n <span class="p">{</span>\n <span class="nv">$fakePasswordEncryptor</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FakePasswordEncryptor</span><span class="p">();</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">assertEquals</span><span class="p">(</span>\n <span class="n">this</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="s1">'Password1'</span><span class="p">,</span> <span class="nv">$fakePasswordEncryptor</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">HashedPassword</span><span class="p">(</span><span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span><span class="p">)</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h3 id="avoid-actual-datetimes">Avoid actual datetimes</h3>\n\n<p>With actual datetimes, we have the same problem as with randomness, neither can be predicted.</p>\n\n<p>The following example shows you that actual datetimes are not predictable like <code class="language-plaintext highlighter-rouge">hash_password</code> in the previous section.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="err">\\</span><span class="nc">DateTimeImmutable</span> <span class="nv">$markerAddedAt</span> <span class="o">=</span> <span class="kc">null</span><span class="p">,</span> <span class="nc">Marker</span> <span class="mf">...</span><span class="nv">$makers</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">addMarker</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$name</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$location</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markerAddedAt</span> <span class="o">=</span> <span class="k">new</span> <span class="err">\\</span><span class="nf">DateTimeImmutable</span><span class="p">(</span><span class="s1">'now'</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">MapTest</span> <span class="kd">extends</span> <span class="nc">TestCase</span>\n<span class="p">{</span>\n <span class="cd">/** @test */</span>\n <span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">adds</span><span class="err"> </span><span class="n">marker</span><span class="err"> </span><span class="n">to</span><span class="err"> </span><span class="n">the</span><span class="err"> </span><span class="nf">map</span><span class="p">()</span>\n <span class="p">{</span>\n <span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Map name'</span><span class="p">);</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">,</span> <span class="p">[</span><span class="mf">47.21725</span><span class="p">,</span> <span class="o">-</span><span class="mf">1.55336</span><span class="p">]);</span>\n \n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">assetTrue</span><span class="p">(</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">hasSameState</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">Marker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">,</span> <span class="p">[</span><span class="mf">47.21725</span><span class="p">,</span> <span class="o">-</span><span class="mf">1.55336</span><span class="p">]),</span> \n <span class="k">new</span> <span class="err">\\</span><span class="nf">DateTimeImmutable</span><span class="p">(</span><span class="s1">'now'</span><span class="p">)</span>\n <span class="p">)</span>\n <span class="p">)</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>When we run <code class="language-plaintext highlighter-rouge">MapTest</code> we get an error because we can predict to the millisecond when the marker was added to the map.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">-Map</span> Object &amp;000000003acad975000000006b83e943 <span class="o">()</span>\n+Map Object &amp;000000003acad936000000006b83e943 <span class="o">(</span>\n+ <span class="s1">'markerAddedAt'</span> <span class="o">=&gt;</span> DateTimeImmutable Object &amp;000000003acad946000000006b83e943 <span class="o">(</span>\n+ <span class="s1">'date'</span> <span class="o">=&gt;</span> <span class="s1">'2021-04-18 17:36:02.919004'</span>\n+ <span class="s1">'timezone_type'</span> <span class="o">=&gt;</span> 3\n+ <span class="s1">'timezone'</span> <span class="o">=&gt;</span> <span class="s1">'UTC'</span>\n+ <span class="o">)</span>\n+<span class="o">)</span>\n</code></pre></div></div>\n\n<p>To prevent this kind of problem, a good idea is to abstract time by introducing an interface that is responsible for time management.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">addMarker</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$name</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$location</span><span class="p">,</span> <span class="kt">Clock</span> <span class="nv">$clock</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markerAddedAt</span> <span class="o">=</span> <span class="nv">$clock</span><span class="o">-&gt;</span><span class="nf">now</span><span class="p">();</span>\n <span class="p">}</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, thanks to the <code class="language-plaintext highlighter-rouge">Clock</code> interface we will be able to create test doubles and easily test this method.</p>\n\n<h2 id="coupling-might-be-your-worst-enemy">Coupling might be your worst enemy</h2>\n\n<blockquote>\n <p>Coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)">Wikipedia</a></p>\n</blockquote>\n\n<p>As you have seen in the previous sections, objects should depend on abstractions instead of concrete implementations. Abstractions (e.g. interfaces) ease testing because your code is more modular. You can use test doubles to reduce the complexity and facilitate testing. Their goal is to mimic the behavior of real objects to replace a subpart of an algorithm.</p>\n\n<p>The following example shows that hardcoding object dependencies won’t help to create test doubles.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MyClass</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">ConcreteImplementation</span> <span class="nv">$concreteImplementation</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="c1">// Here we can only use these concrete implementations, if they use IO for instance you won't be able to test it.</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">concreteImplementation</span> <span class="o">=</span> <span class="nv">$concreteImplementation</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">anotherConcreteImplementation</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">AnotherConcreteImplementation</span><span class="p">();</span>\n \n <span class="c1">// Singleton pattern does not help because it hides object dependencies and makes them hard coded.</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nc">Connection</span><span class="o">::</span><span class="nf">getInstance</span><span class="p">();</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The solution is to use the dependency inversion pattern to remove hard coded dependencies introducing abstractions as much as possible.</p>\n\n<blockquote>\n <p>High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g., interfaces). Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Wikipedia</a></p>\n</blockquote>\n\n<p>In the following example, all class dependencies are interchangeable. So, you can easily create test doubles like fake, stub, or mocks to make sure your objects meet business expectations.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MyClass</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">ImplementationInterface</span> <span class="nv">$concreteImplementation</span><span class="p">,</span>\n <span class="kt">AnoherImplementationInterface</span> <span class="nv">$anotherConcreteImplementation</span><span class="p">,</span>\n <span class="kt">ConnectionInterface</span> <span class="nv">$connection</span>\n <span class="p">)</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">concreteImplementation</span> <span class="o">=</span> <span class="nv">$concreteImplementation</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">anotherConcreteImplementation</span> <span class="o">=</span> <span class="nv">$anotherConcreteImplementation</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nv">$connection</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Caution:</strong> That does not mean you should use interfaces everywhere! Knowing when to introduce new abstractions might be hard at the beginning, there is no magic recipe!</p>\n\n<p>Thanks to my proofreaders <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a> and <a href="https://twitter.com/jjanvier_">@jjanvier_</a>.</p>\n\n Mon, 03 May 2021 00:00:00 -0500\n https://arnolanglade.github.io/why-unit-testing-can-be-hard.html?s=feed\n https://arnolanglade.github.io/why-unit-testing-can-be-hard.html\n \n testing\n \n OOP\n \n \n \n \n \n Why you should not expose objects' state to test them\n <p>To introduce this topic, let’s have a look at the PHP documentation to understand how object comparison works using the comparison and identity operators.</p>\n\n<blockquote>\n <p>When using the comparison operator (==), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values (values are compared with ==), and are instances of the same class.</p>\n\n <p>When using the identity operator (===), object variables are identical if and only if they refer to the same instance of the same class.</p>\n\n <p><a href="https://www.php.net/manual/en/language.oop5.object-comparison.php">PHP documentation </a></p>\n</blockquote>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$object</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Object</span><span class="p">();</span>\n<span class="nv">$otherObject</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Object</span><span class="p">();</span>\n\n<span class="nv">$object</span> <span class="o">==</span> <span class="nv">$otherObject</span> <span class="c1">// true</span>\n<span class="nv">$object</span> <span class="o">===</span> <span class="nv">$otherObject</span> <span class="c1">// false </span>\n</code></pre></div></div>\n\n<p>I add an <code class="language-plaintext highlighter-rouge">equals</code> method to objects to handle object comparison. The purpose of this method is to compare an object state with another one. In the following example, I use the comparison operator (==) because I want to check if the objects have the same state no matter their references.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Email</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$email</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$email</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">email</span> <span class="o">=</span> <span class="nv">$email</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">equals</span><span class="p">(</span><span class="kt">Email</span> <span class="nv">$email</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span> <span class="o">==</span> <span class="nv">$email</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>There is another way to compare object state. Do you know that instances of the same class can access each other’s private members?</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Email</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">equals</span><span class="p">(</span><span class="kt">Email</span> <span class="nv">$email</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">email</span> <span class="o">===</span> <span class="nv">$email</span><span class="o">-&gt;</span><span class="n">email</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> This is really useful to compare Doctrine entities that have persistent collections. The error <code class="language-plaintext highlighter-rouge">Error: Nesting level too deep - recursive dependency?</code> is raised when we compare entities using the comparison operator (==). You should have a look at this <a href="https://www.richardlord.net/blog/php/php-nesting-level-too-deep-recursive-dependency.html">blog post</a> to understand why this error occured. Accessing private attributes let you use the identity operator (===) to prevent this error.</p>\n\n<p>By the way, entities are a bit special because an entity is an object that has an identity. It means that if we want to compare them we should compare their identities instead of their states.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">equals</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span><span class="o">-&gt;</span><span class="nf">equals</span><span class="p">(</span><span class="nv">$mapId</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>I add an extra method called <code class="language-plaintext highlighter-rouge">hasSameState</code> to entities to compare their states because entity state comparison remains really useful for testing.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">hasSameState</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span> <span class="o">==</span> <span class="nv">$map</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>For a long time, I used getters for testing purposes. I only knew this way to ensure objects had the right state.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Nantes'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">getName</span><span class="p">()</span><span class="o">-&gt;</span><span class="nf">shouldReturn</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">)</span> <span class="p">;</span>\n</code></pre></div></div>\n\n<p>It was a mistake because exposing objects’ state breaks data encapsulation. We should not know how objects work internally, we should only use their public API (public methods) to interact with them. But, if we need to build the <code class="language-plaintext highlighter-rouge">Map</code> object with something else than a string, this assertion will no longer be true. That will break all application tests and parts that use this getter! That’s not great! Object comparison I described previously helps to get rid of getters.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Nantes'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">hasSameState</span><span class="p">(</span><span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">))</span><span class="o">-&gt;</span><span class="nf">shouldReturn</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n</code></pre></div></div>\n\n<p>Now, the <code class="language-plaintext highlighter-rouge">Map</code> object is better designed. Its state is not exposed anymore which improves data encapsulation. It follows the “Tell don’t ask” principle because I don’t need to extract its internal state to test it. I only need to use its public API to check if it meets the business exceptions.</p>\n\n<p><strong>Tip:</strong> If you don’t want or if you can’t add a method to your objects that handles comparison you can still compare their instances to avoid adding getters.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span><span class="nv">$map</span><span class="p">,</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">));</span>\n</code></pre></div></div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 13 Apr 2021 00:00:00 -0500\n https://arnolanglade.github.io/you-should-not-expose-objects-state-to-test-them.html?s=feed\n https://arnolanglade.github.io/you-should-not-expose-objects-state-to-test-them.html\n \n testing\n \n OOP\n \n \n \n \n \n How did I organize my last Symfony projects?\n <p>In this blog post, I will explain how I organized my last Symfony projects. They are mainly inspired by Hexagonal and CQRS architecture. Keep in mind that I did not try to implement these architectures by the book, I only took some concepts that helped me to have a simple and clear codebase organization.</p>\n\n<p>If we have a look at the project’s root, nothing special happens, I kept all folders and files created during Symfony installation.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree <span class="nb">.</span> <span class="nt">-L</span> 1 \n├── bin\n├── composer.json\n├── composer.lock\n├── config\n├── features\n├── public\n├── src\n├── symfony.lock\n├── tests\n├── translations\n├── var\n└── vendor\n</code></pre></div></div>\n\n<p>In the next sections, we are going to see how I organized the src folder.</p>\n\n<h2 id="hexagonal-architecture">Hexagonal architecture</h2>\n\n<p>The foundation of the hexagonal architecture is the explicit separation between the domain (inside) and the infrastructure (outside). All dependencies are going from Infrastructure to the Domain.</p>\n\n<p>The domain is the part of the application that contains your business logic. It must reflect as much as possible the problem your application has to solve. This part of the application must not use IO, the infrastructure contains them all. For instance, IO are side effects like network calls, database queries, filesystem operations, actual timestamps or randomness..</p>\n\n<p>Based on that information my first decision was to split src into two areas: <code class="language-plaintext highlighter-rouge">Domain</code> and <code class="language-plaintext highlighter-rouge">Infrastructure</code>.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/ <span class="nt">-L</span> 1\napi/src/Domain/\n├── Domain\n└── Infrastructure\n</code></pre></div></div>\n\n<p><strong>Coupling rules:</strong></p>\n<ul>\n <li>Domain must not depend on the Infrastructure.</li>\n <li>Domain must not use IO</li>\n</ul>\n\n<p>I am not a big fan of the onion architecture because I want to keep my projects as simple as possible. Having a lot of layers can be really hard to maintain because you need to align the whole team on the coupling rules. Agreeing with yourself is not easy, so getting several people to agree may be really hard. Here, we only have a single rule.</p>\n\n<p>Sometimes, I needed to write libraries because I could not find any open source libraries that match my expectations. To avoid coding in the vendor directory, I introduced a third area called <code class="language-plaintext highlighter-rouge">Libraries</code> (this new area is optional). Those libraries may be used in the domain and the infrastructure but their usage should not break the coupling rules that are defined for those areas.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/ <span class="nt">-L</span> 1\napi/src/Domain/\n├── Domain\n├── Infrastructure\n└── Librairies\n</code></pre></div></div>\n\n<p><strong>Coupling rules:</strong></p>\n<ul>\n <li>Libraries must not depend on Domain and Infrastructure</li>\n</ul>\n\n<p>Finally, I created a “sub” area called <code class="language-plaintext highlighter-rouge">Application</code> in the infrastructure that contains all pieces of code needed to have an application up and running: framework code (Symfony kernel, framework customizations), data fixtures, and migration.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Infrastructure/Application <span class="nt">-L</span> 1 \napi/src/Infrastructure/Application\n├── Exception \n├── Fixture\n├── Kernel.php\n├── Migrations\n├── Security\n└── Kernel\n</code></pre></div></div>\n<p>In this example, <code class="language-plaintext highlighter-rouge">Exception</code> and <code class="language-plaintext highlighter-rouge">Security</code> folders contain framework customizations.</p>\n\n<h2 id="business-first">Business first</h2>\n\n<p>A really important thing for me is to drive codebase organization by business concepts. I don’t want to name folders and classes with technical patterns like factory or repository for instance. Non-tech people should be able to understand what a class does thanks to its name.</p>\n\n<h3 id="domain">Domain</h3>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain <span class="nt">-L</span> 1\napi/src/Domain\n├── Cartographer\n└── Map\n</code></pre></div></div>\n\n<p>Because I did not use any technical words to name folders we can easily imagine the project is about making maps. Now, let’s have a look inside the <code class="language-plaintext highlighter-rouge">Map</code> directory:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/Map <span class="nt">-L</span> 1\n├── CartographersAllowedToEditMap.php // Value object\n├── Description.php // Value object\n├── MapCreated.php // Event \n├── MapId.php // Value object\n├── MapName.php // Value object\n├── Map.php // Root aggregate\n├── Maps.php // Repository interface\n├── Marker // All classes to design Marker entity\n├── MarkerAddedToMap.php // Event\n├── MarkerDeletedFromMap.php // Event\n├── MarkerEditedOnMap.php // Event\n├── UnknownMap.php // Exception\n└── UseCase // Use cases orchestration\n</code></pre></div></div>\n\n<p>In this folder, we have all the pieces of code needed to design the <code class="language-plaintext highlighter-rouge">Map</code> aggregate. As you can see, I did not organize it by design patterns like <code class="language-plaintext highlighter-rouge">ValueObject</code>, <code class="language-plaintext highlighter-rouge">Event</code> or <code class="language-plaintext highlighter-rouge">Exception</code>.</p>\n\n<p>As you might have understood the <code class="language-plaintext highlighter-rouge">Map</code> entity has a one-to-many relationship with the Marker entity. All classes needed to modelize this entity are in the Marker folder and they are organized the same way as the <code class="language-plaintext highlighter-rouge">Map</code> directory.</p>\n\n<p>The <code class="language-plaintext highlighter-rouge">UseCase</code> folder gathers all pieces of code needed to orchestrate use cases like command, their handler and business validation.</p>\n\n<p><strong>Tip:</strong> I don’t suffix repositories by ‘Repository’ but I try to use a business concept to name them like <code class="language-plaintext highlighter-rouge">ProductCatalog</code> for a <code class="language-plaintext highlighter-rouge">Product</code> aggregate. If I can find a business concept to name it I use the plural of the aggregate because a repository is a collection of objects.</p>\n\n<h3 id="infrastructure">Infrastructure</h3>\n\n<p>I organize the root of the <code class="language-plaintext highlighter-rouge">Infrastructure</code> folder the same way as the <code class="language-plaintext highlighter-rouge">Domain</code> one.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Infrastructure <span class="nt">-L</span> 1 \napi/src/Infrastructure\n├── Application\n├── Cartographer\n└── Map\n</code></pre></div></div>\n\n<p>Now, let’s have a look at the <code class="language-plaintext highlighter-rouge">Map</code> directory:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Infrastructure/Map <span class="nt">-L</span> 1 \napi/src/Infrastructure/Map\n├── Storage\n└── UserInterface\n └── Web\n └── Cli\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">Storage</code> namespace gathers everything related to data storage like repositories, queries. The <code class="language-plaintext highlighter-rouge">UserInterface</code> namespace gathers everything related to ways to interact with the application like the WEB API (controllers) called by the front application or CLI (Symfony commands).</p>\n\n<h2 id="cqrs">CQRS</h2>\n\n<p>CQRS is the acronym for Command Query Responsibility Segregation. The main idea of CQRS is that you can use different models for writing (command) or reading (query) information. I like the idea of having two small and simple models dedicated to a precise purpose: reading or writing instead of having one big model. It can prevent your aggregate from becoming a god object because as things progress you can have many write and read use cases to handle.</p>\n\n<p>From this pattern, I decided to split the domain into two areas, the first one: <code class="language-plaintext highlighter-rouge">Command</code> and the second one: <code class="language-plaintext highlighter-rouge">Query</code>. It allows me to design a model with the same name for these reading or writing purposes.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/ <span class="nt">-L</span> 2\napi/src/Domain/\n├── Command\n│ ├── Cartographer\n│ └── Map\n└── Query\n ├── Cartographer\n └── Map\n</code></pre></div></div>\n\n<p><strong>Coupling rule:</strong></p>\n<ul>\n <li><code class="language-plaintext highlighter-rouge">Command</code> area must not depend on the <code class="language-plaintext highlighter-rouge">Query</code> area and the other way around.</li>\n</ul>\n\n<p><strong>Note:</strong> I did not make major changes in the infrastructure, the only change I made is to split the storage into two areas like the domain.</p>\n\n<p><strong>Caution:</strong> For those projects, I did not make any projections because my database schema remained simple so I did not need them. I only decided to split my models because my codebase was simple and clearer this way.</p>\n\n<h2 id="last-word">Last word</h2>\n<p>I tried for the last few years to find the perfect architecture but it does not exist. I just tried to use some architectural concepts that make me and my teammates comfortable to work on a daily basis. This project organization has been used for two projects that are in production. One of these projects is a side project I made for fun to create maps without Google Maps. The second was a professional project, real people use it on a daily basis.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 30 Mar 2021 00:00:00 -0500\n https://arnolanglade.github.io/how-did-I-organize-my-last-symfony-project.html?s=feed\n https://arnolanglade.github.io/how-did-I-organize-my-last-symfony-project.html\n \n software-architecture\n \n symfony\n \n \n \n \n \n Persisting entities without ORM\n <p>Today, I will talk about persisting entities without ORM. First, I will introduce the repository pattern because it provides a good abstraction to manage object persistence. Then, we will see what are the impacts on the entity design.</p>\n\n<h2 id="repository-pattern">Repository pattern</h2>\n\n<p>The repository design pattern can be used to manage entity persistence and retrieval. It behaves like a collection of objects and hides the complexity of their storage. It ensures a clean separation between the domain model (the entity) and the data model (SQL tables). The following example shows a basic repository interface. Thanks to the <code class="language-plaintext highlighter-rouge">Maps</code> interface we will be able to add and retrieve Map entities, no matter their storage.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">interface</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n <span class="cd">/**\n * @throws \\LogicException\n * @throws UnknownMap\n */</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">get</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">Map</span><span class="p">;</span>\n\n <span class="cd">/**\n * @throws \\LogicException\n */</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">add</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">void</span><span class="p">;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Caution:</strong> All <code class="language-plaintext highlighter-rouge">Maps</code> implementations should be tested with the same test because we need to be sure they behave the same way. It ensures the application works no matter the chosen implementation.</p>\n\n<p>Let’s see how we can implement this interface with PostgreSQL for instance. The <code class="language-plaintext highlighter-rouge">get</code> method is only responsible to get information from the database to build the map entity whereas the <code class="language-plaintext highlighter-rouge">add</code> method extracts the entity information to store them in the database.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PostgreSqlMaps</span> <span class="kd">implements</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nv">$connection</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">get</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">Map</span>\n <span class="p">{</span>\n <span class="nv">$sql</span> <span class="o">=</span> <span class="sh">&lt;&lt;&lt;SQL\n SELECT map."mapId", map.name\n FROM map\n WHERE map."mapId" = :mapId\n SQL;</span>\n\n <span class="nv">$statement</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="nv">$sql</span><span class="p">,</span> <span class="p">[</span><span class="s1">'mapId'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="nv">$mapId</span><span class="p">]);</span>\n\n <span class="k">if</span> <span class="p">(</span><span class="kc">false</span> <span class="o">===</span> <span class="nv">$map</span> <span class="o">=</span> <span class="nv">$statement</span><span class="o">-&gt;</span><span class="nf">fetchAssociative</span><span class="p">())</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="nc">UnknownMap</span><span class="o">::</span><span class="nf">withId</span><span class="p">(</span><span class="nv">$mapId</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="nv">$map</span><span class="p">[</span><span class="s1">'mapId'</span><span class="p">],</span> <span class="nv">$map</span><span class="p">[</span><span class="s1">'name'</span><span class="p">]);</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">add</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$sql</span> <span class="o">=</span> <span class="sh">&lt;&lt;&lt;SQL\n INSERT INTO map ("mapId", name)\n VALUES (:mapId, :name)\n ON CONFLICT ("mapId")\n DO UPDATE SET name = :name;\n SQL;</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="nv">$sql</span><span class="p">,</span> <span class="p">[</span><span class="s1">'mapId'</span> <span class="o">=&gt;</span> <span class="nv">$map</span><span class="p">,</span> <span class="s1">'name'</span> <span class="o">=&gt;</span> <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">name</span><span class="p">()]);</span>\n <span class="p">}</span>\n\n <span class="k">private</span> <span class="k">function</span> <span class="n">executeQuery</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$sql</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$data</span><span class="p">):</span> <span class="kt">Result</span>\n <span class="p">{</span>\n <span class="c1">// Execute query or throw logic exceptions if something goes wrong.</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> Thanks to the clause <a href="https://www.postgresql.org/docs/9.5/sql-insert.html">ON CONFLICT</a> we can easily insert or update data with a single query.</p>\n\n<h2 id="entity-design-impacts">Entity design impacts</h2>\n\n<p>Now we are able to persist and retrieve our map entity. Let’s study the impact on entity design.</p>\n\n<p>Let’s start with persistence. In the previous example, I used getters to get its properties but I am not a fan of the getter to be honest! Getters break data encapsulation because they expose object implementation details. They don’t follow the <a href="https://www.martinfowler.com/bliki/TellDontAsk.html">Tell don’t ask</a> principle because we should not ask about the object state to do something, we should tell the object to do something for us. I like adding a <code class="language-plaintext highlighter-rouge">toState</code> method that is responsible to turn the entity into an associative array.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">toState</span><span class="p">():</span> <span class="kt">array</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="p">[</span>\n <span class="s1">'mapId'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span><span class="p">,</span>\n <span class="s1">'name'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">,</span>\n <span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>So I just need to call the <code class="language-plaintext highlighter-rouge">toState</code> method instead of getters, this method returns data expected by the <code class="language-plaintext highlighter-rouge">executeQuery</code> method.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PostgreSqlMaps</span> <span class="kd">implements</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">add</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="nv">$sql</span><span class="p">,</span> <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">toState</span><span class="p">());</span>\n <span class="p">}</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Let’s continue with retrieval. If we have a look at the <code class="language-plaintext highlighter-rouge">Map</code>constructor method we can see that a <code class="language-plaintext highlighter-rouge">MapInitialized</code> event is recorded there. Houston, we have a problem! When we build an entity from its state (data stored somewhere) we don’t want to record any event because nothing happens. So, we need to find a solution to avoid recording those events.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">,</span>\n <span class="kt">MapName</span> <span class="nv">$name</span>\n<span class="p">)</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span> <span class="o">=</span> <span class="nv">$mapId</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">recordEvent</span><span class="p">(</span><span class="k">new</span> <span class="nc">MapInitialized</span><span class="p">(</span>\n <span class="nv">$mapId</span><span class="p">,</span>\n <span class="nv">$name</span>\n <span class="p">));</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>I like adding a named constructor called <code class="language-plaintext highlighter-rouge">fromState</code> to the entity. This constructor is responsible for building the aggregate from the state. Moreover, named constructors are explicit and give developers information about when to use them. In the following example, after calling the <a href="https://arnolanglade.github.io/build-object-using-php.html">primary constructor</a> we call the <code class="language-plaintext highlighter-rouge">eraseRecordedEvents</code> method to reset events before returning the object in the right state.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">fromState</span><span class="p">(</span><span class="kt">array</span> <span class="nv">$state</span><span class="p">):</span> <span class="kt">self</span>\n<span class="p">{</span>\n <span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="nv">$state</span><span class="p">[</span><span class="s1">'mapId'</span><span class="p">]),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$state</span><span class="p">[</span><span class="s1">'name'</span><span class="p">])</span>\n <span class="p">);</span>\n\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">eraseRecordedEvents</span><span class="p">();</span>\n\n <span class="k">return</span> <span class="nv">$map</span><span class="p">;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>So, the only change in the repository is to build the <code class="language-plaintext highlighter-rouge">Map</code> entity from the named constructor.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PostgreSqlMaps</span> <span class="kd">implements</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">get</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">Map</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n\n <span class="k">return</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">fromState</span><span class="p">(</span><span class="nv">$map</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h2 id="last-word">Last word</h2>\n\n<p>I did a presentation about the repository design pattern at the Forum PHP in 2018. A video is only available in French <a href="https://www.youtube.com/watch?v=cYFKkhtIr8w&amp;ab_channel=AFUPPHP">here</a> but the slides are in English <a href="https://arnolanglade.gitlab.io/bad-or-good-repository/">here</a> (press “s” to display English notes). Even if this presentation was made for Doctrine ORM it gives a lot of information about the pattern.</p>\n\n<p><strong>Note:</strong> In this talk I spoke about generating the entity identity by the repository. To be honest, I stopped doing that because generating it from controllers is easier and makes the repository design simpler.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 23 Mar 2021 00:00:00 -0500\n https://arnolanglade.github.io/persisting-entities-without-orm.html?s=feed\n https://arnolanglade.github.io/persisting-entities-without-orm.html\n \n OOP\n \n design-patterns\n \n \n \n \n \n OOP: how to build an object\n <p>In this new blog post, I want to talk about object building more specifically about primary and secondary constructors. The primary constructor is the default way to build an object with all its dependencies. The secondary constructors provide other ways to build objects depending on use cases.</p>\n\n<p><strong>Note:</strong> I did not work on a PHP8 project yet so that is why I won’t talk about named arguments feature.</p>\n\n<h2 id="primary-constructor">Primary constructor</h2>\n\n<p>The PHP language provides a single way to build an object thanks to the <code class="language-plaintext highlighter-rouge">__construct()</code> method. I use this method to define the primary constructor of my classes to encapsulate all their dependencies.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">MapName</span> <span class="nv">$name</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">CartographersAllowedToEditMap</span> <span class="nv">$cartographersAllowedToEditMap</span><span class="p">;</span>\n <span class="cd">/** @var Marker[] */</span>\n <span class="k">private</span> <span class="kt">array</span> <span class="nv">$markers</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">MapName</span> <span class="nv">$name</span><span class="p">,</span>\n <span class="kt">CartographersAllowedToEditMap</span> <span class="nv">$cartographersAllowedToEditMap</span><span class="p">,</span>\n <span class="kt">Marker</span> <span class="mf">...</span><span class="nv">$markers</span>\n <span class="p">)</span> <span class="p">{</span> \n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">cartographersAllowedToEditMap</span> <span class="o">=</span> <span class="nv">$cartographersAllowedToEditMap</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markers</span> <span class="o">=</span> <span class="nv">$markers</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> If your objects encapsulate a collection of a specific type (like the <code class="language-plaintext highlighter-rouge">Marker</code> in this example), you can use variadic arguments to automatically validate each item of this collection. Here, we don’t need to iterate the collection to check the type of its items, the language does it for us.</p>\n\n<h2 id="secondary-constructor">Secondary constructor</h2>\n\n<p>The PHP language does not ease the data encapsulation because it only provides a single way to build objects but we should be able to define several constructors depending on all our use cases. How to solve this problem? Named constructors! Named constructors are static factories, in other words static methods that build the object itself.\nLet’s take an example with the map object. How to initialize a map without any marker?</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">initialize</span><span class="p">(</span>\n <span class="kt">string</span> <span class="nv">$name</span><span class="p">,</span>\n <span class="kt">array</span> <span class="nv">$cartographerAllowedToEditMap</span>\n <span class="p">):</span> <span class="kt">self</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$name</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">CartographersAllowedToEditMap</span><span class="p">(</span><span class="nv">$cartographerAllowedToEditMap</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Here, we added a named constructor called <code class="language-plaintext highlighter-rouge">initialize</code> to the <code class="language-plaintext highlighter-rouge">Map</code> class. It uses the primary constructor to build the map object with an empty collection of Marker objects.</p>\n\n<p><strong>Tip:</strong> Some developers change the visibility of the primary constructor method to private but I am not a big fan of that. I use object comparison to test objects to avoid the usage of getters. I like keeping my primary constructor public because it allows me to build objects in any state to compare them to other ones.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">adds</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="n">marker</span><span class="err"> </span><span class="n">on</span><span class="err"> </span><span class="n">the</span><span class="err"> </span><span class="nf">map</span><span class="p">()</span>\n<span class="p">{</span>\n <span class="nv">$actualMap</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">initialize</span><span class="p">(</span>\n <span class="s1">'Bons plans sur Nantes'</span><span class="p">,</span>\n <span class="p">[</span><span class="s1">'Arnaud'</span><span class="p">]</span>\n <span class="p">);</span>\n\n <span class="nv">$actualMap</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">);</span>\n\n <span class="nv">$expectedMap</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="s1">'Bons plans sur Nantes'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">CartographersAllowedToEditMap</span><span class="p">([</span><span class="s1">'Arnaud'</span><span class="p">]),</span>\n <span class="k">new</span> <span class="nc">Marker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">)</span>\n <span class="p">);</span>\n \n <span class="nf">assertSame</span><span class="p">(</span><span class="nv">$actualMap</span><span class="p">,</span> <span class="nv">$expectedMap</span><span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Wed, 10 Mar 2021 00:00:00 -0600\n https://arnolanglade.github.io/oop-how-to-build-an-object.html?s=feed\n https://arnolanglade.github.io/oop-how-to-build-an-object.html\n \n OOP\n \n design-patterns\n \n \n \n \n \n How to validate a command?\n <p>In my previous <a href="http://arnolanglade.github.io/command-handler-patterns.html">blog post</a>, I talked about command and command handler design patterns. I got several questions about data validation and how to give feedback to users. We are going to talk about several kinds of data validation in this blog post. We will start with domain validation, this validation ensures we can build our domain objects in a good state depending on business rules. Then, we will talk about command validation and how we can use it to give feedback to users when they submit data to the application.</p>\n\n<p>Let’s take the same example I used in my previous blog post: an account creation. To create an account, my business expert expects that I provide a username and a password. The username should have at least three characters and should be unique. The password should have at least eight characters, an uppercase letter, a lowercase letter, and a number.</p>\n\n<h2 id="domain-validation">Domain validation</h2>\n\n<p>How to make sure the domain objects follow the business rules? Value object will help us to achieve that. I <strong>strongly recommend you</strong> to wrap all primitives into value objects. It is a good way to introduce new types in your codebase, make it clearer and business-focused. And don’t forget, value objects <strong>cannot</strong> be built in a wrong state.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Username</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$username</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span><span class="err">\\</span><span class="nb">strlen</span><span class="p">(</span><span class="nv">$username</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="err">\\</span><span class="nf">InvalidArgumentException</span><span class="p">(</span><span class="s1">'The username is too short, it should contain at least 3 characters'</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">Password</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span><span class="mi">1</span> <span class="o">!==</span> <span class="err">\\</span><span class="nb">preg_match</span><span class="p">(</span><span class="s1">'#(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,}#'</span><span class="p">,</span> <span class="nv">$password</span><span class="p">))</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="err">\\</span><span class="nf">InvalidArgumentException</span><span class="p">(</span>\n <span class="s1">'The password must contain at least 8 characters, an uppercase letter, lowercase letter and a number'</span>\n <span class="p">);</span>\n <span class="p">}</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then we are able to modelize the <code class="language-plaintext highlighter-rouge">Account</code> aggregate using the <code class="language-plaintext highlighter-rouge">Username</code> and <code class="language-plaintext highlighter-rouge">Password</code> value objects.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Account</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Username</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">Password</span> <span class="nv">$password</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">Username</span> <span class="nv">$username</span><span class="p">,</span>\n <span class="kt">Password</span> <span class="nv">$password</span>\n <span class="p">)</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, we are sure that as developers we cannot instantiate the <code class="language-plaintext highlighter-rouge">Account</code> aggregate in a wrong state. In the next section, we are going to see how to use the domain objects to give users feedback about their data.</p>\n\n<h2 id="command-validation">Command validation</h2>\n\n<p>As I explained in my previous <a href="http://arnolanglade.github.io/command-handler-patterns.html">blog post</a>, an account creation is represented by a <code class="language-plaintext highlighter-rouge">CreateAnAccount</code> command with two properties: the username and the password. We need to validate them to create the account aggregate without any errors and tell users if they provided valid data to perform this action. The command validation will be done by the Symfony validator. Don’t hesitate to have a look at the <a href="https://symfony.com/doc/current/validation.html">validator documentation</a> if you are not familiar with it.</p>\n\n<p>First, we will use the callback constraint to make sure the username and password follow the patterns given by the business expert. Thanks to annotation we will configure the validator to call a static method to validate command properties. I will call them “static validators“ in this blog post.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="cd">/** @Assert\\Callback({"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\UsernameShouldBeValid", "validate"}) */</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="cd">/** @Assert\\Callback({"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\PasswordShouldBeValid", "validate"}) */</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then, it is time to create those static validators. We just need to instantiate our value objects and check if they throw exceptions to catch them and turn them into violations.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">UsernameShouldBeValid</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">ExecutionContextInterface</span> <span class="nv">$context</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="k">try</span> <span class="p">{</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$username</span><span class="p">);</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="err">\\</span><span class="nc">InvalidArgumentException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>\n <span class="nv">$context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'account.usernameShouldBeValid'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">PasswordShouldBeValid</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">,</span> <span class="kt">ExecutionContextInterface</span> <span class="nv">$context</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="k">try</span> <span class="p">{</span>\n <span class="k">new</span> <span class="nc">Password</span><span class="p">(</span><span class="nv">$password</span><span class="p">);</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="err">\\</span><span class="nc">InvalidArgumentException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>\n <span class="nv">$context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'account.passwordShouldBeValid'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>For more complex use cases you can call any methods on value objects, but you need to keep in mind that you cannot inject services into those static validators.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="kt">BookFlightTicket</span> <span class="nv">$flightTicket</span><span class="p">,</span> <span class="kt">ExecutionContextInterface</span> <span class="nv">$context</span><span class="p">):</span> <span class="kt">void</span>\n<span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span>\n <span class="o">!</span><span class="nc">Date</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="nv">$flightTicket</span><span class="o">&gt;</span><span class="n">departureDate</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">laterThan</span><span class="p">(</span>\n <span class="nc">Date</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="nv">$flightTicket</span><span class="o">&gt;</span><span class="n">arrivalDate</span><span class="p">)</span>\n <span class="p">)</span>\n <span class="p">)</span> <span class="p">{</span>\n <span class="nv">$context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'flightTicket.dateShouldBeValid'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The first step is done! Thanks to those static validators, we apply domain validation on command properties to ensure we can instantiate domain objects. But, domain validation only works with a single account because the account aggregate only represents the account of a single user. For instance, an account cannot validate if a username is unique because it needs to be aware of the rest of the created account.</p>\n\n<p>To check if a username is used by another user we will need to ask the repository if an account already exists with the given username. That’s why we will need to create a custom validation constraint because those constraints are declared as services, and they can depend on other application services.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cd">/** @Annotation */</span>\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">UsernameShouldBeUnique</span> <span class="kd">extends</span> <span class="nc">Constraint</span>\n<span class="p">{</span>\n<span class="p">}</span>\n\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">UsernameShouldBeUniqueValidator</span> <span class="kd">extends</span> <span class="nc">ConstraintValidator</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span> <span class="o">=</span> <span class="nv">$accounts</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="nv">$username</span><span class="p">,</span> <span class="kt">Constraint</span> <span class="nv">$constraint</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nv">$constraint</span> <span class="k">instanceof</span> <span class="nc">UsernameShouldBeUnique</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">UnexpectedTypeException</span><span class="p">(</span><span class="nv">$constraint</span><span class="p">,</span> <span class="nc">UsernameShouldBeUnique</span><span class="o">::</span><span class="n">class</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">try</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span><span class="o">-&gt;</span><span class="nf">getByUsername</span><span class="p">(</span><span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$username</span><span class="p">));</span>\n\n <span class="c1">// an exception is thrown if an account does not exist so we don’t add violation</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'account.usernameShouldBeUnique'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">UnknownAccount</span> <span class="nv">$exception</span><span class="p">)</span> <span class="p">{</span>\n <span class="p">}</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Finally, we need to configure the validator to apply this new constraint to the username property.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cd">/**\n * @Assert\\GroupSequence({"CreateAnAccount", "Business"})\n */</span>\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="cd">/** \n * @Assert\\Callback({"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\UsernameShouldBeValid", "validate"})\n * @Domain\\Account\\UseCase\\ValidationRule\\UsernameShouldBeUnique(groups={"Business"})\n */</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$username</span><span class="p">;</span>\n \n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Caution:</strong> we need to apply static validators before applying custom constraints because we need to be sure we can instantiate all domain objects without raising any error. For instance, the instantiation of <code class="language-plaintext highlighter-rouge">Username</code> in <code class="language-plaintext highlighter-rouge">UsernameShouldBeUniqueValidator</code> must not raise any error because the goal of this constraint is not to check if the username contains at least three characters but if the username is already used. It can be done with <a href="https://symfony.com/doc/current/validation/sequence_provider.html">GroupSequence</a>. This validator feature allows adding groups to constraints and defining the validation constraint execution order.</p>\n\n<p>Now, this is the end of the story! If commands are invalid, we just need to serialize violations, give them to your front application, and print errors to users.</p>\n\n<h2 id="last-word">Last word</h2>\n\n<p>This might not be the only way to validate data but it worked on my previous project. Even if I use a service to validate my command I try to use as many domain objects as possible to avoid reinventing the wheel. I hope it answers Baptiste Langlade’s <a href="https://twitter.com/Baptouuuu/status/1364945053236494336">question</a> on Twitter. If you wonder, Baptiste is not my brother ;).</p>\n\n<p>Thanks to my proofreaders <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a> and <a href="https://twitter.com/jjanvier_">@jjanvier_</a>.</p>\n\n Thu, 04 Mar 2021 00:00:00 -0600\n https://arnolanglade.github.io/how-to-validate-a-command.html?s=feed\n https://arnolanglade.github.io/how-to-validate-a-command.html\n \n command-bus\n \n design-patterns\n \n \n \n \n \n Command and command handler design pattern\n <p>This pattern is really interesting; it can help you handle use cases. A command represents the user’s intent, while the command handler performs the actions needed to achieve the use case. Let’s dig a bit into these two concepts.</p>\n\n<h2 id="what-is-a-command">What is a command?</h2>\n\n<p>A command is an object used to encapsulate all the information needed to perform an action. This design pattern is used to represent user intents, and the command is given to a command handler.</p>\n\n<p>A command is often designed as a Data Transfer Object (DTO), which is an object without any behavior (a data structure). The most important design rule to consider is that a command should be easily serializable. This way, it can be sent to a queue such as RabbitMQ or pub-sub to be handled asynchronously.</p>\n\n<h2 id="what-is-a-command-handler">What is a command handler?</h2>\n\n<p>A command handler is just a callable that executes all the actions needed to fulfill a user’s intent. As you may understand, this design pattern is perfect for managing your business use cases.</p>\n\n<h2 id="how-does-it-work">How does it work?</h2>\n\n<p><img src="images/posts/command-handler/explain-command-handler.svg" alt="Command handler design pattern" /></p>\n\n<p>This pattern has some rules. The first one is that a command can be handled by a single command handler because there is only a single way to handle a use case. The second rule is that a command handler should receive a valid command. Validating the command ensures that the user provides the correct data to prevent the handling from failing. It also helps to provide early feedback to the user about the data they provided.</p>\n\n<p>The command is only a DTO that carries data while the command handler is responsible to handle use cases.</p>\n\n<h2 id="how-to-use-it">How to use it?</h2>\n\n<p>Let’s consider a simple example: creating an account. Our business expert expects users to provide an email and a password to create an account for login purposes. We will create a command named <code class="language-plaintext highlighter-rouge">CreateAnAccount</code> and its handler, <code class="language-plaintext highlighter-rouge">CreateAnAccountHandler</code>.\nFirst, we need to create a command named <code class="language-plaintext highlighter-rouge">CreateAnAccount</code> to represent the user’s intent.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="kt">readonly</span> <span class="n">string</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="k">public</span> <span class="kt">readonly</span> <span class="n">string</span> <span class="nv">$password</span><span class="p">;</span>\n \n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">)</span> \n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Next, we need to create a command handler to manage this use case. The command handler can be a function or an invocable object. It should return nothing (void) to be handled asynchronously as we don’t know when it will be processed and can’t expect an instant result. Using the command data, we perform all actions needed to handle the use case. In our example, we create an account aggregate and pass it to the account repository.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccountHandler</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span> <span class="o">=</span> <span class="nv">$accounts</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">CreateAnAccount</span> <span class="nv">$createAnAccount</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$account</span> <span class="o">=</span> <span class="nc">Account</span><span class="o">::</span><span class="nf">create</span><span class="p">(</span>\n <span class="nv">$createAnAccount</span><span class="o">-&gt;</span><span class="nf">username</span><span class="p">(),</span>\n <span class="nv">$createAnAccount</span><span class="o">-&gt;</span><span class="nf">password</span><span class="p">()</span>\n <span class="p">);</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span><span class="o">-&gt;</span><span class="nf">add</span><span class="p">(</span><span class="nv">$account</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Finally, let’s stick those pieces of code together in a controller (this example is made with a Symfony Framework). This controller receives JSON-encoded data to create a command, which is then validated and passed to the handler</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n \n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">Request</span> <span class="nv">$request</span><span class="p">):</span> <span class="kt">Response</span>\n <span class="p">{</span>\n <span class="nv">$command</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">serializer</span><span class="o">-&gt;</span><span class="nf">deserialize</span><span class="p">(</span>\n <span class="nv">$request</span><span class="o">-&gt;</span><span class="nf">getContent</span><span class="p">(),</span>\n <span class="nc">CreateAnAccount</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>\n <span class="s1">'json'</span>\n <span class="p">);</span>\n \n <span class="nv">$violations</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">validator</span><span class="o">-&gt;</span><span class="nf">validate</span><span class="p">(</span><span class="nv">$command</span><span class="p">);</span>\n \n <span class="k">if</span> <span class="p">(</span><span class="mi">0</span> <span class="o">&lt;</span> <span class="nv">$violations</span><span class="o">-&gt;</span><span class="nb">count</span><span class="p">())</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">BadRequestHttpException</span><span class="p">(</span><span class="cm">/*json encoded violation*/</span><span class="p">);</span>\n <span class="p">}</span>\n \n <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">createAnAccountHandler</span><span class="p">)(</span><span class="nv">$command</span><span class="p">);</span>\n \n <span class="k">return</span> <span class="k">new</span> <span class="nc">JsonResponse</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nc">Response</span><span class="o">::</span><span class="no">HTTP_CREATED</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n</code></pre></div></div>\n<p><strong>Tip:</strong> : To simplify command creation, you can use libraries such as the Symfony Serializer component. It eases object creation from a set of data (e.g., JSON), making the process easier and faster.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$createAccount</span> <span class="o">=</span> <span class="nv">$serializer</span><span class="o">-&gt;</span><span class="nf">deserialize</span><span class="p">(</span>\n <span class="s1">'{“username”:”arnaud”, “password”:“password”}'</span><span class="p">,</span>\n <span class="nc">CreateAnAccount</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>\n <span class="s1">'json'</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p>Tip: To avoid reinventing the wheel, you can leverage libraries like the Symfony Validator component to validate the command.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$violation</span> <span class="o">=</span> <span class="nv">$validator</span><span class="o">-&gt;</span><span class="nf">validate</span><span class="p">(</span><span class="nv">$createAccount</span><span class="p">);</span>\n</code></pre></div></div>\n\n<p>I’ve written a dedicated blog post explaining how to validate a command:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/how-to-validate-a-command.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/data-validation.webp" alt="How to validate a command?" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">How to validate a command?</span>\n </span>\n </a>\n</div>\n\n<h2 id="how-to-simplify-that">How to simplify that?</h2>\n\n<p>To simplify this controller, consider using a command bus, which is responsible for finding the right handler for a given command. For more information about this pattern, I’ve written a dedicated blog post explaining how it works:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-bus-design-pattern.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-bus/command-bus.svg" alt="The command bus design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">The command bus design pattern</span>\n </span>\n </a>\n</div>\n\n<p>The following example is built with <a href="https://symfony.com/doc/current/components/messenger.html">Symfony Messenger</a>.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">Request</span> <span class="nv">$request</span><span class="p">):</span> <span class="kt">Response</span>\n<span class="p">{</span>\n <span class="nv">$command</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">serializer</span><span class="o">-&gt;</span><span class="nf">deserialize</span><span class="p">(</span>\n <span class="nv">$request</span><span class="o">-&gt;</span><span class="nf">getContent</span><span class="p">(),</span>\n <span class="nc">CreateAnAccount</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>\n <span class="s1">'json'</span>\n <span class="p">);</span>\n \n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">commandBus</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nv">$command</span><span class="p">);</span>\n \n <span class="k">return</span> <span class="k">new</span> <span class="nc">JsonResponse</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nc">Response</span><span class="o">::</span><span class="no">HTTP_CREATED</span><span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Where is the command validation in this example? Command buses are often built with middleware, making them highly configurable. To ensure that all commands are valid before passing them to a command handler, we need to add middleware to the command bus for command validation.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">ValidationMiddleware</span> <span class="kd">implements</span> <span class="nc">MiddlewareInterface</span>\n<span class="p">{</span>\n <span class="c1">// …</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">handle</span><span class="p">(</span><span class="kt">Envelope</span> <span class="nv">$envelope</span><span class="p">,</span> <span class="kt">StackInterface</span> <span class="nv">$stack</span><span class="p">):</span> <span class="kt">Envelope</span>\n <span class="p">{</span>\n <span class="nv">$message</span> <span class="o">=</span> <span class="nv">$envelope</span><span class="o">-&gt;</span><span class="nf">getMessage</span><span class="p">();</span> \n <span class="nv">$violations</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">validator</span><span class="o">-&gt;</span><span class="nf">validate</span><span class="p">(</span><span class="nv">$message</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nv">$groups</span><span class="p">);</span>\n <span class="k">if</span> <span class="p">(</span><span class="err">\\</span><span class="nb">count</span><span class="p">(</span><span class="nv">$violations</span><span class="p">))</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">ValidationFailedException</span><span class="p">(</span><span class="nv">$message</span><span class="p">,</span> <span class="nv">$violations</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="nv">$stack</span><span class="o">-&gt;</span><span class="nb">next</span><span class="p">()</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nv">$envelope</span><span class="p">,</span> <span class="nv">$stack</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> Take a look at this blog post if you need to manage user permissions. Adding a middleware to the command bus can enhance the security of your application:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/how-to-handle-user-permissions-through-command-bus-middleware.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/how-to-handle-permissions-through-command-bus-middleware.webp" alt="How to handle user permissions through command bus middleware" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">How to handle user permissions through command bus middleware</span>\n </span>\n </a>\n</div>\n\n<h2 id="my-last-thoughts">My last thoughts</h2>\n\n<p>In many applications,I have seen a lot of classes named managers or services (e.g., AccountService, AccountManager) that gather all use case management into a single class. While this approach might be effective initially as development progresses, these classes tend to grow larger and larger, and become a “god object.” This makes maintenance challenging, reduces readability, and can quickly turn into a dump. I believe this pattern can address these issues.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Thu, 25 Feb 2021 00:00:00 -0600\n https://arnolanglade.github.io/command-handler-patterns.html?s=feed\n https://arnolanglade.github.io/command-handler-patterns.html\n \n command-bus\n \n design-patterns\n \n \n \n \n \n\n","date":"2024-01-02 05:30:02 -0600","content":"\n\n \n Arnaud Langlade\n \n https://arnolanglade.github.io/\n \n Tue, 02 Jan 2024 05:30:02 -0600\n Tue, 02 Jan 2024 05:30:02 -0600\n Jekyll v4.2.1\n \n \n Testing a React application: Secure your tests from internationalization impact\n <p>In my previous company, we automated the translation process. We used Lokalise, a cloud-based localization and translation management system. The developers imported all translation keys into the system, while the OPS team was responsible for translating all the keys.</p>\n\n<p><img src="images/posts/test-strategy-i18n-react-application/translation-management-workflow.svg" alt="translation management workflow with lokalized" /></p>\n\n<p>This process is excellent because you don’t have to wait for translations. As a developer, you add the new translation key and provide the default language. The OPS team is notified when a new key is imported into the tool. They don’t need a developer to provide translations; they are highly autonomous. Afterward, the developers need to pull the translations into the codebase and deploy the application.</p>\n\n<p>Let’s consider an example: a React Application that uses the <a href="https://github.com/formatjs/formatjs">React-Intl</a> as its internationalization system. This library provides a component called <code class="language-plaintext highlighter-rouge">FormattedMessage</code> that finds the translation for a given key and locale. This component must be used within a React Context called <code class="language-plaintext highlighter-rouge">IntlProvider</code>.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">translations</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">translation</span><span class="dl">'</span> <span class="p">};</span>\n\n\n<span class="p">&lt;</span><span class="nc">IntlProvider</span> <span class="na">locale</span><span class="p">=</span><span class="s">"en"</span> <span class="na">messages</span><span class="p">=</span><span class="si">{</span><span class="nx">translations</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">FormattedMessage</span> <span class="na">id</span><span class="p">=</span><span class="s">"key"</span> <span class="p">/&gt;</span>\n<span class="p">&lt;/</span><span class="nc">IntlProvider</span><span class="p">&gt;;</span>\n</code></pre></div></div>\n\n<p>I like wrapping the <code class="language-plaintext highlighter-rouge">IntlProvider</code> in a custom provider that allows configuring React Intl for the entire application and provides additional features like locale switching. To keep this example simple, I hardcoded the locale.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">AppIntlProvider</span><span class="p">({</span> <span class="nx">children</span> <span class="p">}:</span> <span class="p">{</span> <span class="nl">children</span><span class="p">:</span> <span class="nx">ReactElement</span> <span class="p">})</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">translations</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">translation</span><span class="dl">'</span> <span class="p">};</span>\n \n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">IntlProvider</span>\n <span class="na">messages</span><span class="p">=</span><span class="si">{</span><span class="nx">translations</span><span class="si">}</span>\n <span class="na">locale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="na">defaultLocale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">IntlProvider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now let’s go back to the testing problem. The following example is a test that checks if the <code class="language-plaintext highlighter-rouge">onClick</code> callback is called when the button with the label “OK” is clicked.`</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">MyComponent</span><span class="p">({</span> <span class="nx">onClick</span> <span class="p">}:</span> <span class="p">{</span> <span class="nl">onClick</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="k">void</span> <span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>\n // ...\n <span class="p">&lt;</span><span class="nc">Button</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">FormattedMessage</span> <span class="na">id</span><span class="p">=</span><span class="s">"validate"</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">Button</span><span class="p">&gt;</span>\n <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n<span class="c1">//const translations = { validate: 'OK' };</span>\n\n<span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">validate something</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">onClick</span> <span class="o">=</span> <span class="nx">jest</span><span class="p">.</span><span class="nx">fn</span><span class="p">();</span>\n <span class="nx">render</span><span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">MyComponent</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span> <span class="p">/&gt;,</span>\n <span class="p">{</span>\n <span class="na">wrapper</span><span class="p">:</span> <span class="nx">AppIntlProvider</span><span class="p">,</span>\n <span class="p">},</span>\n <span class="p">);</span>\n \n <span class="nx">userEvent</span><span class="p">.</span><span class="nx">click</span><span class="p">(</span><span class="nx">screen</span><span class="p">.</span><span class="nx">getByText</span><span class="p">(</span><span class="dl">'</span><span class="s1">OK</span><span class="dl">'</span><span class="p">));</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">onClick</span><span class="p">).</span><span class="nx">toHaveBeenCalled</span><span class="p">();</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>What happens if an OPS changes the translation of the ‘validate’ key from ‘OK’ to ‘GO’ for any reason? Your test will break even if the code and the test have not changed. That is a shame. Should translations break your test suites? I would like to answer this question with a no.\nThe solution that I use to prevent this problem is to override each translation that the test needs. I added an extra prop to the custom React Intl provider called overriddenTranslations that lets me override the translations my test needs.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">AppIntlProvider</span><span class="p">(</span>\n <span class="p">{</span> <span class="nx">children</span><span class="p">,</span> <span class="nx">overriddenTranslations</span> <span class="p">}:</span>\n <span class="p">{</span> <span class="nl">children</span><span class="p">:</span> <span class="nx">ReactElement</span><span class="p">,</span> <span class="nx">overriddenTranslations</span><span class="p">?:</span> <span class="nb">Partial</span><span class="o">&lt;</span><span class="nx">Translations</span><span class="o">&gt;</span> <span class="p">},</span>\n<span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">translations</span><span class="p">:</span> <span class="nx">Translations</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">translation</span><span class="dl">'</span> <span class="p">};</span>\n \n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">IntlProvider</span>\n <span class="na">messages</span><span class="p">=</span><span class="si">{</span> <span class="p">{</span> <span class="p">...</span><span class="nx">translations</span><span class="p">,</span> <span class="p">...</span><span class="nx">overriddenTranslations</span> <span class="p">}</span> <span class="si">}</span>\n <span class="na">locale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="na">defaultLocale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">IntlProvider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, we only need to override the translation for the key ‘validate.’ Its value will remain ‘OK’ in the test context.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// const translations = { validate: 'GO' };</span>\n\n<span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">validate something</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">onClick</span> <span class="o">=</span> <span class="nx">jest</span><span class="p">.</span><span class="nx">fn</span><span class="p">();</span>\n <span class="nx">render</span><span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">MyComponent</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span> <span class="p">/&gt;,</span>\n <span class="p">{</span>\n <span class="na">wrapper</span><span class="p">:</span> <span class="p">(</span><span class="nx">children</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">AppIntlProvider</span> <span class="na">overriddenTranslations</span><span class="p">=</span><span class="si">{</span> <span class="p">{</span> <span class="na">validate</span><span class="p">:</span> <span class="dl">'</span><span class="s1">OK</span><span class="dl">'</span> <span class="p">}</span> <span class="si">}</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">AppIntlProvider</span><span class="p">&gt;</span>\n <span class="p">),</span>\n <span class="p">},</span>\n <span class="p">);</span>\n \n <span class="nx">userEvent</span><span class="p">.</span><span class="nx">click</span><span class="p">(</span><span class="nx">screen</span><span class="p">.</span><span class="nx">getByText</span><span class="p">(</span><span class="dl">'</span><span class="s1">OK</span><span class="dl">'</span><span class="p">));</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">onClick</span><span class="p">).</span><span class="nx">toHaveBeenCalled</span><span class="p">();</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>Overriding a translation makes the test more resilient; even if you change the translation, the test will still pass (be green). In this specific context, it allows the OPS team to change any translation without breaking the test suite.</p>\n\n Mon, 11 Dec 2023 00:00:00 -0600\n https://arnolanglade.github.io/test-strategy-i18n-react-application.html?s=feed\n https://arnolanglade.github.io/test-strategy-i18n-react-application.html\n \n react\n \n testing\n \n \n \n \n \n The Mikado Method: Small Steps, Big Improvements\n <p>In this blog post, I will introduce the Mikado Method. This method helps solve complex problems without breaking your codebase, even if you need to introduce significant changes.</p>\n\n<p>It is common to work using PR (Pull Request), you can work on your task without breaking your application and disturbing the rest of the team. However, when you start working on a task without maintaining something that works, you end up adding too many changes that are not production-ready. The drawback of this approach is that your PRs will be large and hard to merge.</p>\n\n<p>It often happens when you refactor your codebase. You start refactoring something but it breaks another part of this application, then you fix it but it introduces a new problem elsewhere. As a result, you accumulate many changes without being able to merge them.</p>\n\n<p>Merging big PR is more complicated than simple changes. First, we need to ask for code reviews, but it can be challenging for your teammate to understand what you did when your PR includes too many things. Then, another drawback is the need to rebase your PR several times due to other PRs being pushed to the main branch.</p>\n\n<p>Now, you understand why it’s difficult to introduce big changes in your codebase. It is better to work on small steps that can be mergeable at any time. The Mikado method takes its name from the Mikado game, where the goal is to remove one stick without disturbing the others. The Mikado method has the same philosophy. It aims to make small incremental improvements to a project without breaking the existing codebase. This way, you can push your changes at any time and they won’t break your application even if you did not finish your task.</p>\n\n<p>This method simplifies refactoring. You can continuously improve your codebase instead of stacking changes in a huge PR which can’t be merged because the test suites are broken. It’s better to regularly merge small changes that improve your codebase quality. This method is ideal for brownfield development. It enables you to add new features or alter existing ones without breaking the rest of the application. Moreover, it facilitates the improvement of the application’s architecture while allowing the delivery of new features concurrently.</p>\n\n<p>How does it work? Let’s take an example: MySQL doesn’t match the project’s needs; we need to use PostgreSQL. First, we need to define a goal that is clear and understandable for everyone. In our case, it is “Migrate the application from MySQL to PostgreSQL,” as you can see in the following example.</p>\n\n<p><img src="images/posts/mikado-method/define-goal.webp" alt="define a goal" /></p>\n\n<p><strong>Note:</strong> A goal can be what you want to improve in your application such as refactoring a section of the application to enhance its clarity or improving an existing feature.</p>\n\n<p>There are less chances that you can achieve your goal in a single attempt and quickly but we will try to solve it. Based on what we learn in this initial experimentation, we will split a big task (our goal) into smaller ones, which we call prerequisites. As mentioned earlier, this approach prevents ending up with a large pull request that is difficult to merge.</p>\n\n<p>To migrate the application to PostgreSQL, we first need to install the database. Then, we need to update our repositories because they use SQL queries specific to MySQL.</p>\n\n<p><img src="images/posts/mikado-method/add-prerequisites.webp" alt="add prerequisites to the mikado graph" /></p>\n\n<p>Now, you will start exploring all the prerequisites. Select a prerequisite from the list and start an experimentation to solve it. If you can easily achieve it, that’s excellent! Commit your changes, mark the prerequisite as completed, and proceed to the next one on the list.</p>\n\n<p><img src="images/posts/mikado-method/prerequisite-completed.webp" alt="prerequisite completed" /></p>\n\n<p>If you cannot easily solve it, you need to revert your changes and define a sublist of prerequisites to achieve the original prerequisite. The purpose is to avoid making big changes but to focus on working on small steps while keeping the codebase stable. Reverting changes may not be natural to a developer, but it’s an important step in the process. It allows you to continue working in smaller steps, while the exploration helps you learn what is necessary to solve a prerequisite.</p>\n\n<p><img src="images/posts/mikado-method/add-prerequisite-to-prerequisite.webp" alt="add prerequisite to prerequisite" /></p>\n\n<p>Continue to resolve all prerequisites until the end. When all prerequisites are done, your goal is completed!</p>\n\n<p><img src="images/posts/mikado-method/goal-completed.webp" alt="goal completed" /></p>\n\n<p>As you can see in the previous sections of the blog post, we can represent your progress as a graph. This is a useful way to communicate the progress of your task with the rest of the team. For example, you can show the mikado graph at the daily meeting to easily explain what you did. If, for any reason, you cannot complete your task, you can share the mikado graph with a colleague to explain what you’ve done and what remains to be done. Organizing your work becomes easier, especially when you are working on complex tasks. The Mikado graph is more visual than a simple to-do list because it allows you to see dependencies between prerequisites.</p>\n\n<p>I wrote a small application called MikadoApp to easily create and share your Mikado graphs. All the images in the blog posts are screenshots from the application. You can start using it thanks to this <a href="https://mikado-method-teal.vercel.app">link</a>, and you can find the source code on <a href="https://github.com/arnolanglade/mikado-app">GitHub</a>. Don’t hesitate to contribute to the application to improve it.</p>\n\n<p>Since I started using this method, my way of working has changed. I try to break down my work into small steps, and each commit can be pushed into production. If I refactor something, it’s great because I regularly push improvements. If I work on a feature, I can refactor what I need to create my feature without breaking the rest of the application.</p>\n\n<p>Now,I like working directly on the main branch, but I ensure that I only push stable commits. That’s what we call Trunk Based Development. This approach allows delivering small improvements to production quickly and frequently. Even though it can be practiced with PRs, I no longer prefer working with them due to the many associated processes that slow down the delivery.</p>\n\n Mon, 27 Nov 2023 00:00:00 -0600\n https://arnolanglade.github.io/mikado-method.html?s=feed\n https://arnolanglade.github.io/mikado-method.html\n \n methodology\n \n \n \n \n \n Open-Closed principle: Enhancing code modularity\n <p>Have you missed my last blog post about the <a href="/oop-inheritance-pitfalls.html">pitfalls of inheritance</a>? I explain how it could be a bad idea to use it too much. Applying composition prevents this problem; it is better to work with small classes to easily assemble. In this blog post, I will talk about the open-closed principle. This principle facilitates composition and helps avoid relying too much on inheritance.</p>\n\n<p>This principle is one of the SOLID principles, and I think it is super important because it allows you to write more flexible code. I wanted to explain it because its definition is quite simple, but it is not necessarily easy to grasp.</p>\n\n<blockquote>\n <p>The open closed principle states “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”; that is, such an entity can allow its behaviour to be extended without modifying its source code.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle">Wikipedia</a></p>\n</blockquote>\n\n<p>The first time I read the definition of this principle, I understood that I should not have to modify my code to add additional behavior. This part of the definition “open for extension” was a bit confusing. What did it mean? Does it refer to OOP inheritance? No, it doesn’t refer to OOP inheritance. I have written a blog post about OOP inheritance. It explains why extending a class to change its behavior may seem simple, but is it a good idea? It introduces a lot of coupling in your codebase and between your team.</p>\n\n<p>Before digging into the principle, let’s consider a scenario to illustrate the following example: a class called ‘DiscountCalculator’ is in charge of calculating discounts based on the products in the basket. We apply a 20% discount to products with the category ‘sport,’ a 50% discount to products with the category ‘home,’ and a 10% discount to products with the category ‘food.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">Product</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">public</span> <span class="nx">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span>\n <span class="k">public</span> <span class="nx">category</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span>\n <span class="k">public</span> <span class="nx">price</span><span class="p">:</span> <span class="kr">number</span>\n <span class="p">)</span> <span class="p">{}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">Basket</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">public</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[])</span> <span class="p">{}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">DiscountCalculator</span> <span class="p">{</span>\n <span class="nx">calculate</span><span class="p">(</span><span class="nx">basket</span><span class="p">:</span> <span class="nx">Basket</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="kd">let</span> <span class="nx">totalDiscount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>\n\n\n <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">product</span> <span class="k">of</span> <span class="nx">basket</span><span class="p">.</span><span class="nx">products</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">switch</span> <span class="p">(</span><span class="nx">product</span><span class="p">.</span><span class="nx">category</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">case</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">:</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.2</span><span class="p">;</span> <span class="c1">// 20% discount</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="k">case</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">:</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.5</span><span class="p">;</span> <span class="c1">// 50% discount</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="k">case</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">:</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.1</span><span class="p">;</span> <span class="c1">// 10% discount</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="p">}</span>\n <span class="p">}</span>\n \n <span class="k">return</span> <span class="nx">totalDiscount</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="c1">// Example usage:</span>\n<span class="nx">it</span><span class="p">.</span><span class="nx">each</span><span class="p">([</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Football</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">20</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Couch</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">100</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Banana</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>\n<span class="p">])(</span><span class="dl">'</span><span class="s1">calculates discounts for %s category</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">,</span> <span class="nx">expectedDiscount</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">product</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Product</span><span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">basket</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Basket</span><span class="p">([</span><span class="nx">product</span><span class="p">]);</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="k">new</span> <span class="nx">DiscountCalculator</span><span class="p">().</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">basket</span><span class="p">)).</span><span class="nx">toBe</span><span class="p">(</span><span class="nx">expectedDiscount</span><span class="p">);</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>This code does not follow the open-close principle because we need to modify this <code class="language-plaintext highlighter-rouge">DiscountCalculator</code> class every time we want to add or remove a discount rule. The problem is that<code class="language-plaintext highlighter-rouge">DiscountCalculator</code> may become really large if the business asks us to add a lot of discount rules. Large objects are hard to understand, so it won’t facilitate its maintenance and testability.</p>\n\n<p>Let’s refactor this code to enhance its modularity and align it with the Open-Closed principle. We will use the strategy pattern to rewrite the calculator to remove the hard-coded rules. First, we will introduce a new interface that specifies how a discount works. This interface has two methods: the first one is <code class="language-plaintext highlighter-rouge">isApplicable</code>, which determines if a discount can be applied to a product, while the second one <code class="language-plaintext highlighter-rouge">calculate</code> calculates the amount of the discount.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span>\n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span><span class="p">;</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">SportCategoryDiscount</span> <span class="k">implements</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">category</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">;</span>\n <span class="p">}</span>\n \n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.2</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">HomeCategoryDiscount</span> <span class="k">implements</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">category</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">;</span>\n <span class="p">}</span>\n \n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.5</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">FoodCategoryDiscount</span> <span class="k">implements</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">category</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">;</span>\n <span class="p">}</span>\n \n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.1</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then, we need to update the calculator. It will determine whether a discount is applicable to a product and calculate the discount amount. With this approach, you can easily add or remove discount rules as needed.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">DiscountCalculator</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">discounts</span><span class="p">:</span> <span class="nx">Discount</span><span class="p">[])</span> <span class="p">{}</span>\n \n <span class="nx">calculateDiscount</span><span class="p">(</span><span class="nx">basket</span><span class="p">:</span> <span class="nx">Basket</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="kd">let</span> <span class="nx">totalDiscount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>\n \n <span class="nx">basket</span><span class="p">.</span><span class="nx">products</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">discounts</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">discount</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">if</span><span class="p">(</span><span class="nx">discount</span><span class="p">.</span><span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">))</span> <span class="p">{</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">discount</span><span class="p">.</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="p">});</span>\n <span class="p">});</span>\n \n <span class="k">return</span> <span class="nx">totalDiscount</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="c1">// Example usage:</span>\n<span class="nx">it</span><span class="p">.</span><span class="nx">each</span><span class="p">([</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Football</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">20</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Couch</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">100</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Banana</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>\n<span class="p">])(</span><span class="dl">'</span><span class="s1">calculates discounts for %s category</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">,</span> <span class="nx">expectedDiscount</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">product</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Product</span><span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">basket</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Basket</span><span class="p">([</span><span class="nx">product</span><span class="p">]);</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="k">new</span> <span class="nx">DiscountCalculator</span><span class="p">([</span>\n <span class="k">new</span> <span class="nx">SportCategoryDiscount</span><span class="p">(),</span>\n <span class="k">new</span> <span class="nx">HomeCategoryDiscount</span><span class="p">(),</span>\n <span class="k">new</span> <span class="nx">FoodCategoryDiscount</span><span class="p">(),</span>\n <span class="p">]).</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">basket</span><span class="p">)).</span><span class="nx">toBe</span><span class="p">(</span><span class="nx">expectedDiscount</span><span class="p">);</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>We don’t need to over-engineer to apply the open-close principle. With the right design pattern, it is quite simple. Now, the discount calculator is more flexible. We didn’t introduce a lot of new code but we divided the class into smaller ones. Small classes are easier to test and understand, and it will facilitate the maintenance and the evolution of your application.</p>\n\n\n Mon, 13 Nov 2023 00:00:00 -0600\n https://arnolanglade.github.io/open-close-principle.html?s=feed\n https://arnolanglade.github.io/open-close-principle.html\n \n OOP\n \n SOLID\n \n \n \n \n \n The pitfalls of OOP's inheritance: Why simple isn't always better\n <p>In OOP, the simplest way to change the behavior of a class A is to create a class B that extends class A. Extensions allow you to override any public and protected methods of the parent class. That‘s quite simple, right?</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/simple-inheritance.svg" alt="Simple object inheritance" /></p>\n\n<p>Furthermore, you can extend a class multiple times with several levels of inheritance. In the following example, we can see that class B has two children, and the class hierarchy has four levels of inheritance. Now let’s explore why it is not a good idea and which problem can occur?</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/inheritance-with-several-levels.svg" alt="Object inheritance with several levels" /></p>\n\n<p>Designing code like this won’t facilitate refactoring. Let’s consider a scenario where Class A has a method that is overridden in both Class B and Class E. What happens if we decide to change the signature of this method in Class A? We will need to rewrite this method in Class B and Class E to match the new signature. Another frustrating aspect is that we will have to modify all portions of the code that use this method. In a small codebase, this may be manageable, but in a large one, it’s a different story!</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/refactoring-inheritance-with-several-levels.svg" alt="Refactoring with object inheritance with several levels" /></p>\n\n<p>This code won’t ease team collaboration. Let’s consider another scenario: where we are working on a huge monolith shared with several other teams. What happens if team A needs to change class A? That means teams B, C, and D must also update their codebases. We have introduced coupling between these three teams because of the coupling between classes A, B, C, and D. That’s a shame. This design will slow down your delivery because team A will need to coordinate with three other teams if it needs to change class A.</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/refactoring-inheritance-with-several-teams.svg" alt="Refactoring with object inheritance with several teams" /></p>\n\n<p>I have worked on several codebases that heavily relied on inheritance, but now I barely use it due to the drawbacks I’ve described. Instead, I prefer to use composition. It is better to work with several small classes and assemble them, it’s like playing with Lego blocks. Moreover, it greatly simplifies testing.</p>\n\n<p>I try to apply the open-closed principle as much as possible to enhance code modularity and facilitate evolution. In a related blog post, I explain the principle and provide an example to illustrate how to refactor code that doesn’t follow this principle. Here is the link:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/open-close-principle.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/open-close-principle.webp" alt="Open-Closed principle: Enhancing code modularity" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Open-Closed principle: Enhancing code modularity</span>\n </span>\n </a>\n</div>\n\n\n Mon, 23 Oct 2023 00:00:00 -0500\n https://arnolanglade.github.io/oop-inheritance-pitfalls.html?s=feed\n https://arnolanglade.github.io/oop-inheritance-pitfalls.html\n \n OOP\n \n \n \n \n \n Why breaking encapsulation is not a good idea\n <p>In this blog post, I would like to speak about an important concept in Oriented Object Programming which is the encapsulation principle.</p>\n\n<p>Before speaking about encapsulation let’s talk a bit about OOP. What is the object’s life cycle? The first step of the object’s life cycle is to be instantiated. We give everything an object needs to initialise its internal state. Then we use its public API (public methods) to communicate with it. An object exposes a public API (behaviour) that manipulates its internal state (data).</p>\n\n<p><img src="images/posts/why-breaking-encapsulation-is-not-a-good-idea/object-life-cycle.svg" alt="Object life cycle" /></p>\n\n<p>So, what is encapsulation? This principle restricts direct access to the state of the object from outside. This means that the internal implementation details of a class are hidden. Accessing the state of the object is only allowed through its public API (public methods). This concept helps to protect the data from outside interference and ensures controlled and secured data manipulation.</p>\n\n<p><strong>Note:</strong> An object that only has getters and setters is not an object! This is a data structure because it has no behaviour.</p>\n\n<p>I worked on many applications that used getters and setters. They are good examples of what is breaking encapsulation. It is easy to break encapsulation but it is not a good idea. It will make your code less maintainable and your applications less evolutive. Let’s take a simple example to understand why breaking encapsulation is a bad idea. I want to find the closest point of interest on a map close to a given location.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Location</span> <span class="o">=</span> <span class="p">{</span>\n <span class="na">latitude</span><span class="p">:</span> <span class="kr">number</span>\n <span class="na">longitude</span><span class="p">:</span> <span class="kr">number</span>\n<span class="p">}</span>\n\n\n<span class="kd">type</span> <span class="nx">PointOfInterest</span> <span class="o">=</span> <span class="p">{</span>\n <span class="na">name</span><span class="p">:</span> <span class="kr">string</span>\n <span class="na">location</span><span class="p">:</span> <span class="nx">Location</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nb">Map</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">pointOfInterests</span><span class="p">:</span> <span class="nx">PointOfInterest</span><span class="p">[])</span> <span class="p">{}</span>\n\n\n <span class="nx">getPointOfInterests</span><span class="p">():</span> <span class="nx">PointOfInterest</span><span class="p">[]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">pointOfInterests</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">AClassWhereWeNeedToFindClosestPOI</span> <span class="p">{</span>\n <span class="nx">doSomething</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">pointOfInterest</span> <span class="o">=</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getPointOfInterests</span><span class="p">()</span>\n <span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">pointOfInterest</span><span class="p">:</span> <span class="nx">PointOfInterest</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">})[</span><span class="mi">0</span><span class="p">]</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">Map</code> class has a <code class="language-plaintext highlighter-rouge">getPointOfInterest</code> getter that gets the class property with the same name. Then we can use this getter to access the list of points of interest to iterate them and find the closest one.</p>\n\n<p>The drawback with this getter is that we will need to copy/paste this piece of code if we have to look for the closest point of interest in several places. It won’t help you to mutualize code. At best, you can extract this piece of code into a dedicated class like the following example:</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">POIFinder</span> <span class="p">{</span>\n <span class="nx">find</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">):</span> <span class="nx">PointOfInterest</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getPointOfInterests</span><span class="p">()</span>\n <span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">pointOfInterest</span><span class="p">:</span> <span class="nx">PointOfInterest</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">})[</span><span class="mi">0</span><span class="p">]</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The problem with this code is that we extract the <code class="language-plaintext highlighter-rouge">Map</code> object behaviour into another class. We will turn the <code class="language-plaintext highlighter-rouge">Map</code> object into a data structure if we remove all methods that add a behaviour to it.</p>\n\n<p><strong>Note:</strong> A class that ends with -ER (like in the previous example) is a good insight into how this class does the job of another class.</p>\n\n<p>What happens if we need to change the internal of the POI list? Now, we don’t want to use an array anymore, we want to manage the POI list with a custom class named <code class="language-plaintext highlighter-rouge">PointOfInterestList</code>. It might be a simple refactoring for small applications but it is super painful for huge ones. If the getter method is used hundreds of times, we will have to refactor each <code class="language-plaintext highlighter-rouge">getPointOfInterest</code> usage to make them compatible with the new signature.</p>\n\n<p>To avoid this problem, we only need to apply the “Tell, don’t ask” principle. This principle says that we should tell an object to do something instead of asking for its internal state to do something in his stead.</p>\n\n<p>The solution would be to add a <code class="language-plaintext highlighter-rouge">findClosestPointOfInterest</code> method to the <code class="language-plaintext highlighter-rouge">Map</code> object. The only purpose of this method is to find the closest POI no matter how the POI list is designed. This allows you to refactor the internal state of the object as many times you want.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">ListOfPointOfInterest</span> <span class="p">{</span>\n <span class="nx">findClosest</span><span class="p">(</span><span class="nx">location</span><span class="p">:</span> <span class="nx">Location</span><span class="p">)</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nb">Map</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">pointOfInterests</span><span class="p">:</span> <span class="nx">ListOfPointOfInterest</span><span class="p">)</span> <span class="p">{}</span>\n\n\n <span class="nx">findClosestPointOfInterest</span><span class="p">(</span><span class="nx">location</span><span class="p">:</span> <span class="nx">Location</span><span class="p">):</span> <span class="nx">PointOfInterest</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">pointOfInterests</span><span class="p">.</span><span class="nx">findClosest</span><span class="p">(</span><span class="nx">location</span><span class="p">)</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> Breaking encapsulation to test your code is a bad idea too. I’ve written an article to present you with an alternative to the getter to prevent exposing the state of the objects. Here is the link:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/you-should-not-expose-objects-state-to-test-them.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/test-comparison.webp" alt="Why you should not expose objects' state to test them" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Why you should not expose objects' state to test them</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 19 Sep 2023 00:00:00 -0500\n https://arnolanglade.github.io/why-breaking-encapsulation-is-not-a-good-idea.html?s=feed\n https://arnolanglade.github.io/why-breaking-encapsulation-is-not-a-good-idea.html\n \n testing\n \n OOP\n \n \n \n \n \n Don’t test private methods\n <p>It is pretty easy to make mistakes when you start testing your code. One of the first mistakes I made was to test private methods. Spoiler alert: it was a bad idea because I had to use reflection to make them public to access them. If you need to test a private method, it probably means that your code is not well designed</p>\n\n<p>We don’t test private methods. Private methods are implementation details of objects and we should not care about them. Don’t worry! They are tested in the end. When you test public methods you also test the private ones as described in the next schema.</p>\n\n<p><img src="images/posts/do-not-test-private-method/test-private-methods-through-public-ones.svg" alt="Test private methods through public ones" /></p>\n\n<p>I needed to test the private methods because my object was a God object (huge object). It did a lot of things. It had a few public methods and a lot of private ones because too many things happened behind the scenes.</p>\n\n<p><img src="images/posts/do-not-test-private-method/object-with-too-many-private-methods.svg" alt="Object with too many private methods" /></p>\n\n<p>The problem with this design is this object did not follow the <strong>S</strong>ingle <strong>R</strong>esponsibility <strong>P</strong>rinciple, but what is this principle?</p>\n\n<blockquote>\n <p>There should never be more than one reason for a class to change. In other words, every class should have only one responsibility</p>\n\n <p><a href="https://en.wikipedia.org/wiki/SOLID">wikipedia</a></p>\n</blockquote>\n\n<p>My object was super huge because it did too many things. It had too many responsibilities. Because of that, I could not test it easily. How can we avoid that?</p>\n\n<p><img src="images/posts/do-not-test-private-method/complicated-to-test-objects-with-many-responsibilities.svg" alt="complicated to test objects with many responsibilities" /></p>\n\n<p>It’s better to work on small problems than a big one. The solution would have been to identify each responsibility to extract them into dedicated objects. We don’t need magic tricks to test small objects. It is simple to test them because they do a simple thing, and we only need to use their public API (public method) to test them. We don’t need reflection anymore.</p>\n\n<p><img src="images/posts/do-not-test-private-method/split-good-objects-into-small-classes.svg" alt="split good objects into small classes" /></p>\n\n<p>Then, we need to apply the composition pattern to assemble those classes to make them work as the God object. Composition is like playing Lego: we have many small bricks, and we put them together to make a big piece. Software is the same. You should work with small classes/functions to easily test them and piece them together to make your feature.</p>\n\n<p>Let’s take an example. The following class is in charge of importing products into an application as a PIM or an ERP. This class does several things, it gets product data from a CSV file and it imports them into a database. We need to test the whole class to ensure the product import works as expected. That’s a bit annoying because I can’t test the CSV file reading or the production saving.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Product</span> <span class="o">=</span> <span class="p">{</span>\n <span class="na">name</span><span class="p">:</span> <span class="kr">string</span>\n <span class="na">description</span><span class="p">:</span> <span class="kr">string</span>\n<span class="p">};</span>\n\n<span class="kd">class</span> <span class="nx">ProductImport</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">connection</span><span class="p">:</span> <span class="nx">Connection</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">async</span> <span class="k">import</span><span class="p">(</span><span class="nx">filePath</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">loadProductFromCsvFile</span><span class="p">(</span><span class="nx">filePath</span><span class="p">);</span>\n <span class="p">}</span>\n \n <span class="k">private</span> <span class="k">async</span> <span class="nx">loadProductFromCsvFile</span><span class="p">(</span><span class="nx">file</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="na">csvData</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>\n <span class="nx">createReadStream</span><span class="p">(</span><span class="nx">file</span><span class="p">)</span>\n <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">csvParser</span><span class="p">())</span>\n <span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">data</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="na">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">csvData</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">product</span><span class="p">))</span>\n <span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">end</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">data</span> <span class="k">of</span> <span class="nx">csvData</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">saveProducts</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="p">});</span>\n <span class="p">}</span>\n\n <span class="k">private</span> <span class="k">async</span> <span class="nx">saveProducts</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">execute</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">INSERT INTO products (name, description) VALUES (?, ?)</span><span class="dl">'</span><span class="p">,</span>\n <span class="p">[</span><span class="nx">product</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">product</span><span class="p">.</span><span class="nx">description</span><span class="p">],</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>We need to split this class into smaller ones to ease testing. We will extract both private methods into dedicated classes.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">CsvProductLoader</span> <span class="p">{</span>\n <span class="k">async</span> <span class="nx">loadProduct</span><span class="p">(</span><span class="nx">file</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nx">Product</span><span class="p">[]</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="na">products</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>\n <span class="nx">createReadStream</span><span class="p">(</span><span class="nx">file</span><span class="p">)</span>\n <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">csvParser</span><span class="p">())</span>\n <span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">data</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="na">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">products</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">product</span><span class="p">));</span>\n \n <span class="k">return</span> <span class="nx">products</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">MysqlProducts</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">connection</span><span class="p">:</span> <span class="nx">Connection</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">async</span> <span class="nx">save</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">execute</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">INSERT INTO products (name, description) VALUES (?, ?)</span><span class="dl">'</span><span class="p">,</span>\n <span class="p">[</span><span class="nx">product</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">product</span><span class="p">.</span><span class="nx">description</span><span class="p">],</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n<p>Now, we can test them stand-alone because these classes expose public methods. We don’t need a magic trick such as reflection to change their visibility to test them.</p>\n\n<p>We still need the <code class="language-plaintext highlighter-rouge">ProductImport</code> class. It will depend on both previous classes and act as a controller. It asks <code class="language-plaintext highlighter-rouge">CsvProductLoader</code> to get the product information from the CSV file and asks <code class="language-plaintext highlighter-rouge">CsvProductLoader</code> to save them into a database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">ProductImport</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">productLoader</span><span class="p">:</span> <span class="nx">CsvProductLoader</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">MysqlProducts</span><span class="p">,</span>\n <span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">async</span> <span class="k">import</span><span class="p">(</span><span class="nx">filePath</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">products</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">productLoader</span><span class="p">.</span><span class="nx">loadProduct</span><span class="p">(</span><span class="nx">filePath</span><span class="p">);</span>\n <span class="nx">products</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="na">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">products</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span><span class="nx">product</span><span class="p">));</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>That’s great because we extract IO usage into new classes. Both <code class="language-plaintext highlighter-rouge">MysqlProducts</code> and <code class="language-plaintext highlighter-rouge">CsvProductLoader</code> need to be tested with integration/contract tests since <code class="language-plaintext highlighter-rouge">ProductImport</code> can be unit tested.</p>\n\n<p>We need to make a last change. We cannot rely on concrete classes. We need to introduce interfaces to avoid coupling between <code class="language-plaintext highlighter-rouge">ProductImport</code> and its dependencies (<code class="language-plaintext highlighter-rouge">MysqlProducts</code> and <code class="language-plaintext highlighter-rouge">CsvProductLoader</code>).</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">ProductLoader</span> <span class="p">{</span>\n <span class="nx">loadProduct</span><span class="p">(</span><span class="nx">file</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nx">Product</span><span class="p">[]</span><span class="o">&gt;</span>\n<span class="p">}</span>\n\n<span class="kr">interface</span> <span class="nx">Products</span> <span class="p">{</span>\n <span class="nx">save</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">ProductImport</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">productLoader</span><span class="p">:</span> <span class="nx">ProductLoader</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">Products</span><span class="p">,</span>\n <span class="p">)</span> <span class="p">{}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note</strong>: I’ve written an article about how the inversion dependency design pattern will ease testing. Here is the link:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/inversion-dependency/ease-testing-thanks-to-the-dependency-inversion-design-pattern.webp" alt="Ease testing thanks to the dependency inversion design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Ease testing thanks to the dependency inversion design pattern</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 17 Jul 2023 00:00:00 -0500\n https://arnolanglade.github.io/do-not-test-private-methods.html?s=feed\n https://arnolanglade.github.io/do-not-test-private-methods.html\n \n testing\n \n OOP\n \n \n \n \n \n Ease testing thanks to the dependency inversion design pattern\n <p>In this new blog post, I would like to speak about the dependency inversion design pattern. This pattern makes your code more modular and helps to improve codebase testability. It’s quite simple and super powerful.</p>\n<h2 id="what-does-this-design-pattern-say">What does this design pattern say?</h2>\n<p>A class should not depend on another one to avoid coupling them together. If a class is coupled with another one, it means you won’t be able to use the first one without the second one.</p>\n\n<p><img src="images/posts/inversion-dependency/concrete-class-should-not-use-concrete-class.svg" alt="Concrete class should not use concrete class" /></p>\n\n<p>The classes should only depend on abstractions (e.g. interfaces). An interface can be implemented in several ways. It will make your code more modular because you can use a specific implementation depending on the context.</p>\n\n<p><img src="images/posts/inversion-dependency/depend-on-abstraction.svg" alt="Concrete class should depend on abstraction" /></p>\n\n<p>The interfaces should not depend on concrete implementations to avoid coupling them to another class.</p>\n\n<p><img src="images/posts/inversion-dependency/abstraction-should-not-use-concrete-class.svg" alt="Abstraction should not use concrete class" /></p>\n\n<h2 id="how-does-this-pattern-improve-testability">How does this pattern improve testability?</h2>\n\n<p>Let’s see with a simple example how dependency inversion helps to make your code easily testable. The following class lets a cartographer add a marker on a map.</p>\n\n<p><strong>Note:</strong> I wrote an article about unit testing to help you to understand the main mistakes that make your codebase less testable. Here is the link https://arnolanglade.github.io/why-unit-testing-can-be-hard.html.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">AddMarkerToMap</span> <span class="p">{</span>\n <span class="nx">execute</span><span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">repository</span> <span class="o">=</span> <span class="nx">PosgresqlMaps</span><span class="p">.</span><span class="nx">getInstance</span><span class="p">()</span>\n \n <span class="kd">const</span> <span class="nx">map</span> <span class="o">=</span> <span class="nx">repository</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="nx">marker</span><span class="p">.</span><span class="nx">mapId</span><span class="p">)</span>\n \n <span class="nx">map</span><span class="p">.</span><span class="nx">addMarker</span><span class="p">(</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span><span class="p">,</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="p">,</span>\n <span class="p">)</span>\n\n <span class="nx">repository</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">)</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>This class uses a singleton <code class="language-plaintext highlighter-rouge">PosgresqlMaps.getInstance()</code> to retrieve an instance of the <code class="language-plaintext highlighter-rouge">PosgresqlMaps</code> repository. This repository is in charge of saving map data into a PostgreSQL database. The problem is that we cannot run this code without a working database. This class is coupled to the <code class="language-plaintext highlighter-rouge">PosgresqlMaps</code> repository.</p>\n\n<p>We don’t want to use IO (your tools like a database) when we unit-test a piece of code because we want to avoid setting up any tools to a short feedback loop. We only want to check if a section of the application behaves as expected. We don’t want to test if the map data is well stored.</p>\n\n<p>Using the dependency inversion pattern will help us to remove the coupling between <code class="language-plaintext highlighter-rouge">AddMarkerToMap</code> and <code class="language-plaintext highlighter-rouge">PosgresqlMaps</code> and make it easy to unit test.</p>\n\n<p>First, we need to remove the coupling between both classes. We will create an abstraction to define how to retrieve and save maps in the application.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">Maps</span> <span class="p">{</span>\n <span class="kd">get</span><span class="p">(</span><span class="nx">mapId</span><span class="p">:</span> <span class="nx">MapId</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nb">Map</span><span class="o">&gt;</span><span class="p">;</span>\n <span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> When I cannot use a business term to name a repository I pluralize the name of my aggregate to name it. That’s why I name it <code class="language-plaintext highlighter-rouge">Maps</code> because I want to handle map aggregate persistence.</p>\n\n<p>Now, we can create as many implementations as we need. We will create a dedicated implementation for testing purposes. It will only keep it in memory which will avoid using a database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">InMemoryMaps</span> <span class="k">implements</span> <span class="nx">Maps</span> <span class="p">{</span>\n <span class="k">private</span> <span class="nx">maps</span><span class="p">:</span> <span class="nb">Record</span><span class="o">&lt;</span><span class="nx">MapId</span><span class="p">,</span> <span class="nb">Map</span><span class="o">&gt;</span><span class="p">;</span>\n \n <span class="k">async</span> <span class="kd">get</span><span class="p">(</span><span class="nx">mapId</span><span class="p">:</span> <span class="nx">MapId</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nb">Map</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">[</span><span class="nx">mapId</span><span class="p">];</span>\n <span class="p">}</span>\n\n <span class="k">async</span> <span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">[</span><span class="nx">map</span><span class="p">.</span><span class="nx">id</span><span class="p">()]</span> <span class="o">=</span> <span class="nx">map</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> I name all implementations with a prefix depending on what they are. If a repository uses a database, I will prefix the class with the name of the database. When I create an implementation for testing purposes, I use the <code class="language-plaintext highlighter-rouge">InMemory</code> prefix.</p>\n\n<p>As we want to create a working application, we will create an implementation which uses a database for the production environment.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">PosgresqlMaps</span> <span class="k">implements</span> <span class="nx">Maps</span> <span class="p">{</span>\n <span class="c1">// …</span>\n <span class="k">async</span> <span class="kd">get</span><span class="p">(</span><span class="nx">mapId</span><span class="p">:</span> <span class="nx">MapId</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nb">Map</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">map</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span>\n <span class="s2">`SELECT * FROM maps WHERE id = </span><span class="p">${</span><span class="nx">mapId</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span>\n <span class="p">);</span>\n\n\n <span class="k">return</span> <span class="k">new</span> <span class="nb">Map</span><span class="p">(</span><span class="nx">map</span><span class="p">);</span>\n <span class="p">}</span>\n \n <span class="k">async</span> <span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span>\n <span class="s2">`INSERT INTO maps VALUES (</span><span class="p">${</span><span class="nx">map</span><span class="p">.</span><span class="nx">toState</span><span class="p">()}</span><span class="s2">)`</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>We need to refactor a bit the <code class="language-plaintext highlighter-rouge">AddMarkerToMap</code> class to be able to inject an implementation of the <code class="language-plaintext highlighter-rouge">Maps</code> interface.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">AddMarkerToMap</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">maps</span><span class="p">:</span> <span class="nx">Maps</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="nx">execute</span><span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">map</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="nx">marker</span><span class="p">.</span><span class="nx">mapId</span><span class="p">)</span>\n\n\n <span class="nx">map</span><span class="p">.</span><span class="nx">addMarker</span><span class="p">(</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="p">,</span> <span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span>\n <span class="p">)</span>\n \n <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">)</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Finally, we can test this class because we can instantiate the <code class="language-plaintext highlighter-rouge">AddMarkerToMap</code> class with the <code class="language-plaintext highlighter-rouge">InMemoryMaps</code> class. This implementation helps us to test this class because it does not use any IO. Here, we don’t want to test if the data are well persisted but we want to test the business logic of marker addition on a map.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">adds a new marker to the map</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">maps</span> <span class="o">=</span> <span class="nx">InMemoryMaps</span><span class="p">()</span>\n \n <span class="k">new</span> <span class="nx">AddMarkerToMap</span><span class="p">(</span><span class="nx">maps</span><span class="p">).</span><span class="nx">execute</span><span class="p">({</span>\n <span class="na">mapId</span><span class="p">:</span> <span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">,</span> <span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Le Sunset</span><span class="dl">'</span><span class="p">,</span>\n <span class="na">latitude</span><span class="p">:</span> <span class="mf">23.252353245</span><span class="p">,</span> <span class="na">longitude</span><span class="p">:</span> <span class="mf">43.5432563457</span>\n <span class="p">})</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">maps</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span>\n <span class="k">new</span> <span class="nb">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nx">Marker</span><span class="p">(</span><span class="dl">'</span><span class="s1">Le Sunset</span><span class="dl">'</span><span class="p">,</span> <span class="mf">23.252353245</span><span class="p">,</span> <span class="mf">43.5432563457</span><span class="p">)</span>\n <span class="p">)</span>\n <span class="p">)</span>\n<span class="p">})</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> We don’t use a unit test to ensure the application uses its tools well. We use integration tests for this. For instance, if we want to ensure that a repository works as expected.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 19 Jun 2023 00:00:00 -0500\n https://arnolanglade.github.io/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html?s=feed\n https://arnolanglade.github.io/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html\n \n testing\n \n design-pattern\n \n OOP\n \n \n \n \n \n Use composition instead of props drilling\n <p>In this blog post, I would like to speak about how composition can improve your React codebase. It’s easy to add a lot of props to your component to make them configurable but it’s not a good idea.</p>\n\n<p>Let’s take an example. You are working on an e-Commerce webshop. A <code class="language-plaintext highlighter-rouge">ProductList</code> is used in the shop and the shop administration displays a list of products. In the shop administration, the component displays the product information and some calls to action (like product deletion and categorization for example) to manage products. In the shop you only need to display the product information, so, you don’t want to display the calls to action.</p>\n\n<p>As we can see in the next example, most of the <code class="language-plaintext highlighter-rouge">ProductList</code> props are used to render and configure the checkbox or the button.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductList</span><span class="p">({</span>\n <span class="nx">products</span><span class="p">,</span>\n <span class="nx">displayCheckbox</span><span class="p">,</span>\n <span class="nx">displayAction</span><span class="p">,</span>\n <span class="nx">actionLabel</span><span class="p">,</span>\n <span class="nx">onCheckboxClick</span><span class="p">,</span>\n <span class="nx">onActionClick</span><span class="p">,</span>\n<span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">products</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">product</span> <span class="o">=&gt;</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">displayCheckbox</span> <span class="o">&amp;&amp;</span>\n <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="p">=</span><span class="s">"checkbox"</span> <span class="na">onclick</span><span class="p">=</span><span class="si">{</span><span class="nx">onCheckboxClick</span><span class="si">}</span> <span class="p">/&gt;</span> <span class="p">:</span> <span class="kc">null</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">product</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">displayAction</span> <span class="o">&amp;&amp;</span>\n <span class="p">&lt;</span><span class="nt">button</span> <span class="na">onclick</span><span class="p">=</span><span class="si">{</span><span class="nx">onActionClick</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">actionLabel</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> <span class="p">:</span> <span class="kc">null</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n</code></pre></div></div>\n\n<p>This component is used in the <code class="language-plaintext highlighter-rouge">AdminShop</code>and <code class="language-plaintext highlighter-rouge">Shop</code> pages to display the product list to the customer or the shop owner.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Display to shop owner</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">AdminShop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getAllProducts</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span>\n <span class="na">products</span><span class="p">=</span><span class="si">{</span><span class="nx">products</span><span class="si">}</span>\n <span class="na">displayCheckbox</span><span class="p">=</span><span class="si">{</span><span class="kc">true</span><span class="si">}</span>\n <span class="na">displayAction</span><span class="p">=</span><span class="si">{</span><span class="kc">true</span><span class="si">}</span>\n <span class="na">actionLabel</span><span class="p">=</span><span class="s">"delete"</span>\n <span class="na">onCheckboxClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span>\n <span class="na">onActionClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span>\n <span class="p">/&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="c1">// Display to customers</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">Shop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getProductsAvailableforSale</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span>\n <span class="na">products</span><span class="p">=</span><span class="si">{</span><span class="nx">products</span><span class="si">}</span>\n <span class="na">displayCheckbox</span><span class="p">=</span><span class="si">{</span><span class="kc">false</span><span class="si">}</span>\n <span class="na">displayAction</span><span class="p">=</span><span class="si">{</span><span class="kc">false</span><span class="si">}</span>\n <span class="p">/&gt;</span>\n\n\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">ProductList</code> has to display elements depending on the given props. This big component will help mutualize the code but it will introduce complexity. Adding too many props will make your components complex, and hard to understand and maintain. Composition will help us to get rid of those props.</p>\n\n<p><strong>Note:</strong> The <code class="language-plaintext highlighter-rouge">ProductList</code> component only has 3 props because I wanted to keep the example simple but guess what happens when your components have tens of props to configure them?</p>\n\n<p>How can composition help us? It’s like playing Lego. You need several bricks from different sizes and colors to create something. The big <code class="language-plaintext highlighter-rouge">ProductList</code> component can be split into several small components used to build the product list depending on business cases.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductList</span><span class="p">({</span><span class="nx">children</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">children</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">Product</span><span class="p">({</span><span class="nx">label</span><span class="p">,</span> <span class="nx">checkbox</span><span class="p">,</span> <span class="nx">action</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">checkbox</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">label</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">action</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductCheckbox</span><span class="p">({</span><span class="nx">onClick</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="p">=</span><span class="s">"checkbox"</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span><span class="p">/&gt;;</span>\n<span class="p">}</span>\n\n\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductAction</span><span class="p">({</span><span class="nx">onClick</span><span class="p">,</span> <span class="nx">actionLabel</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">&lt;</span><span class="nt">button</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">actionLabel</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>In the previous code example, we created 4 new components: <code class="language-plaintext highlighter-rouge">ProductList</code>, <code class="language-plaintext highlighter-rouge">Product</code>, <code class="language-plaintext highlighter-rouge">ProductCheckbox</code> and <code class="language-plaintext highlighter-rouge">ProductAction</code>. They are like Lego bricks and we can assemble them to create the product list with or without the call to action.</p>\n\n<p><strong>Note:</strong> It’s not mandatory to create a dedicated component for the checkbox and the button. It can be useful to wrap generic components into more business-oriented ones. It helps to make things clearer. It’s another way to apply composition.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Display to shop owner</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">AdminShop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getAllProducts</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">products</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">product</span> <span class="o">=&gt;</span> \n <span class="p">&lt;</span><span class="nc">Product</span>\n <span class="na">label</span><span class="p">=</span><span class="si">{</span><span class="nx">product</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span>\n <span class="na">checkbox</span><span class="p">=</span><span class="si">{</span><span class="p">&lt;</span><span class="nc">ProductCheckbox</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span> <span class="p">/&gt;</span><span class="si">}</span>\n <span class="na">action</span><span class="p">=</span><span class="si">{</span><span class="p">&lt;</span><span class="nc">ProductAction</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span> <span class="na">actionLabel</span><span class="p">=</span><span class="si">{</span><span class="dl">"</span><span class="s2">delete</span><span class="dl">"</span><span class="si">}</span> <span class="p">/&gt;</span><span class="si">}</span>\n <span class="p">/&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="c1">// Display to customers</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">Shop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getProductAvailableforSale</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">products</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">product</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nc">Product</span> <span class="na">label</span><span class="p">=</span><span class="si">{</span><span class="nx">product</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span> <span class="p">/&gt;)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Small components are easier to test. They help build more stable applications and are easier to maintain. Your codebase will be less complex to understand. It will decrease your and your teammates’ mental load because you won’t have any components with complex API and logic.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 22 May 2023 00:00:00 -0500\n https://arnolanglade.github.io/use-composition-instead-of-props-drilling.html?s=feed\n https://arnolanglade.github.io/use-composition-instead-of-props-drilling.html\n \n react\n \n testing\n \n \n \n \n \n How to use custom React hook to increase application testability\n <p>In my previous blog, I spoke about reducing coupling in a React app to improve testing. Now I will show you how a custom React hook can increase testability.</p>\n\n<p><strong>Note:</strong> I assume that you are comfortable with React hooks. If you aren’t, please have a look at the <a href="https://reactjs.org/docs/hooks-intro.html">React documentation</a></p>\n\n<p>First of all, I will show you some code that is not testable. In my <a href="https://mymaps.world">side project</a>, I use <code class="language-plaintext highlighter-rouge">react-map-gl</code> to create maps with <a href="https://www.mapbox.com/">Mapbox</a>. Unfortunately, I can’t render the map with the testing library because this library only works in a web browser. I might have done something wrong but I haven’t found any solution to solve this problem.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">MapPage</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span><span class="nx">mapId</span><span class="p">}</span> <span class="o">=</span> <span class="nx">useParams</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">mapId</span><span class="p">:</span> <span class="kr">string</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">();</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">markers</span><span class="p">,</span> <span class="nx">setMarkers</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">isMarkerOpened</span><span class="p">,</span> <span class="nx">setIsMarkerOpened</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setMarkers</span><span class="p">(</span><span class="nx">getMarkers</span><span class="p">(</span><span class="nx">mapId</span><span class="p">));</span>\n <span class="p">},</span> <span class="p">[</span><span class="nx">mapId</span><span class="p">]);</span>\n\n\n <span class="kd">const</span> <span class="nx">openMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">closeMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;&gt;</span>\n <span class="p">&lt;</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">markers</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span>\n <span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nc">Marker</span>\n <span class="na">longitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span><span class="si">}</span>\n <span class="na">latitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="si">}</span>\n <span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerIcon</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">openMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">Marker</span><span class="p">&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerPopup</span> <span class="na">isOpened</span><span class="p">=</span><span class="si">{</span><span class="nx">isMarkerOpened</span><span class="si">}</span> <span class="na">onClose</span><span class="p">=</span><span class="si">{</span><span class="nx">closeMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/&gt;</span>\n <span class="p">)</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><code class="language-plaintext highlighter-rouge">MapPage</code> is in charge of loading map data depending on the <code class="language-plaintext highlighter-rouge">mapId</code> and rendering a map with its markers. I can’t test the <code class="language-plaintext highlighter-rouge">MapBoard</code> component because the <code class="language-plaintext highlighter-rouge">ReactMapGL</code> component can’t be rendered through the test tooling. That’s sad because I still want to check if I can open the marker popup when a user clicks on a marker.</p>\n\n<p>React will help us to fix this issue! We need to refactor this component to extract the business logic into a hook. This way, the component will only be responsible for rendering things. Let’s begin by creating the hooks.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="nx">mapId</span><span class="p">,</span> <span class="p">{</span><span class="nx">defaultIsMarkerOpened</span><span class="p">}</span> <span class="o">=</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">false</span><span class="p">})</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">markers</span><span class="p">,</span> <span class="nx">setMarkers</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">isMarkerOpened</span><span class="p">,</span> <span class="nx">setIsMarkerOpened</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="nx">defaultIsMarkerOpened</span><span class="p">);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setMarkers</span><span class="p">(</span><span class="nx">getMarkers</span><span class="p">(</span><span class="nx">mapId</span><span class="p">));</span>\n <span class="p">},</span> <span class="p">[</span><span class="nx">mapId</span><span class="p">]);</span>\n\n\n <span class="kd">const</span> <span class="nx">openMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">closeMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n\n\n <span class="k">return</span> <span class="p">{</span>\n <span class="nx">markers</span><span class="p">,</span>\n <span class="nx">isMarkerOpened</span><span class="p">,</span>\n <span class="nx">closeMarkerPopup</span><span class="p">,</span>\n <span class="nx">openMarkerPopup</span><span class="p">,</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n<p>The hook exposes two variables: <code class="language-plaintext highlighter-rouge">markers</code> which is an array of map’s markers and <code class="language-plaintext highlighter-rouge">isMarkerOpened</code> which is a boolean that indicates if the popup is opened or closed. It exposes two functions, <code class="language-plaintext highlighter-rouge">openMarkerPopup</code> and <code class="language-plaintext highlighter-rouge">closeMarkerPopup</code> that let us mutate the <code class="language-plaintext highlighter-rouge">isMarkerOpened</code> boolean.</p>\n\n<p><strong>Note:</strong> We could only expose <code class="language-plaintext highlighter-rouge">setIsMarkerOpened</code> but I think <code class="language-plaintext highlighter-rouge">openMarkerPopup</code> and <code class="language-plaintext highlighter-rouge">closeMarkerPopup</code> function names are clearer and match the component logic.</p>\n\n<p>Now, we need to call the hook from the <code class="language-plaintext highlighter-rouge">MapPage</code> component and it will still work as before.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">MapPage</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span>\n <span class="nx">markers</span><span class="p">,</span>\n <span class="nx">isMarkerOpened</span><span class="p">,</span>\n <span class="nx">closeMarkerPopup</span><span class="p">,</span>\n <span class="nx">openMarkerPopup</span>\n <span class="p">}</span> <span class="o">=</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="nx">mapId</span><span class="p">);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;&gt;</span>\n <span class="p">&lt;</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">markers</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span>\n <span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nc">Marker</span>\n <span class="na">longitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span><span class="si">}</span>\n <span class="na">latitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="si">}</span>\n <span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerIcon</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">openMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">Marker</span><span class="p">&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerPopup</span> <span class="na">isOpened</span><span class="p">=</span><span class="si">{</span><span class="nx">isMarkerOpened</span><span class="si">}</span> <span class="na">onClose</span><span class="p">=</span><span class="si">{</span><span class="nx">closeMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/&gt;</span>\n <span class="p">)</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">MapPage</code> is still untestable but we can start testing the hook to ensure hook logic matches business expectations. We can test if we can open a marker’s popup. That’s great because the testing library provides the <code class="language-plaintext highlighter-rouge">renderHook</code> helper that eases the hook testing.</p>\n\n<p><strong>Note:</strong> If you want to know how <code class="language-plaintext highlighter-rouge">renderHook</code> works you should have a look at this <a href="https://kentcdodds.com/blog/how-to-test-custom-react-hooks">blog post</a> written by <a href="https://twitter.com/kentcdodds">Kent C. Dodds</a>.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">describe</span><span class="p">(</span><span class="dl">'</span><span class="s1">Map Page</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">should open the marker popup</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span> <span class="nx">result</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">renderHook</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">useMapPage</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">false</span><span class="p">}</span>\n <span class="p">));</span>\n \n <span class="nx">act</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">openMarkerPopup</span><span class="p">());</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">isMarkerOpened</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n <span class="p">});</span>\n\n\n <span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">should close the marker popup</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span> <span class="nx">result</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">renderHook</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">useMapPage</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">true</span><span class="p">}</span>\n <span class="p">));</span>\n \n <span class="nx">act</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">closeMarkerPopup</span><span class="p">());</span>\n\n <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">isMarkerOpened</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n <span class="p">});</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>As I said at the beginning of this blog post I wrote a blog post to explain how to reduce coupling in a React application. Please, have a look at this <a href="/how-to-reduce-coupling-in-your-react-app.html">blog post</a> to understand how to make a dependency injection system.</p>\n\n<p>Now, we need to remove the <code class="language-plaintext highlighter-rouge">getMarkers</code> function call from the hooks if we want to test the map data loading. We don’t want to trigger side effects like HTTP calls in the unit test suite because we want to have the shortest feedback loop. We will get the <code class="language-plaintext highlighter-rouge">getMarkers</code> function to <code class="language-plaintext highlighter-rouge">useServiceContainer</code> which is a hook that provides any services.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="nx">mapId</span><span class="p">,</span> <span class="p">{</span><span class="nx">defaultIsMarkerOpened</span><span class="p">}</span> <span class="o">=</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">false</span><span class="p">})</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span><span class="nx">getMarkers</span><span class="p">}</span> <span class="o">=</span> <span class="nx">useServiceContainer</span><span class="p">();</span>\n <span class="c1">// ...</span>\n \n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setMarkers</span><span class="p">(</span><span class="nx">getMarkers</span><span class="p">(</span><span class="nx">mapId</span><span class="p">));</span>\n <span class="p">},</span> <span class="p">[</span><span class="nx">mapId</span><span class="p">]);</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>By default, the <code class="language-plaintext highlighter-rouge">useServiceContainer</code> hooks return the production services, we will need to replace the <code class="language-plaintext highlighter-rouge">getMarkers</code> service with a fake service for testing purposes. The <code class="language-plaintext highlighter-rouge">useServiceContainer</code> hooks can’t work without a React Provider. I like to create a factory that wraps components I test with all needed providers. It avoids a lot of noise in the test suites and makes tests more readable.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">const</span> <span class="nx">createWrapper</span> <span class="o">=</span> <span class="p">(</span><span class="nx">serviceContainer</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="kd">function</span> <span class="nx">Wrapper</span><span class="p">(</span>\n <span class="p">{</span> <span class="nx">children</span> <span class="p">}:</span> <span class="p">{</span> <span class="nl">children</span><span class="p">:</span> <span class="nx">ReactElement</span> <span class="p">},</span>\n<span class="p">)</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span> <span class="na">value</span><span class="p">=</span><span class="si">{</span><span class="nx">serviceContainer</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">};</span>\n</code></pre></div></div>\n\n<p>Note: the factory has a parameter which is the service container. It will let us define the services we want to override for testing.</p>\n\n<p>The <code class="language-plaintext highlighter-rouge">renderHook</code> has a <code class="language-plaintext highlighter-rouge">wrapper</code> option that lets you define the component that will wrap the hook you are testing. We will use the <code class="language-plaintext highlighter-rouge">createWrapper</code> factory to wrap the hook into the <code class="language-plaintext highlighter-rouge">ContainerContext</code> provider and we create a fake <code class="language-plaintext highlighter-rouge">getMarkers</code> service.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">describe</span><span class="p">(</span><span class="dl">'</span><span class="s1">Map Page</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">should load the markers of the map</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">markers</span> <span class="o">=</span> <span class="p">[{</span><span class="na">id</span><span class="p">:</span> <span class="dl">'</span><span class="s1">makerId</span><span class="dl">'</span><span class="p">}];</span>\n <span class="kd">const</span> <span class="p">{</span> <span class="nx">result</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">renderHook</span><span class="p">(</span>\n <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">),</span>\n <span class="p">{</span><span class="na">wrapper</span><span class="p">:</span> <span class="nx">createWrapper</span><span class="p">({</span><span class="na">getMarkers</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">markers</span><span class="p">})}</span>\n <span class="p">);</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">markers</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="nx">markers</span><span class="p">);</span>\n <span class="p">});</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>Now, the <code class="language-plaintext highlighter-rouge">getMarkers</code> is predictable. That means we can test the map loading because the <code class="language-plaintext highlighter-rouge">getMarker</code> function will return <code class="language-plaintext highlighter-rouge">[{id: 'makerId'}]</code> every time.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 04 Apr 2023 00:00:00 -0500\n https://arnolanglade.github.io/how-to-use-custom-react-hook-to-increase-application-testability.html?s=feed\n https://arnolanglade.github.io/how-to-use-custom-react-hook-to-increase-application-testability.html\n \n react\n \n testing\n \n \n \n \n \n How to reduce coupling in your React app\n <p>Today, I would like to cover dependency injection in React. I worked with several frameworks using tools to build and inject dependencies. It is pretty convenient if you apply the dependency inversion principle because you can easily change a dependency with another one.</p>\n\n<p>I will start by briefly introducing what is a React Context and I will then show you how to solve coupling problems in a React application.</p>\n\n<h2 id="what-is-a-react-context">What is a React Context?</h2>\n\n<blockquote>\n <p>Context provides a way to pass data through the component tree without having to pass props down manually at every level.</p>\n\n <p><a href="https://reactjs.org/docs/context.html">React documentation</a></p>\n</blockquote>\n\n<p>Let’s take an example: several components display the username of the user who is connected. We have to pass the username as props to every application component that needs this information. It is annoying, but React context can help for this specific use case.</p>\n\n<p>First, we need to create a context:</p>\n\n<p>```ts self-taught\nconst UserContext = React.createContext<string>();</string></p>\n<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\nThen, we need to wrap our components using a context provider and give it a value. The value is the data we want to share with the provider’s children components.\n\n```tsx\nfunction App() {\n return (\n &lt;UserContext.Provider value={'arn0'}&gt;\n &lt;Toolbar /&gt;\n &lt;OtherComponent /&gt;\n &lt;/UserContext.Provider&gt;\n );\n}\n</code></pre></div></div>\n\n<p>Finally, we can get this value (the username) from the context thanks to the useContext hooks.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">Toolbar</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">username</span> <span class="o">=</span> <span class="nx">useContext</span><span class="p">(</span><span class="nx">UserContext</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>\n Welcome <span class="si">{</span><span class="nx">username</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n</code></pre></div></div>\n<h2 id="which-problems-coupling-brings">Which problems coupling brings?</h2>\n\n<blockquote>\n <p>Coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)">Wikipedia</a></p>\n</blockquote>\n\n<p>The developer’s worst enemy is <strong>coupling</strong> because it makes your code less testable. To illustrate what I am saying we will take an example: a to-do list application. The <code class="language-plaintext highlighter-rouge">TodoList</code> component is responsible for retrieving data from the server and building the list of tasks to do.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">findTasks</span> <span class="o">=</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/tasks</span><span class="dl">'</span><span class="p">);</span>\n<span class="p">}</span>\n\n<span class="kd">function</span> <span class="nx">TodoList</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">setTasks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="o">&lt;</span><span class="nx">Task</span><span class="p">[]</span><span class="o">&gt;</span><span class="p">([]);</span>\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="p">(</span><span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">findTasks</span><span class="p">();</span>\n <span class="nx">setTasks</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>\n <span class="p">})();</span>\n <span class="p">},</span> <span class="p">[]);</span>\n \n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">task</span><span class="p">:</span> <span class="nx">Task</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nt">li</span> <span class="na">key</span><span class="p">=</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The problem with the <code class="language-plaintext highlighter-rouge">TodoList</code> component is that it depends on the <code class="language-plaintext highlighter-rouge">axios</code> library to get data from the server. It does not ease testing because we need to set up the server to make this component work. Unit testing requires a short feedback loop! We need to find a way to get rid of this HTTP call. It would be great to be able to do HTTP calls in production but using stub for testing.</p>\n\n<h2 id="how-react-context-reduces-coupling">How React Context reduces coupling?</h2>\n\n<p>The problem with the <code class="language-plaintext highlighter-rouge">TodoList</code> component is that we should be able to use several implementations of the <code class="language-plaintext highlighter-rouge">findTasks</code>, but we can’t with its design. We need an implementation for the production that will make an HTTP call and another one for testing that will return stub.</p>\n\n<p>The <code class="language-plaintext highlighter-rouge">findTasks</code> function should not be hardcoded but it should be injected as a component dependency. A React Context will help us to solve that issue.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">ServiceContainer</span> <span class="o">=</span> <span class="p">{</span><span class="na">findTasks</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nx">Task</span><span class="o">&gt;</span><span class="p">};</span>\n\n<span class="kd">const</span> <span class="nx">ContainerContext</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createContext</span><span class="o">&lt;</span><span class="nx">ServiceContainer</span><span class="o">&gt;</span><span class="p">({}</span> <span class="k">as</span> <span class="nx">ServiceContainer</span><span class="p">);</span>\n\n<span class="k">export</span> <span class="kd">const</span> <span class="nx">useServiceContainer</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">useContext</span><span class="p">(</span><span class="nx">ContainerContext</span><span class="p">);</span>\n\n<span class="kd">const</span> <span class="nx">findTasks</span> <span class="o">=</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/tasks</span><span class="dl">'</span><span class="p">);</span>\n<span class="p">}</span>\n\n<span class="kd">function</span> <span class="nx">App</span><span class="p">()</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span> <span class="na">value</span><span class="p">=</span><span class="si">{</span><span class="nx">findTasks</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">TodoList</span><span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">ServiceContainer</code> type represents all services we want to register in our application. The <code class="language-plaintext highlighter-rouge">ContainerContext</code> will share those services with <code class="language-plaintext highlighter-rouge">ContainerContext.Provider</code> children.</p>\n\n<p>Then, we only need to get the <code class="language-plaintext highlighter-rouge">findTasks</code> function from the React Context.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">TodoList</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span><span class="nx">findTasks</span><span class="p">}</span> <span class="o">=</span> <span class="nx">useServiceContainer</span><span class="p">();</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">setTasks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="o">&lt;</span><span class="nx">Task</span><span class="p">[]</span><span class="o">&gt;</span><span class="p">([]);</span>\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="p">(</span><span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">findTasks</span><span class="p">();</span>\n <span class="nx">setTasks</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>\n <span class="p">})();</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">task</span><span class="p">:</span> <span class="nx">Task</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nt">li</span> <span class="na">key</span><span class="p">=</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, the code is testable because we can easily replace the <code class="language-plaintext highlighter-rouge">findTasks</code> by stub in the test suite. We can easily set up a test because this new function does not use HTTP calls.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">render the todo list</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">render</span><span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span> <span class="na">value</span><span class="p">=</span><span class="si">{</span>\n <span class="p">{</span> <span class="na">findTasks</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">({</span><span class="na">id</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="na">label</span><span class="p">:</span> <span class="dl">'</span><span class="s1">label</span><span class="dl">'</span><span class="p">})</span> <span class="p">}</span>\n <span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">TodoList</span><span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span><span class="p">&gt;</span>\n <span class="p">)</span>\n\n <span class="c1">// …</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 06 Mar 2023 00:00:00 -0600\n https://arnolanglade.github.io/how-to-reduce-coupling-in-your-react-app.html?s=feed\n https://arnolanglade.github.io/how-to-reduce-coupling-in-your-react-app.html\n \n react\n \n design-patterns\n \n \n \n \n \n What is the difference between CQS and CQRS patterns?\n <p>I recently found out that I did not grasp those design patterns. There are a lot of resources on the Internet about them but they are not always accurate. That’s a shame because they are pretty simple. I will share my understanding of them with you.</p>\n\n<h2 id="what-is-command-query-segregation-cqs">What is Command Query Segregation (CQS)?</h2>\n\n<blockquote>\n <p>The fundamental idea is that we should divide an object’s methods into two sharply separated categories:</p>\n <ul>\n <li>Queries: Return a result and do not change the observable state of the system (are free of side effects).</li>\n <li>Commands: Change the state of a system but do not return a value.</li>\n </ul>\n\n <p><a href="https://martinfowler.com/bliki/CommandQuerySeparation.html">Martin Fowler</a></p>\n</blockquote>\n\n<p>This concept is not specific to Object Oriented Programming but improves the object’s design. The object methods only have a single purpose: reading or changing the object state. We can see an object as a living entity. We can ask a question to someone because we need information. For example, we can ask someone what time it is. This is a query. We can ask someone to do something, we don’t expect an answer but we want to get the job done. For example, we can ask a child to finish his/her spinach. This is a command.</p>\n\n<p>We can apply this pattern to any object: like an aggregate. Let’s take an example! I would like to add markers on a map and then I would like to find which markers are the closest to a specific location (GPS Coordinates).\nk</p>\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nb">Map</span> <span class="p">{</span>\n <span class="nx">addMarker</span><span class="p">(</span><span class="nx">label</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">latitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="k">void</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n\n <span class="nx">findClosestMarkers</span><span class="p">(</span><span class="nx">location</span><span class="p">:</span> <span class="nx">Location</span><span class="p">):</span> <span class="nx">Marker</span><span class="p">[]</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">addMarker</code> method is in charge of mutating the object state without returning any result, while the ‘findClosestMarkers’ method finds the right markers without changing the object’s state. This object follows the CQS definition.</p>\n\n<p>Let’s go further. If we design our aggregates following the CQS pattern, we should apply it to the classes that handle use cases.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">MapService</span> <span class="p">{</span>\n <span class="nx">addMarkerToTheMap</span><span class="p">(</span><span class="nx">label</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">latitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">);</span> <span class="k">void</span>\n <span class="nx">findAllMarkersCloseToLocation</span><span class="p">():</span> <span class="nx">Marker</span><span class="p">[]</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>This ensures there is no inconsistency in the codebase. The business services use and manipulate the aggregates. For example, if the <code class="language-plaintext highlighter-rouge">MapService.addMarkerToTheMap</code> method returns a result, it might mean that the <code class="language-plaintext highlighter-rouge">Map.addMarker</code> method will need to return the expected result.</p>\n\n<h2 id="what-is-command-query-responsibility-segregation-cqrs">What is Command Query Responsibility Segregation (CQRS)?</h2>\n\n<blockquote>\n <p>Starting with CQRS, CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).</p>\n\n <p><a href="https://web.archive.org/web/20190211113420/http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-sourcing-agh/">Greg young</a></p>\n</blockquote>\n\n<p><strong>Note:</strong> Greg Young’s blog does not exist anymore but his blog posts are still available thanks to archived.org.</p>\n\n<p>CQRS is the separation of command and query into two different objects instead of only one. MapService does not follow the CQRS pattern because it has a query and a command. We need to cut this object in half.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">MapReadService</span> <span class="p">{</span>\n <span class="nx">addMarkerToTheMap</span><span class="p">(</span><span class="nx">label</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">latitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">);</span> <span class="k">void</span>\n<span class="p">}</span>\n\n<span class="kr">interface</span> <span class="nx">MapWriteService</span> <span class="p">{</span>\n <span class="nx">findAllMarkersCloseToLocation</span><span class="p">():</span> <span class="nx">Marker</span><span class="p">[]</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>That’s pretty simple, right? Anyway, we don’t need to introduce complicated things in our application to use this tactical design pattern. We don’t need a write and a read model,\na command and query bus, an event sourcing architecture or multiple databases. Greg Young published this blog post in 2012 to explain what CQRS was not about.</p>\n\n<blockquote>\n <p>CQRS is not a silver bullet\nCQRS is not a top level architecture\nCQRS is not new\nCQRS is not shiny\nCQRS will not make your jump shot any better\nCQRS is not intrinsically linked to DDD\nCQRS is not Event Sourcing\nCQRS does not require a message bus\nCQRS is not a guiding principle / CQS is\nCQRS is not a good wife\nCQRS is learnable in 5 minutes\nCQRS is a small tactical pattern\nCQRS can open many doors.</p>\n</blockquote>\n\n<p><strong>Note:</strong> This blog does not exist anymore but it has been archived by archived.org. The post is available <a href="https://web.archive.org/web/20160729165044/https://goodenoughsoftware.net/2012/03/02/cqrs/">here</a></p>\n\n<p>Depending on the number of use cases the service classes can become really huge. CQRS helps to decrease their size but I am a big fan of them. I like to separate each use case into a dedicated class.</p>\n\n<p>I’ve written a blog post to explain what is a commands and we can apply it to query too:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-handler-patterns.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-handler/command-handler.webp" alt="Command and command handler design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Command and command handler design pattern</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 06 Feb 2023 00:00:00 -0600\n https://arnolanglade.github.io/what-is-the-difference-between-cqs-and-cqrs-patterns.html?s=feed\n https://arnolanglade.github.io/what-is-the-difference-between-cqs-and-cqrs-patterns.html\n \n software-architecture\n \n design-patterns\n \n \n \n \n \n Hexagonal architecture by example\n <p>In this blog post, I would like to explain the basics of hexagonal architecture thanks to a simple example: a product catalogue. The catalogue manager can add new products through a user interface and the nightly cron task imports new products from the ERP.</p>\n\n<p>Before going deeper into hexagonal architecture, let’s see what we need to create the product management application. We need two entry points: the first one will be consumed by the graphical client and the other one will be used by the cron task. Then, we will need another piece of code which will be in charge of persisting product data into storage.</p>\n\n<p><img src="images/posts/hexagonal-architecture/application-architecture.svg" alt="Application architecture" /></p>\n\n<h2 id="what-is-hexagonal-architecture">What is hexagonal architecture?</h2>\n\n<blockquote>\n <p>The hexagonal architecture, or ports and adapters architecture, is an architectural pattern used in software design. It aims at creating loosely coupled application components that can be easily connected to their software environment by means of ports and adapters. This makes components exchangeable at any level and facilitates test automation.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Hexagonal_architecture_(software)">Wikipedia</a></p>\n</blockquote>\n\n<p>There are three main areas in the hexagonal architecture:\nThe <strong>primary adapters (user interface)</strong> are the whole application entry points that can be consumed by clients like a UI or a CLI.\nThe <strong>secondary adapters (infrastructure)</strong> connect the application to tools like the database, file system, etc.\nThe <strong>domain</strong> is all pieces of code that represent the problem we are solving. This part must be side-effect free (it must not use any tools).</p>\n\n<h2 id="domain">Domain</h2>\n\n<p>The domain is the area where we solve our business problems no matter the technical constraints. We can start by designing the product aggregate.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Name</span> <span class="o">=</span> <span class="kr">string</span><span class="p">;</span>\n<span class="kd">type</span> <span class="nx">Description</span> <span class="o">=</span> <span class="kr">string</span><span class="p">;</span>\n\n<span class="k">export</span> <span class="kd">class</span> <span class="nx">Product</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">name</span><span class="p">:</span> <span class="nx">Name</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">description</span><span class="p">:</span> <span class="nx">Description</span>\n <span class="p">)</span> <span class="p">{}</span>\n\n <span class="nx">toState</span><span class="p">():</span> <span class="kr">string</span><span class="p">[]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">description</span><span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>As I said, we need to save products into the database but we don’t mind if the database is PostgreSQL, MySQL or whatever in the domain. We will define an <strong>abstraction (an interface)</strong> to avoid accessing any technical asset from the domain. This interface which is called a <strong>port</strong> will specify how to store a new product from a business point of view. This is nothing more than applying the dependency inversion design pattern.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kr">interface</span> <span class="nx">ProductCatalog</span> <span class="p">{</span>\n <span class="nx">add</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="k">void</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h3 id="what-about-testing">What about testing?</h3>\n\n<p>Moving IO as far as possible from your domain code is really convenient because it eases unit testing. We will mainly test this part of the application with unit testing. It offers a very short feedback loop, it will help you to design your domain step by step without setting up the whole application.</p>\n\n<p><strong>Tip:</strong> I’ve written a blog post about unit testing that explains why testing can be hard. It mainly gives you tips to move IO outside your code to make it testable.</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="why-unit-testing-can-be-hard.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/why-unit-testing-can-be-hard.webp" alt="Why unit testing can be hard?" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Why unit testing can be hard?</span>\n </span>\n </a>\n</div>\n\n<h3 id="coupling-rules">Coupling rules</h3>\n\n<p>The domain code must not use any IO: any tools like your database, randomness, or actual datetime, nor depend on the primary and the secondary adapters. We will explain what they are in the next sections.</p>\n\n<h2 id="secondary-adapters-infrastructure">Secondary adapters (Infrastructure)</h2>\n\n<p>The secondary or driven adapters implement the ports defined in the domain. In our example, the adapter will be a <code class="language-plaintext highlighter-rouge">PostgresProductCatalog</code> class that implements the <code class="language-plaintext highlighter-rouge">ProductCatalog</code> interface (port). Its purpose will be to store product data in a database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">PostgresProductCatalog</span> <span class="k">implements</span> <span class="nx">ProductCatalog</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">pg</span><span class="p">:</span> <span class="nx">Client</span><span class="p">)</span> <span class="p">{}</span>\n\n <span class="nx">add</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">pg</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">INSERT INTO product (name, properties) VALUES ($1, $2)</span><span class="dl">'</span><span class="p">,</span>\n <span class="nx">product</span><span class="p">.</span><span class="nx">toState</span><span class="p">()</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>An advantage of this architecture is that we can simply delay choices. At the beginning of a project, it may be hard to choose the right tools because you still need to learn and understand the business. In that case, you can implement an in-memory adapter, it will work the same way as the previous one but it will only keep product aggregate in memory.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">InMemoryProductCatalog</span> <span class="k">implements</span> <span class="nx">ProductCatalog</span> <span class="p">{</span>\n <span class="k">private</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[];</span>\n\n <span class="nx">add</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">products</span> <span class="o">=</span> <span class="p">[</span><span class="nx">product</span><span class="p">,</span> <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">products</span><span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> This adapter can be used in your test suites because it lets you bypass your tools constraints like foreign key constraints when we use a database, for instance.</p>\n\n<h3 id="what-about-testing-1">What about testing?</h3>\n\n<p>The part of the application is mainly covered by “integration” or “contract” tests. Those tests ensure that the tools used by the application work as expected. For example, you are able to save and query your database.</p>\n\n<p><strong>Tip:</strong> I encourage you to test all implementations of a given port with the same test because it will ensure they work the same way.</p>\n\n<h3 id="coupling-rules-1">Coupling rules</h3>\n\n<p>The infrastructure code only depends on the domain code.</p>\n\n<h2 id="primary-adapters-user-interface">Primary adapters (User interface)</h2>\n\n<p>The primary adapters or driving adapters are entry points that describe how the application is consumed by the clients. Their purpose is to tell the domain what to do. Actually, it can be a Web controller or CLI command for instance.</p>\n\n<p>In our example, we need two adapters: a web controller and a CLI command. Both of them will execute the same action, they will save product data but they have different input and output. The first one takes JSON and returns an HTTP response and the second one takes input and returns code status.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">try</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">productCatalog</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="k">new</span> <span class="nx">Product</span><span class="p">(</span>\n <span class="nx">request</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">),</span> <span class="c1">// get name argument for cli command</span>\n <span class="nx">request</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">description</span><span class="dl">'</span><span class="p">),</span> <span class="c1">// get description argument for cli command</span>\n <span class="p">))</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">HttpResponse</span><span class="p">(</span><span class="mi">201</span><span class="p">);</span> <span class="c1">// return 0 for cli command</span>\n<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nb">Error</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nx">HttpResponse</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span> <span class="c1">// return 1 for cli command</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>As you see, the only differences are the input and output of the adapter. We need to refactor this code to avoid duplication between both primary adapters. It should be extracted into a dedicated business service.</p>\n\n<p><strong>Tip:</strong> These business services can be written using the command and command handler patterns. I’ve written a blog post that explains these design patterns:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-handler-patterns.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-handler/command-handler.webp" alt="Command and command handler design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Command and command handler design pattern</span>\n </span>\n </a>\n</div>\n\n<p>I’ve written a bunch of articles about how to handle a command, validate its data, handle user permissions, and so on. Take a look at these articles:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/tag/command-bus">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/data-validation.webp" alt="See all blog posts about command handling." />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">See all blog posts about command handling.</span>\n </span>\n </a>\n</div>\n\n<h3 id="what-about-testing-2">What about testing?</h3>\n\n<p>There are several ways to test primary adapters.</p>\n\n<p>First option: the easiest one, your application only has one primary adapter. I advise you to write an acceptance test that boots the application and checks that the whole application works for each business use case.</p>\n\n<p>Second option: the complex one, your application has several primary adapters like our example (web and CLI). I advise you to check that your command handler works as expected thanks to an acceptance. That way you ensure your handler will work as expected for both adapters. Thus, you can write a test to ensure that the adapters return the right output (HTTP response or code status) depending on the case.</p>\n\n<h3 id="coupling-rules-2">Coupling rules</h3>\n\n<p>The user interface code only depends on the domain code.</p>\n\n<h2 id="flow-of-control">Flow of control</h2>\n\n<p><img src="images/posts/hexagonal-architecture/hexgonal-architecture-flow-control.svg" alt="Hexgonal architecture: flow control" /></p>\n\n<p>The application flow goes from the user interface <strong>(1)</strong> through the domain <strong>(2)</strong> to the infrastructure <strong>(3)</strong> then goes back through the domain <strong>(2)</strong> to the user interface <strong>(4)</strong>.</p>\n\n<p>Example: The UI sends data to an HTTP controller <strong>(1)</strong>, then a product aggregate is created <strong>(2)</strong>, then the repository saves data into the database <strong>(3)</strong>, and finally the web controller sends a 200 HTTP response <strong>(4)</strong>. We don’t need step <strong>(2)</strong> because nothing happens in the domain after the product creation.</p>\n\n<h2 id="code-organization">Code organization</h2>\n\n<p>The <strong>domain</strong> contains the aggregates, ports, business services and so on. Most importantly, they must not use IO and must be business oriented.</p>\n\n<p>The <strong>infrastructure</strong> contains all secondary adapters that use external tools (IO) like your database.</p>\n\n<p>The <strong>user interface</strong> contains all primary adapters that are the application entry points. Users and machines use them to interact with the application.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>src\n├── domain\n│ ├── ProductCatalog.ts\n│ └── Product.ts\n├── infra\n│ ├── InMemoryProductCatalog.ts\n│ └── PostgresProductCatalog.ts\n└── user-interface\n ├── CliCreateProduct.ts\n └── WebCreateProduct.ts\n</code></pre></div></div>\n\n<p><strong>Note:</strong> I decided to split each class/interface into a dedicated module because I wanted to show you where things are. Feel free to organize your module as you wish.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 09 Jan 2023 00:00:00 -0600\n https://arnolanglade.github.io/hexagonal-architect-by-example.html?s=feed\n https://arnolanglade.github.io/hexagonal-architect-by-example.html\n \n software-architecture\n \n \n \n \n \n What is the event sourcing pattern?\n <p>Event sourcing consists in storing all changes that happened to an application as a sequence of events instead of only storing the current state of the application. The sum of all events is the current application state. When I heard about this pattern a few years ago, I was really confused. I used to only persist the current application state in a database and that was fine! So I asked myself do I need that?</p>\n\n<p>I will show you an example to help you understand what this pattern stands for. People used to explain it with a bank account but I wanted to find something funnier: a table soccer game. A complete example is available on a Github repository:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="https://github.com/arnolanglade/table-soccer">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/github-logo.png" alt="Have a look at the GitHub repository" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Have a look at the GitHub repository</span>\n </span>\n </a>\n</div>\n\n<p>Let’s start! A group of developers who are fans of table soccer wants to create an application to see who’s the best player. They decided to save the results of matches and rank themselves.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">redTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">blueTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">gameScore</span><span class="p">:</span> <span class="nx">Score</span><span class="p">,</span>\n <span class="p">)</span> <span class="p">{}</span>\n\n <span class="k">public</span> <span class="nx">recordScore</span><span class="p">(</span><span class="nx">redPlayerScore</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">bluePlayerScore</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">,</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">,</span>\n <span class="k">new</span> <span class="nx">Score</span><span class="p">(</span><span class="nx">redPlayerScore</span><span class="p">,</span> <span class="nx">bluePlayerScore</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n\n <span class="c1">// example: ['arn0', 'momos', 'Popeye', 'coco', 10, 1]</span>\n <span class="k">public</span> <span class="nx">toState</span><span class="p">():</span> <span class="p">[</span><span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">,</span> <span class="kr">number</span><span class="p">,</span> <span class="kr">number</span><span class="p">]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">[</span>\n <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">.</span><span class="nx">toState</span><span class="p">(),</span>\n <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">.</span><span class="nx">toState</span><span class="p">(),</span>\n <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">gameScore</span><span class="p">.</span><span class="nx">toState</span><span class="p">()</span>\n <span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">Game</code> Aggregate has a <code class="language-plaintext highlighter-rouge">recordScore</code> method to record the score at the end of the game. Then we get the current state of <code class="language-plaintext highlighter-rouge">Game</code> with the <code class="language-plaintext highlighter-rouge">toState</code> method to save it in the database.</p>\n\n<p>That works perfectly for the one versus one games but what happens for two versus two games? Let’s focus on one of the players, we will call him Popeye. Actually, Popeye is not a really good player even if he is full of goodwill. He is smart, he always wants to play with the best player to have more chances to win. We cannot know who is the best player with only the result of the game. Who has really scored? Popeye or its teammate?</p>\n\n<p>Event sourcing is the solution. Instead of saving the score of the game, we will store what really happens. We will refactor the <code class="language-plaintext highlighter-rouge">Game</code> aggregate to make it compliant with the event sourcing pattern.</p>\n\n<p>First, we will rework the aggregate construction. We still want to encapsulate its current state but we want to record all events that happened too. In the following example, we added an <code class="language-plaintext highlighter-rouge">events</code> argument to the primary constructor and a named constructor (secondary construct) called <code class="language-plaintext highlighter-rouge">start</code> to the <code class="language-plaintext highlighter-rouge">Game</code> class. From a business point of view, its goal is to initialize the game and from a technical point of view, it lets us record the <code class="language-plaintext highlighter-rouge">GameStarted</code> event.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">redTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">blueTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">gameScore</span><span class="p">:</span> <span class="nx">Score</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">events</span><span class="p">:</span> <span class="nx">Event</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[]</span>\n <span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">public</span> <span class="k">static</span> <span class="nx">start</span><span class="p">(</span>\n <span class="nx">redAttacker</span><span class="p">:</span> <span class="nx">Player</span><span class="p">,</span>\n <span class="nx">redDefender</span><span class="p">:</span> <span class="nx">Player</span><span class="p">,</span>\n <span class="nx">blueAttacker</span><span class="p">:</span> <span class="nx">Player</span><span class="p">,</span>\n <span class="nx">blueDefender</span><span class="p">:</span> <span class="nx">Player</span>\n <span class="p">):</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">redTeam</span> <span class="o">=</span> <span class="nx">Team</span><span class="p">.</span><span class="nx">ofTwoPlayer</span><span class="p">(</span><span class="nx">redAttacker</span><span class="p">,</span> <span class="nx">redDefender</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">blueTeam</span> <span class="o">=</span> <span class="nx">Team</span><span class="p">.</span><span class="nx">ofTwoPlayer</span><span class="p">(</span><span class="nx">blueAttacker</span><span class="p">,</span> <span class="nx">blueDefender</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span>\n <span class="nx">redTeam</span><span class="p">,</span>\n <span class="nx">blueTeam</span><span class="p">,</span>\n <span class="nx">Score</span><span class="p">.</span><span class="nx">playersHaveNotScored</span><span class="p">(),</span>\n <span class="p">[</span><span class="k">new</span> <span class="nx">GameStarted</span><span class="p">(</span><span class="nx">redTeam</span><span class="p">,</span> <span class="nx">blueTeam</span><span class="p">)],</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then we will add a new method to <code class="language-plaintext highlighter-rouge">Game</code> to record all goals scored by any players. That will let us know who is the best striker in the game. In the following example, we record two events: <code class="language-plaintext highlighter-rouge">GoalScored</code> and <code class="language-plaintext highlighter-rouge">GameEnded</code>. The first one is recorded every time a player scores and the second one is recorded when the first team has 10 points meaning the game is over.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span> \n <span class="c1">// …</span>\n <span class="k">public</span> <span class="nx">goalScoredBy</span><span class="p">(</span><span class="nx">player</span><span class="p">:</span> <span class="nx">Player</span><span class="p">):</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">teamColor</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">.</span><span class="nx">isTeammate</span><span class="p">(</span><span class="nx">player</span><span class="p">)</span> <span class="p">?</span> <span class="nx">TeamColor</span><span class="p">.</span><span class="nx">Red</span> <span class="p">:</span> <span class="nx">TeamColor</span><span class="p">.</span><span class="nx">Blue</span><span class="p">;</span>\n <span class="kd">const</span> <span class="nx">gameScore</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">gameScore</span><span class="p">.</span><span class="nx">increase</span><span class="p">(</span><span class="nx">teamColor</span><span class="p">);</span>\n\n <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">GoalScored</span><span class="p">(</span><span class="nx">teamColor</span><span class="p">,</span> <span class="nx">player</span><span class="p">,</span> <span class="nx">gameScore</span><span class="p">))</span>\n\n <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">gameScore</span><span class="p">.</span><span class="nx">canIncrease</span><span class="p">(</span><span class="nx">teamColor</span><span class="p">))</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">GameEnded</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">,</span> <span class="nx">gameScore</span><span class="p">))</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">,</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">,</span>\n <span class="nx">gameScore</span><span class="p">,</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">,</span>\n <span class="p">);</span>\n <span class="p">}</span>\n <span class="c1">// …</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> We can drop the <code class="language-plaintext highlighter-rouge">recordScore</code> method because we won’t want to only record the score of the game at the end of the game.</p>\n\n<p>Finally, the last thing to refactor is the persistence mechanism. We need to rework the <code class="language-plaintext highlighter-rouge">toState</code> because we won’t store a snapshot of the <code class="language-plaintext highlighter-rouge">Game</code> state but we want to save all events raised during the game. This method will return all serialized events and metadata like the name of the aggregate. Normally, we should persist some extra metadata like the aggregate id or the date when the event has been raised. Then, those data will be used in the <code class="language-plaintext highlighter-rouge">Game</code> repository to persist changes in the database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span> \n <span class="c1">// …</span>\n <span class="k">public</span> <span class="nx">toState</span><span class="p">():</span> <span class="p">[[</span><span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">]]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">event</span><span class="p">:</span> <span class="nx">Event</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="dl">'</span><span class="s1">Game</span><span class="dl">'</span><span class="p">,</span> <span class="nx">event</span><span class="p">.</span><span class="nx">toState</span><span class="p">()]);</span>\n <span class="p">}</span>\n <span class="c1">// …</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Last thing, we will add a named constructor to be able to build the object from the persisted state (a list of events). The <code class="language-plaintext highlighter-rouge">fromEvents</code> will iterate on all events to compute and set the current state of a game.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span> \n <span class="c1">// …</span>\n <span class="k">public</span> <span class="k">static</span> <span class="nx">fromEvents</span><span class="p">(</span><span class="nx">events</span><span class="p">:</span> <span class="nx">Event</span><span class="p">[]):</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">let</span> <span class="nx">redTeam</span><span class="p">,</span> <span class="nx">blueTeam</span><span class="p">,</span> <span class="nx">score</span><span class="p">;</span>\n <span class="nx">events</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">event</span><span class="p">:</span> <span class="nx">Event</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">switch</span> <span class="p">(</span><span class="kc">true</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">case</span> <span class="nx">event</span> <span class="k">instanceof</span> <span class="na">GameStarted</span><span class="p">:</span>\n <span class="nx">redTeam</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">;</span>\n <span class="nx">blueTeam</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">;</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="k">case</span> <span class="nx">event</span> <span class="k">instanceof</span> <span class="na">GameEnded</span><span class="p">:</span>\n <span class="nx">score</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">score</span><span class="p">;</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="p">});</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span><span class="nx">redTeam</span><span class="p">,</span> <span class="nx">blueTeam</span><span class="p">,</span> <span class="nx">score</span><span class="p">,</span> <span class="nx">events</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="c1">// …</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, we have all the data we need to know if Popeye really helps his teammate. In the following code example, we can see that Momos and arn0 were not in a good shape. Coco and Popeye won easily but we can see that Popeye did not score. Perhaps, he is a good defender, who knows?</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">game</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">startTwoVersusTwo</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Popeye</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n</code></pre></div></div>\n\n<p>I explained to you how to save <code class="language-plaintext highlighter-rouge">Game</code> aggregate events and create the aggregate from events in the previous sections of the blog post. The last missing feature is the leaderboard! How to create it? It won’t be as simple as querying a SQL table in the database because we need to get all game events for each game and compute them to know who is the better striker. Even though it can be fast in the beginning, the more games you have, the longer it will be.</p>\n\n<p>To prevent this problem, we need to create data projections. That means we will compute a representation of the data we want to query from the event stream. We will compute the new projection of the leaderboard each time a game ends.</p>\n\n<p>Last but not least, We often associate CQRS with the event sourcing pattern even if there are two different patterns.</p>\n\n<p>Don’t forget that a complete example is available on a Github repository.</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="https://github.com/arnolanglade/table-soccer">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/github-logo.webp" alt="Have a look at the GitHub repository" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Have a look at the GitHub repository</span>\n </span>\n </a>\n</div>\n\n<p>Any resemblance to real and actual names is purely coincidental!</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 28 Nov 2022 00:00:00 -0600\n https://arnolanglade.github.io/what-is-the-event-sourcing-pattern.html?s=feed\n https://arnolanglade.github.io/what-is-the-event-sourcing-pattern.html\n \n software-architecture\n \n \n \n \n \n My feedback about example mapping\n <p>Example mapping is a workshop that gathers tech and non-tech people to ensure everyone has the same understanding of the domain problem. It also helps clarify the acceptance criteria for a given story. Because it’s always better to understand what is expected and raise all bottlenecks before developing a story.</p>\n\n<p>Disclaimer! I won’t explain how to run such a workshop, you can easily find a bunch of articles on the web. You can also have a look at <a href="/agile-tour-rennes-example-mapping.html">these slides</a>, they come from one of my talks about example mapping if you’re not familiar with it. In this blog article, I want to share with you my experience on Example Mapping and how it helps me to prepare and organize the team’s work.</p>\n\n<p><strong>Caution:</strong> A little while ago, I got feedback from <a href="https://twitter.com/brunoboucard">Bruno Boucard</a> about using sticky notes. He advised me to use index cards instead of sticky notes. The workshop attendees can put them on a table and easily move them, unlike stick notes. I speak about sticky notes in this blog post because I only practiced this workshop remotely using tools like <a href="https://www.miro.com">Miro</a>.</p>\n\n<h2 id="who-will-attend-the-workshop">Who will attend the workshop?</h2>\n\n<p>The methodology recommends to involve at least the product managers, developers and testers. The goal of example mapping is that the product manager shares the problem with the person(s) who will solve it. I will go further, you can invite anyone who wants to understand what you are doing. It is a good way to share knowledge.</p>\n\n<p>During my last year at Akeneo, I worked on a new product called Shared Catalogs. All my teammates including devs, product manager, and engineering managers were newcomers. Even if they were really well onboarded on Akeneo’s products, they had a micro vision of what Akeneo PIM did, and the software’s functional perimeter was pretty huge. At this time, I was working at Akeneo for 4 years, andI had a good understanding of the product. During the example mapping sessions I shared as much knowledge as possible with my teammates, it helped the team to quickly improve their functional skills.</p>\n\n<h2 id="when-do-we-plan-it">When do we plan it?</h2>\n\n<p>From my experience, a 30-minute slot is a good tradeoff. It’s not too long and you can easily illustrate the main business rules of the story and detect all bottlenecks. With a 30-minute meeting, you’re sure that your teammates will stay focused, especially when you work remotely. Having regular and short workshops is better than doing a big and long one.</p>\n\n<p>Depending on their roles, some team members can be really busy. For instance, I worked with several PMs who were often in meetings and it was really hard to catch them. To be sure that everyone can be available, each team member booked a 30 minutes slot after the daily meeting. Doing an example mapping was not mandatory, we only did the workshop if we needed to prepare stories.</p>\n\n<h2 id="how-organize-the-team">How organize the team</h2>\n\n<p>The attendees can have different roles: onek person writes sticky notes, another animates the workshop and the others ask questions and drive the person who writes sticky notes. I think it is important to switch his/her role each session to keep everyone involved during the workshop.</p>\n\n<p>I worked with some product managers and domain experts who wanted to contribute and write sticky notes. It is not a good idea because they should focus on sharing the knowledge and let the rest of the team grasp the business expectations. You won’t help someone if you do his/her job.</p>\n\n<h2 id="how-to-start">How to start</h2>\n\n<p>Writing the title of a story on a yellow sticky note is pretty simple but I sometimes had difficulties getting the business rules and the examples listed. Especially, when you are doing this workshop with a team for the first time. I found out that it was easier to sometimes start by writing the example first or sometimes by writing the business rules first.</p>\n\n<p>First option: start by writing the business rules and then write the examples if your team is comfortable with the exercise and your product manager has a clear vision of what is expected.</p>\n\n<p>Second option: start by writing examples and then extract business rules from examples if your team is not comfortable with the workshop or if your product manager needs to explore a topic and he/she waits for your feedback. It will let you and your teammates speak, and understand what is going on. When you have enough examples and your understanding of business is better you can extract the business rules.</p>\n\n<p>Don’t be afraid if it is a bit complicated to be efficient in the beginning. One day, my teammates and I prepared a story about exporting a CSV file, quite simple, right? We only needed to “take data from the DB and build a file” but it wasn’t that simple! We turned this “simple” story into at least 15 stories. We discovered a lot of “hidden” business rules. We thought it was a story but it was an epic…</p>\n\n<h2 id="how-to-write-example">How to write example</h2>\n\n<p>Don’t try to write gherkins scenarios at all costs because it can be time-consuming. The goal of this workshop is to ensure all teammates grasp what the business expects and it is the right time to raise all problems and incomprehension.</p>\n\n<p>The simplest format I used to define the example looked like the Given / When / Then but a really simplified version.</p>\n\n<p><img src="images/posts/example-mapping/write-simple-exmaple.webp" alt="Simplified gherkins" /></p>\n\n<p>Sometimes it can be more readable to draw something.</p>\n\n<p><img src="images/posts/example-mapping/draw-example.webp" alt="Draw examples" /></p>\n\n<p>Don’t limit yourself, if you prefer another format, use it. The most important thing is that everyone understands what is expected.</p>\n\n<h2 id="dont-forget-red-sticky-notes">Don’t forget red sticky notes</h2>\n\n<p>Avoid endless debates! Don’t hesitate to use red sticky notes if your teammates disagree on something. Keep in mind that your product manager can’t answer all questions during the workshops. It’s normal, the product manager is not a super(wo)man! Thus, add a red sticky note and take time to think about it, he/she’ll answer all questions in the next session.</p>\n\n<h2 id="have-small-stories">Have small stories</h2>\n\n<p>I like to talk with the PM when the story is ready to be developed (when there are no more red stickies and when all teammates are OK with it). I usually challenge him/her to know which business rules are really mandatory and which ones are nice-to-have. It ensures your stories are really small and it eases the prioritization. You can focus on what is really important and keep what is nice-to-have for later.</p>\n\n<p><strong>Tip:</strong> If your story has too many business rules, it’s a smell! That means you should split it into small ones. It will be easier to ship several small stories than a big one. If a business rule has too many examples, that’s a smell too. You might have missed some business rules.</p>\n\n<p><img src="images/posts/example-mapping/split-story.webp" alt="Split story into small ones" /></p>\n\n<p>I am not a big fan of estimates, it’s a waste of time. We should focus on understanding the problem we want to solve, instead of giving figures that will probably be wrong. Having a really small story will help you to be more predictive. You can count the stories done during a time frame and easily forecast what your team will be able to do during the next iteration.</p>\n\n<h2 id="final-thoughts">Final thoughts</h2>\n\n<p>The first example mapping workshop can be complex but don’t give up. The more you practice, the more comfortable your team will be with the workshop. Example mapping is a good way to align the team’s understanding with the stakeholders expectations. It will help your team to better collaborate and break all silos between all kinds of positions in your team. Last but not least, it will help you refine your stories and improve your backlog prioritization.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 31 Oct 2022 00:00:00 -0500\n https://arnolanglade.github.io/my-feedback-about-example-mapping.html?s=feed\n https://arnolanglade.github.io/my-feedback-about-example-mapping.html\n \n BDD\n \n methodology\n \n \n \n \n \n How I have learned programming by myself\n <p>I am, what we call, a self-taught. I studied telecommunications and networks at school, unfortunately, I only learned the basics of programming. I had to learn and improve my skills by myself for many years during my free time. I did not take the easiest path to learn! That’s why I wanted to share with you my own experience and what I did to learn software development. I hope this post will help some of you.</p>\n\n<h2 id="find-a-mentor">Find a mentor</h2>\n\n<p>In the beginning, even though I knew some basics of programming I was a bit lost. I wasn’t able to build an application end to end and I did not know which subject I had to study to solve that. That’s why I advise junior engineers to find at least one mentor. A mentor can teach you what is important like how to test, design patterns, software architecture, and so on. A mentor will help you focus on the right topics like how to build robust applications instead of focusing on hype technologies.</p>\n\n<p><strong>Tip:</strong> If you’re a junior, I would recommend you focus on testing: TDD will help you to design your code step by step. Architectural patterns like hexagonal architecture will help you to decouple your code from IO. Agile: eXtreme programming will help you to reduce the cost of changes by having multiple short development cycles rather than a long one.</p>\n\n<h2 id="play-and-have-fun-with-a-side-project">Play and have fun with a side project</h2>\n\n<p>You can have strong constraints at work, so it can be really hard to try new things because of bad processes, bad code quality, impossible deadlines etc. I have worked on several side projects for the last 10 years. I tried twice to release an application for a French NGO to manage their volunteer data. Then I tried to make an application to organize my trips. The last one is about making maps to remember places I have been. I learned a lot from those projects, they let me try what I read in blog posts, books or what I saw in conferences without any pressure of production. The funny thing is that I learned more from failures. Only my last side project <a href="https://mymaps.world">“mymaps”</a> is live, I did not release the other ones! This is because they were only playgrounds rather than real projects. They helped me understand why being pragmatic is important, focusing only on technical aspects does not help to build an application. Keep in mind that a good codebase is not the only thing you need to make a successful project.</p>\n\n<h2 id="contribute-to-an-open-source-project">Contribute to an open-source project</h2>\n\n<p>I worked on <a href="https://sylius.com">Sylius</a> which is an open-source e-commerce framework. The community of Sylius is great. I learned a lot of good practices like testing, code review and behaviour-driven development for instance. I mainly worked on the <code class="language-plaintext highlighter-rouge">SyliusResourceBundle</code> which is a library that eases CRUD management. During this period, I was working for a web agency, it helped me to be more efficient at work and ship projects faster.</p>\n\n<p><strong>Caution:</strong> Many companies use open-source projects but they don’t contribute to them. I was happy to contribute to this project during my free time, but you should negotiate allocated time with your company to help those projects if they help you deliver value to your customers.</p>\n\n<p>I would like to thank <a href="https://pjedrzejewski.com">Pawel</a> for making me a core team member. Contributing to Sylius has opened many doors to me.</p>\n\n<p>Thanks to what I have done in that library, I had the chance to do my first conference (<a href="https://live.symfony.com/2015-paris">Symfony live</a>) as a speaker. That was so great! I was so excited and terrified at the same time. Then I got hired by a french startup <a href="https://www.akeneo.com/">Akeneo</a> to work on an open-source PIM (Product Information Management). I only worked for service companies before Akeneo, this experience made me discover what was software edition.</p>\n\n<h2 id="attend-conferences-and-meetups">Attend conferences and meetups</h2>\n\n<p>Attending conferences is a great way to learn and open your mind to new things. You can have a chat with other attendees during breaks as well. It is a good way to meet new people and to have interesting talks. One of my favourite conferences is <a href="http://www.ncrafts.io">newcraft</a>, its local edition at <a href="https://bordeaux.ncrafts.io/">Bordeaux</a> was really great too.</p>\n\n<p>When you will be comfortable the next step will be to do a presentation. Preparing a talk is good to dive into the topic you will present and formalize your ideas. Even if you know this topic, it may not be that easy to clearly explain it to someone else. Don’t be shy, submit your talks! A lot of conference organizations help new speakers. I did not think too much when I submitted my first talk. I thought it wouldn’t be selected but I received an email that said my talk was accepted. I was so happy and excited! I realized what happened and I really started to panic (true story, a little panic attack) so I started to work on my talk to be ready for D-day. You can have a look at <a href="http://arnolanglade.github.io/talks.html">my talks</a>.</p>\n\n<h2 id="read-books">Read books</h2>\n\n<p>Another way to learn is through books. This is a good way to shut down your computer while still learning new things about software engineering.</p>\n\n<p><strong>Tip:</strong> Some books in my library: <a href="https://www.oreilly.com/library/view/accelerate/9781457191435/">Accelerate</a>, <a href="https://www.oreilly.com/library/view/extreme-programming-explained/0201616416/">Extreme Programming Explained</a>, <a href="https://www.oreilly.com/library/view/domain-driven-design-distilled/9780134434964/">Domain-Driven Design Distilled</a>, <a href="https://www.oreilly.com/library/view/patterns-principles-and/9781118714706/">Patterns, Principles, and Practices of Domain-Driven Design</a>, <a href="https://www.yegor256.com/elegant-objects.html">Elegant Objects</a> and so on.</p>\n\n<h2 id="final-thoughts">Final thoughts</h2>\n\n<p>A few weeks ago, I saw some software engineers saying on social media that we should self-train in our free time. Learning in your free time will help you progress faster but it can be time and energy consuming. Don’t forget that burnouts are real. One of my friends experienced burnout and couldn’t do anything for almost a year, he was completely out of energy.</p>\n\n<p>I also had to take several breaks in my learning process to avoid going to the dark side of the force. <strong>Only do things when you want in your free time! Don’t put pressure on yourself!</strong> And keep in mind that learning should be fun!</p>\n\n<p>Learning is a part of your job. Companies should let you learn during business hours. On a day-to-day basis, pair and mob programming is a good way to learn and challenge your ideas. Your company should train you as well. For instance, <a href="https://matthiasnoback.nl">Mathias Noback</a> gave us some training when I was at Akeneo. I learned a lot from him, and I definitely recommend him!</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 17 Oct 2022 00:00:00 -0500\n https://arnolanglade.github.io/how-I-have-learned-programming-by-myself.html?s=feed\n https://arnolanglade.github.io/how-I-have-learned-programming-by-myself.html\n \n learning\n \n \n \n \n \n Increase your test quality thanks to builders or factories\n <p>In a previous <a href="http://arnolanglade.github.io/you-should-not-expose-objects-state-to-test-them.html">blog post</a>, I explained why it’s better to compare object instances instead of exposing their state to test them. This avoids breaking encapsulation and it does not have any impact on their design.</p>\n\n<p>Let’s take an example! My side project allows me to create maps to remember places I have been. A map has a name and, as a cartographer, I am allowed to rename it. Real basic use case but more than enough! The following test ensures I can rename this map:</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="s1">'Pepito'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="s1">'Bordeaux city'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="s1">'Good places in Anglet'</span><span class="p">),</span>\n <span class="nc">Tag</span><span class="o">::</span><span class="nf">city</span><span class="p">(),</span>\n <span class="nc">MarkerList</span><span class="o">::</span><span class="nb">empty</span><span class="p">(),</span>\n<span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">);</span>\n\n<span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span>\n <span class="nv">$map</span><span class="p">,</span>\n <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="s1">'Pepito'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="s1">'Good places in Anglet'</span><span class="p">),</span>\n <span class="nc">Tag</span><span class="o">::</span><span class="nf">city</span><span class="p">(),</span>\n <span class="nc">MarkerList</span><span class="o">::</span><span class="nb">empty</span><span class="p">(),</span>\n <span class="p">)</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p>We can see that comparing object instances is great for encapsulation because we don’t expose the object’s state but this makes the test less readable. Here, the only thing we want to focus on is the value of <code class="language-plaintext highlighter-rouge">MapName</code>. The values of the other value object are only noise because they are not useful for this test. But, this is not the only drawback of this test. What happens if you want to add an extra property to the <code class="language-plaintext highlighter-rouge">Map</code> object? In this case, we will need to refactor all the tests that create a map object. It might be easily doable in small projects but it can become messy for big ones.</p>\n\n<p>Now, let’s show how we can improve this test. The title of my blogpost can give you a huge hint on the solution. We will add a named constructor called <code class="language-plaintext highlighter-rouge">whatever</code> to the <code class="language-plaintext highlighter-rouge">Map</code> object to centralize the object construction. Named constructors are static factories that build the object itself.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Map</span> \n<span class="p">{</span>\n <span class="cd">/** @internal */</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">whatever</span><span class="p">(</span>\n <span class="kt">string</span> <span class="nv">$mapId</span> <span class="o">=</span> <span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$addedBy</span> <span class="o">=</span> <span class="s1">'Pepito'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$name</span> <span class="o">=</span> <span class="s1">'Anglet city'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$description</span> <span class="o">=</span> <span class="s1">'Good places in Anglet'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$tag</span> <span class="o">=</span> <span class="s1">'city'</span><span class="p">,</span>\n <span class="kt">array</span> <span class="nv">$markers</span> <span class="o">=</span> <span class="p">[],</span>\n <span class="p">):</span> <span class="kt">self</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="nv">$mapId</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$addedBy</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$name</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="nv">$description</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Tag</span><span class="p">(</span><span class="nv">$tag</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MarkerList</span><span class="p">(</span><span class="nv">$markers</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> I like to add a <code class="language-plaintext highlighter-rouge">@internal</code> annotation to remind all teammates that the object constructor should only be used in tests.</p>\n\n<p>The value object instantiation is delegated to the <code class="language-plaintext highlighter-rouge">whatever</code> constructor. I try to use primitive data types like arguments as much as possible, it makes me write less code and it’s easier to read. All constructor arguments have a default value, then I can override a given value depending on the needs thanks to the named argument feature.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">whatever</span><span class="p">(</span><span class="n">name</span><span class="o">:</span> <span class="s1">'Bordeaux city'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">);</span>\n\n<span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span>\n <span class="nv">$map</span><span class="p">,</span>\n <span class="nc">Map</span><span class="o">::</span><span class="nf">whatever</span><span class="p">(</span><span class="n">name</span><span class="o">:</span> <span class="s1">'Anglet city'</span><span class="p">)</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p>Now, the test is clear and focuses on the right thing. Everyone can easily understand it, and it will help your teammates to grasp the code you wrote. Refactoring will be simplified as you only have to rewrite the <code class="language-plaintext highlighter-rouge">whatever</code> constructor if the signature of the primary constructor of <code class="language-plaintext highlighter-rouge">Map</code> changes.</p>\n\n<p>I know that some people won’t like the idea of adding a method to objects only for testing purposes. If you don’t like that, you can replace this static factory with a builder.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MapBuilder</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$mapId</span> <span class="o">=</span> <span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$addedBy</span> <span class="o">=</span> <span class="s1">'Pepito'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$name</span> <span class="o">=</span> <span class="s1">'Anglet city'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$description</span> <span class="o">=</span> <span class="s1">'Good places in Anglet'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$tag</span> <span class="o">=</span> <span class="s1">'city'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">array</span> <span class="nv">$markers</span> <span class="o">=</span> <span class="p">[];</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">identifiedBy</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span> <span class="o">=</span> <span class="nv">$mapId</span><span class="p">;</span>\n \n <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">named</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$name</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>\n\n <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="c1">// ... other setters ....</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">build</span><span class="p">():</span> <span class="kt">Map</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">addedBy</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">description</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Tag</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">tag</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MarkerList</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markers</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then your test will look like this:</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="p">(</span><span class="k">new</span> <span class="nc">MapBuilder</span><span class="p">())</span><span class="o">-&gt;</span><span class="nf">named</span><span class="p">(</span><span class="s1">'Bordeaux city'</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">();</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">);</span>\n\n<span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span>\n <span class="nv">$map</span><span class="p">,</span>\n <span class="p">(</span><span class="k">new</span> <span class="nc">MapBuilder</span><span class="p">())</span><span class="o">-&gt;</span><span class="nf">named</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">()</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> Read or anemic models don’t have logic to ensure they are built in a good way. If you use this method for them you can add some logic to your builder/factories to ensure they are created with consistent data. It will make your tests stronger.</p>\n\n<h2 id="final-thought">Final thought</h2>\n\n<p>Builders or factories ease test refactoring and make tests more readable. Don’t forget that bad test suites are a nightmare to maintain and can drastically slow down your delivery. Taking care of your test quality will help you to ship fast. Moreover, good tests are free documentation.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 10 Oct 2022 00:00:00 -0500\n https://arnolanglade.github.io/increase-your-test-quality-thanks-to-builders-or-factories.html?s=feed\n https://arnolanglade.github.io/increase-your-test-quality-thanks-to-builders-or-factories.html\n \n testing\n \n \n \n \n \n How to handle user permissions through command bus middleware\n <p>Applying user permissions might be very complex and can lead to introducing a lot of accidental complexity to your application. In this blog post, I want to share with you how to do it by simply adding a middleware to your command bus.</p>\n\n<p><strong>Note:</strong> If you’re not familiar with this pattern, please have a look at this <a href="http://arnolanglade.github.io/command-bus-design-pattern.html">blog post</a>, it explains what a command bus and a middleware are.</p>\n\n<p>Let’s imagine a basic use case: an application with two kinds of users: regular ones and admins. We want to allow certain actions only to admin users.</p>\n\n<p>First, I will introduce an interface <code class="language-plaintext highlighter-rouge">OnlyPerformedByAdministrator</code> that will be implemented by the command restricted to the admin users.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">interface</span> <span class="nc">OnlyPerformedByAdministrator</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">username</span><span class="p">():</span> <span class="kt">string</span><span class="p">;</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">CreateNewProduct</span> <span class="kd">implements</span> <span class="nc">OnlyPerformedByAdministrator</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">username</span><span class="p">():</span> <span class="kt">string</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then, we will add a <code class="language-plaintext highlighter-rouge">CheckAccessPermission</code> middleware to the command bus that will check if the user can execute an action. If he/she can’t, an <code class="language-plaintext highlighter-rouge">AccessDenied</code> exception will be thrown. It will be caught later in the execution flow to be turned into something that will be understandable to the user.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">AccessDenied</span> <span class="k">extends</span> <span class="err">\\</span><span class="nc">Exception</span>\n<span class="p">{</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">CheckAccessPermission</span> <span class="kd">implements</span> <span class="nc">Middleware</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">private</span> <span class="nc">Users</span> <span class="nv">$users</span><span class="p">)</span> <span class="p">{}</span>\n\n <span class="k">final</span> <span class="k">public</span> <span class="k">function</span> <span class="n">handle</span><span class="p">(</span><span class="kt">Command</span> <span class="nv">$command</span><span class="p">,</span> <span class="kt">Middleware</span> <span class="nv">$next</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$user</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">users</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">username</span><span class="p">()));</span>\n <span class="k">if</span> <span class="p">(</span><span class="nv">$command</span> <span class="k">instanceof</span> <span class="nc">OnlyPerformedByAdministrator</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="nf">isAdmin</span><span class="p">())</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">AccessDenied</span><span class="p">();</span>\n <span class="p">}</span>\n\n <span class="nv">$next</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nv">$command</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>This middleware will stop the command processing if an error is raised. We need to catch this exception to return a 403 HTTP response in the web controller, or to return a status code greater than 0 in the CLI command.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">WebToggleCartographerPremiumStatus</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">private</span> <span class="nc">CommandBus</span> <span class="nv">$commandBus</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">Request</span> <span class="nv">$request</span><span class="p">):</span> <span class="kt">Response</span>\n <span class="p">{</span>\n <span class="k">try</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">commandBus</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="k">new</span> <span class="nc">CreateNewProduct</span><span class="p">(</span><span class="cd">/** ... */</span><span class="p">));</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">AccessDenied</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">Response</span><span class="p">(</span><span class="mi">403</span><span class="p">,</span> <span class="s1">'Access denied'</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">Response</span><span class="p">(</span><span class="mi">200</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h2 id="why-do-i-handle-permissions-with-a-middleware">Why do I handle permissions with a middleware?</h2>\n\n<p>I decided to add a middleware to the command bus because it ensures that permissions are checked no matter where commands are dispatched. For example: from the web controller or a CLI command. Moreover, I don’t depend on a security library or any framework configuration. All permission business rules are coded in the domain.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 26 Sep 2022 00:00:00 -0500\n https://arnolanglade.github.io/how-to-handle-user-permissions-through-command-bus-middleware.html?s=feed\n https://arnolanglade.github.io/how-to-handle-user-permissions-through-command-bus-middleware.html\n \n command-bus\n \n \n \n \n \n The command bus design pattern\n <p><strong>Note:</strong> Before reading this blog post, if you don’t know what a command and a command handler are, I advise you to first read the blog post I’ve written about those design patterns. It will help you to understand this new article:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-handler-patterns.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-handler/command-handler.webp" alt="Command and command handler design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Command and command handler design pattern</span>\n </span>\n </a>\n</div>\n\n<h2 id="what-is-a-bus">What is a bus?</h2>\n\n<p>Let’s start with the basics, what is a bus? In computer science, a bus is a system that connects several components and transfers data between them. In software, those components are called middleware. A middleware processes an incoming request and returns a response. As you can see in the schema below, the main advantage of a bus is that it is highly customizable as you can add as many middleware as you want.</p>\n\n<p><img src="images/posts/command-bus/bus.svg" alt="A bus" /></p>\n\n<p>In the next sections, we will speak about the command bus which is often associated with an event bus. Using an event bus is not mandatory but we will see how it will make your application more modular and evolutive. Their goal is to deliver a command or an event to their handler(s). Events and commands are objects used to encapsulate information needed to achieve an action (a command) or to tell what happened in the system (an event).</p>\n\n<h2 id="the-command-bus">The command bus</h2>\n\n<p><strong>Quick reminder about command and command handler:</strong> A command represents a user’s intent. The data carried by the command has to be valid. It can be only handled by only one handler that is just a callable that will perform the user action.</p>\n\n<p>Now, we will build a command bus following the same architecture that I described in the previous section. The only difference is that the command bus will return void. As commands canmight be handled asynchronously, we don’t want to wait for the result of the command processing.</p>\n\n<p><img src="images/posts/command-bus/command-bus.svg" alt="A command bus" /></p>\n\n<p>Let’s see the most common middleware used to build a command bus. The first one is probably the “logging middleware”. It helps to make your application observable and it is really useful for bug hunting. Then the “validation middleware” ensures that the command is valid before giving it to the handler. Its purpose is to stop the command processing if data is invalid. It is pretty convenient because it avoids validating them manually. When your application uses a database, the “transaction middleware” wraps the handler execution into a SQL transaction. It makes sure all database changes are done, otherwise it rollbacks the transaction. Finally, the last middleware is responsible for finding and executing the handler that matches the command.</p>\n\n<h2 id="the-event-bus">The event bus</h2>\n\n<p>An event represents something that happened in the application. Unlike a command, an event can be handled by several handlers. Listening to events allows us to enhance existing features or add new ones very quickly. Several teams can listen to the same event to perform additional tasks depending on business needs. It makes applications more evolutive without adding accidental complexity and lets your team work isolated from each other.</p>\n\n<p><strong>Tip:</strong> I would like to encourage you to mainly use business-oriented events instead of technical ones. They clearly describe what happened from a business point of view. For example, <code class="language-plaintext highlighter-rouge">NewAccountHasBeenCreated</code> is more understandable than <code class="language-plaintext highlighter-rouge">ResourceCreated</code> with a resource property equal to ‘Account’</p>\n\n<p>Even if the event bus is built the same way as the command bus we don’t need all the different middleware. We don’t need the validation middleware because events are generated by the aggregates with value objects. Those objects ensure domain invariant which means they are always valid. We also don’t need the transactional middleware because the event will be processed into the transaction begun during the command processing. Moreover, depending on your business needs you may not want to process events into this transaction. Let’s take a simple example. After creating an account, an event <code class="language-plaintext highlighter-rouge">AccountCreated</code> is dispatched, then a welcome email is sent during <code class="language-plaintext highlighter-rouge">AccountCreated</code> processing. If the email sending fails, do we want to roll back the account creation? Not sure! In that case, you need to speak with your product manager to decide how to process this event.</p>\n\n<p>As I said previously, events are recorded by aggregates and they should be business oriented. I will share with you two ways to dispatch events into the event bus.</p>\n\n<p><img src="images/posts/command-bus/event-bus.svg" alt="A event bus" /></p>\n\n<p><strong>Solution 1:</strong> You can collect them from your repository if no errors have been raised during the aggregate persisting and then dispatch them.</p>\n\n<p><strong>Solution 2:</strong> The other solution is to collect events from the command handler. The handler can return them, and then the “handle command” middleware catches and dispatches them.</p>\n\n<p><strong>Note:</strong> My previous <a href="http://arnolanglade.github.io/command-handler-patterns.html">blog post</a> about the command and command handler pattern said that a command handler should return void. Here, the idea is that the command bus should return void only the “handle command” should be aware of the result of the handler execution.</p>\n\n<p>I’ve written a bunch of articles about how to handle a command, validate its data, handle user permissions, and so on. Take a look at these articles:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/tag/command-bus">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/data-validation.webp" alt="See all blog posts about command handling." />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">See all blog posts about command handling.</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 12 Sep 2022 00:00:00 -0500\n https://arnolanglade.github.io/command-bus-design-pattern.html?s=feed\n https://arnolanglade.github.io/command-bus-design-pattern.html\n \n command-bus\n \n design-patterns\n \n \n \n \n \n Objective: set up your projects more easily\n <p>For the last decade I worked on several more or less complex projects. I often had problems with their installation. Sometimes, the project was not documented or the existing documentation was not up to date. I had to run commands but I did not understand all of them. When I got errors it was hard to understand what happened. That was not always simple.</p>\n\n<p>During my last projects, I used makefile to provide an abstraction to simplify their installation and hide complexity. It let me install projects with a single command and provided a minimal set of targets which made my daily work easier.</p>\n\n<h2 id="how-does-makefile-work">How does makefile work?</h2>\n\n<p>A makefile is a set of “rules” that looks like:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>target: prerequisites prerequisites\n recipe\n recipe\n ...\n</code></pre></div></div>\n\n<p>A <strong>target</strong> is the name of a file (or a folder) that is generated by <code class="language-plaintext highlighter-rouge">make</code>. It could also be the name of an action to perform but you need to declare it as PHONY.</p>\n\n<p>A <strong>prerequisite</strong> are the files (or folders) needed to create the target, you can see them as target dependencies.</p>\n\n<p>A <strong>recipe</strong> are all actions executed when the target is run. <strong>Caution:</strong> you need to indent all recipes using a “real” tab character otherwise you will get errors.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.env:\n <span class="nb">cp</span> .env.dist .env\n</code></pre></div></div>\n\n<p>If the <code class="language-plaintext highlighter-rouge">.env</code> file does not exist, the recipe will be carried out, but if it does exist the recipe won’t be executed #magic.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: cache\ncache: .env\n bin/console c:c\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">cache</code> target does not target a file. Declaring this target as PHONY allows having a file named <code class="language-plaintext highlighter-rouge">cache</code> in the same directory as the Makefile.</p>\n\n<p><strong>Note:</strong> If the <code class="language-plaintext highlighter-rouge">.env</code> file does not exist the <code class="language-plaintext highlighter-rouge">.env</code> target will be performed before the <code class="language-plaintext highlighter-rouge">cache</code> target.</p>\n\n<h2 id="lets-take-an-example">Let’s take an example</h2>\n\n<p>For instance, a project orchestrated by docker-compose having:</p>\n<ul>\n <li>a front application written in JS using React framework,</li>\n <li>a back application written in PHP using Symfony framework,</li>\n <li>a PostgreSQL database managed by Doctrine DBAL and Doctrine migration</li>\n</ul>\n\n<p><strong>Caution:</strong> I will only speak about projects setup for dev purposes. I won’t talk about making docker images ready for production.</p>\n\n<p>Let’s start installing the project dependencies. The following targets install project dependencies if they have not been downloaded yet. They can guess if they are outdated to upgrade them thanks to target prerequisites. Another interesting thing is that nothing will be done if dependencies are already installed and up to date.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Front</span>\nweb/yarn.lock: web/package.json\n docker-compose run <span class="nt">--rm</span> node yarn <span class="nb">install\n\n</span>web/node_modules: web/yarn.lock\n docker-compose run <span class="nt">--rm</span> node yarn <span class="nb">install</span> <span class="nt">--frozen-lockfile</span>\n docker-compose run <span class="nt">--rm</span> node yarn check <span class="nt">--integrity</span>\n\n<span class="c"># back</span>\napi/composer.lock: api/composer.json\n docker-compose run <span class="nt">--rm</span> fpm composer update\n\napi/vendor: api/composer.lock\n docker-compose run <span class="nt">--rm</span> fpm composer <span class="nb">install</span>\n\n</code></pre></div></div>\n\n<p>Then, we need to “up” all docker-compose services: the web server, the PHP process manager, the datatable, and the node to run the front application in development mode.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: up\nup:\n docker-compose up <span class="nt">-d</span>\n</code></pre></div></div>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker-compose ps \n Name Command State Ports \n<span class="nt">---------------------------------------------------------------------------------------------------------------------------------------------</span> \nmy-maps-node docker-entrypoint.sh yarn ... Up \nmy-maps-web nginx <span class="nt">-g</span> daemon off<span class="p">;</span> Up 80/tcp \nmy-maps_database_1 docker-entrypoint.sh postgres Up 5432/tcp \nmy-maps_fpm_1 php-fpm <span class="nt">-F</span> Up \n</code></pre></div></div>\n\n<p>The last thing to do is to create the database schema using Doctrine migration.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: db-migration\ndb-migration: api/vendor\n docker-compose run <span class="nt">--rm</span> fpm bin/console doctrine:migrations:migrate <span class="nt">--no-interaction</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> To ease my daily work, I like introducing other targets like <code class="language-plaintext highlighter-rouge">db</code> target that resets database quickly or <code class="language-plaintext highlighter-rouge">fixture</code> to load some data fixtures.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: db\ndb: api/vendor\n docker-compose run <span class="nt">--rm</span> fpm bin/console doctrine:database:drop <span class="nt">--force</span> <span class="nt">--no-interaction</span>\n docker-compose run <span class="nt">--rm</span> fpm bin/console doctrine:database:create <span class="nt">--no-interaction</span>\n\n.PHONY: fixtures\nfixtures: api/vendor\n docker-compose run <span class="nt">--rm</span> fpm bin/console project:fixtures:load\n</code></pre></div></div>\n\n<p>Now, we have all atomic targets to set up all parts of the application. Another interesting thing with make, is that it can run several targets within a single command <code class="language-plaintext highlighter-rouge">make up api/vendor web/node_modules</code>.This is pretty useful to create scenarios. For instance, to set up and run the project I only need to run the following command:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>make up api/vendor web/node_modules db db-migration fixtures\n</code></pre></div></div>\n\n<p>But it works with everything:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>make db db-migration fixtures\nmake api/vendor web/node_modules\n</code></pre></div></div>\n\n<p>To make your day-to-day basis, you can introduce targets that run those scenarios.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># It builds and runs the application</span>\n.PHONY: app-dev\napp-dev: up api/vendor web/node_modules db db-migration fixtures\n\n<span class="c"># It resets the database</span>\n.PHONY: db-reset\ndb-reset: db db-migration fixtures\n\n<span class="c"># It resets the database</span>\n.PHONY: dependencies\ndependencies: api/vendor web/node_modules\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> I advise you to introduce the minimum set of targets into the makefile. Keep it simple! Don’t forget that everyone uses it! To let developers have their custom targets you may want to include custom makefiles using <a href="https://www.gnu.org/software/make/manual/html_node/Include.html">include</a>. Don’t forget to add an entry into <code class="language-plaintext highlighter-rouge">.ignore</code> to avoid committing those files. Now, developers can create their own makefile with their personal targets.</p>\n\n<h2 id="one-last-word">One last word</h2>\n\n<p>Makefile is only a solution, this is not THE solution. The important thing to keep in mind is that you should be able to easily run your project to reduce the developer’s mental load and let them focus on the right thing. It will improve the day-to-day basis and make newcomers’ onboarding easier.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Wed, 02 Jun 2021 00:00:00 -0500\n https://arnolanglade.github.io/objective-set-up-your-projects-more-easily.html?s=feed\n https://arnolanglade.github.io/objective-set-up-your-projects-more-easily.html\n \n makefile\n \n \n \n \n \n Why unit testing can be hard?\n <blockquote>\n <p>Unit tests are typically automated tests written and run by software developers to ensure that a section of an application (known as the “unit”) meets its design and behaves as intended</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Unit_testing">Wikipedia</a></p>\n</blockquote>\n\n<p>I remember when I started to test my code it was really hard! It was mainly because I misunderstood some basics like what testing was about and the need of well-designed code. Unit tests ensure your code works as expected, but we often forget that unit testing is also the simplest way to have quick feedback during development phase.</p>\n\n<p>In this blog post, I will share what I learned to easily unit test my codebases.</p>\n\n<h2 id="test-your-public-methods">Test your public methods</h2>\n\n<p>Objects should be seen as black boxes. Public methods are the only way to interact with objects, while private and protected methods are implementation details. We should not pay attention to how objects work internally. That’s why we don’t test private and protected methods. If you need to test them, that’s a design smell! Your objects might do too many things and they probably do not respect the <strong>S</strong>ingle <strong>R</strong>esponsibility <strong>P</strong>rinciple.</p>\n\n<blockquote>\n <p>The single-responsibility principle (SRP) is a computer-programming principle that states that every class in a computer program should have responsibility over a single part of that program’s functionality, which it should encapsulate.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Single-responsibility_principle">Wikipedia</a></p>\n</blockquote>\n\n<p>Actually, it is better to have several small objects solving simple problems instead of having god objects that are doing everything the wrong way. If your objects become too big, split them into smaller ones because they are easier to maintain and to test.</p>\n\n<h2 id="do-not-unit-test-code-that-uses-ios">Do not unit test code that uses IOs</h2>\n\n<blockquote>\n <p>Input/output (I/O, or informally io or IO) is the communication between an information processing system, such as a computer, and the outside world, possibly a human or another information processing system.</p>\n\n <p><a href="https://press.rebus.community/programmingfundamentals/chapter/input-and-output/">Wikipedia</a></p>\n</blockquote>\n\n<p>For example, IO are side effects like: network calls, database queries, filesystem operations, actual timestamps or randomness.</p>\n\n<h3 id="do-not-deal-with-the-outside">Do not deal with the outside</h3>\n\n<p>The code covered by unit tests should not depend on the outside world like databases, external services and so on. Unit tests should not require any application setup, they have to remain as simple as possible. Their goal is to give you quick feedback by checking that a small piece of code (a unit) matches a business expectation. If you want to be sure that all application parts are well integrated with the outside world, you have to use an integration test.</p>\n\n<p>The following example shows a piece of code that depends on the external service. Here, we can’t build the <code class="language-plaintext highlighter-rouge">Map</code> object without a working database.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HandleMarkerAddition</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nv">$connection</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">AddMarkerToMap</span> <span class="nv">$command</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$mapState</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="s1">'SELECT ... FROM ...'</span><span class="p">,</span> <span class="p">[</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">mapId</span><span class="p">()]);</span>\n\n <span class="nv">$map</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">fromState</span><span class="p">(</span><span class="nv">$mapState</span><span class="p">);</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">name</span><span class="p">(),</span> <span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">location</span><span class="p">());</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="s1">'INSERT INTO ...'</span><span class="p">,</span> <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">toState</span><span class="p">()]);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The goal of this piece of code is to add a marker to a <code class="language-plaintext highlighter-rouge">Map</code> object, no matter how the object is stored. Tests that cover this class should focus on business use cases instead of technical details. A solution would be to use a repository design pattern to hide the map storage logic. The class will better follow the <strong>S</strong>ingle <strong>R</strong>esponsable <strong>P</strong>rinciple because it will only handle the marker addition use case whereas the map repository will be in charge of storing data.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HandleMarkerAddition</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Maps</span> <span class="nv">$maps</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Maps</span> <span class="nv">$maps</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">maps</span> <span class="o">=</span> <span class="nv">$maps</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">AddMarkerToMap</span> <span class="nv">$command</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$map</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">maps</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">mapId</span><span class="p">());</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">name</span><span class="p">(),</span> <span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">location</span><span class="p">());</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">maps</span><span class="o">-&gt;</span><span class="nf">add</span><span class="p">(</span><span class="nv">$map</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>With this new design, it is easier to test this class. Thanks to the <code class="language-plaintext highlighter-rouge">Maps</code> interface , we are able to simply create test doubles for the map repository.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// `PostgreSQLMaps` is the implementation used by default on the production</span>\n<span class="nv">$maps</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PostgreSQLMaps</span><span class="p">();</span>\n<span class="p">(</span><span class="k">new</span> <span class="nc">HandleMarkerAddition</span><span class="p">(</span><span class="nv">$postgreSQLMaps</span><span class="p">)(</span><span class="nv">$command</span><span class="p">);</span>\n\n<span class="c1">// `InMemoryMaps` is an implementation that keeps map objects in memory for testing </span>\n<span class="nv">$maps</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">InMemoryMaps</span><span class="p">();</span>\n<span class="p">(</span><span class="k">new</span> <span class="nc">HandleMarkerAddition</span><span class="p">(</span><span class="nv">$inMemoryMaps</span><span class="p">)(</span><span class="nv">$command</span><span class="p">);</span>\n\n<span class="c1">// In both cases we can retrieve the Map object from the repository to check the map has the new marker.</span>\n<span class="nv">$map</span> <span class="o">=</span> <span class="nv">$maps</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">mapId</span><span class="p">());</span>\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">hasSameState</span><span class="p">(</span><span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best place'</span><span class="p">,</span> <span class="k">new</span> <span class="nc">Marker</span><span class="p">(</span><span class="cm">/* … */</span><span class="p">)))</span> <span class="c1">// should return true;</span>\n\n</code></pre></div></div>\n\n<h3 id="do-not-deal-with-randomness">Do not deal with randomness</h3>\n\n<p>Randomness makes your code unpredictable. To simply test a piece of code you should be able to predict its result. To ease unit testing your code should avoid using randomness as much as possible.</p>\n\n<p>The following example shows a piece of code that uses randomness.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HashedPassword</span>\n<span class="p">{</span>\n <span class="c1">// ... </span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$hash</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">hash</span> <span class="o">=</span> <span class="nv">$hash</span><span class="p">;</span>\n <span class="p">}</span>\n\n\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">fromString</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$hash</span> <span class="o">=</span> <span class="err">\\</span><span class="nb">password_hash</span><span class="p">(</span><span class="nv">$password</span><span class="p">,</span> <span class="no">PASSWORD_BCRYPT</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span><span class="nv">$hash</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="c1">// ...</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">HashedPasswordTest</span> <span class="kd">extends</span> <span class="nc">TestCase</span>\n<span class="p">{</span>\n <span class="cd">/** @test */</span>\n <span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">builds</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="n">password</span><span class="err"> </span><span class="n">from</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="nf">string</span><span class="p">()</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">assertEquals</span><span class="p">(</span>\n <span class="nv">$this</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="s1">'Password1'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">HashedPassword</span><span class="p">(</span><span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span><span class="p">)</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>When we run <code class="language-plaintext highlighter-rouge">HashedPasswordTest</code> we get an error because the <code class="language-plaintext highlighter-rouge">password_hash</code> generates a random salt to hash the password. The problem is that the <code class="language-plaintext highlighter-rouge">password_hash</code> function cannot return the same hash for a given password. Each time you call this function a different hash will be returned.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">-Password</span> Object &amp;000000006e7168e60000000023b11bb2 <span class="o">(</span>\n- <span class="s1">'hash'</span> <span class="o">=&gt;</span> <span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span>\n+Password Object &amp;000000006e7168210000000023b11bb2 <span class="o">(</span>\n+ <span class="s1">'hash'</span> <span class="o">=&gt;</span> <span class="s1">'$2y$10$b/9GX4grnt4gH5cm8FzzSuUNGGQUiA/w.5HdKNEsW3dHtSUeTMXgK'</span>\n</code></pre></div></div>\n\n<p>The simplest solution would be to hardcode the salt to make sure the <code class="language-plaintext highlighter-rouge">hash_password</code> returns the same hash every time but this is not a good design. This would weaken the password generation because we need to test it. Another way would be to extract the hash generation in another place.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HashedPassword</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">fromString</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">,</span> <span class="kt">PasswordEncryptor</span> <span class="nv">$passwordEncryptor</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$hash</span> <span class="o">=</span> <span class="nv">$passwordEncryptor</span><span class="o">-&gt;</span><span class="nb">hash</span><span class="p">(</span><span class="nv">$password</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span><span class="nv">$hash</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">PasswordEncryptor</code> interface makes test doubles creation possible. Now, we just need to create a fake object to test this method.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">FakePasswordEncryptor</span> <span class="kd">implements</span> <span class="nc">PasswordEncryptor</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">hash</span><span class="p">():</span> <span class="kt">string</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span><span class="p">;</span>\n <span class="p">}</span>\n\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">HashedPasswordTest</span> <span class="kd">extends</span> <span class="nc">TestCase</span>\n<span class="p">{</span>\n <span class="cd">/** @test */</span>\n <span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">builds</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="n">password</span><span class="err"> </span><span class="n">from</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="nf">string</span><span class="p">()</span>\n <span class="p">{</span>\n <span class="nv">$fakePasswordEncryptor</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FakePasswordEncryptor</span><span class="p">();</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">assertEquals</span><span class="p">(</span>\n <span class="n">this</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="s1">'Password1'</span><span class="p">,</span> <span class="nv">$fakePasswordEncryptor</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">HashedPassword</span><span class="p">(</span><span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span><span class="p">)</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h3 id="avoid-actual-datetimes">Avoid actual datetimes</h3>\n\n<p>With actual datetimes, we have the same problem as with randomness, neither can be predicted.</p>\n\n<p>The following example shows you that actual datetimes are not predictable like <code class="language-plaintext highlighter-rouge">hash_password</code> in the previous section.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="err">\\</span><span class="nc">DateTimeImmutable</span> <span class="nv">$markerAddedAt</span> <span class="o">=</span> <span class="kc">null</span><span class="p">,</span> <span class="nc">Marker</span> <span class="mf">...</span><span class="nv">$makers</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">addMarker</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$name</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$location</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markerAddedAt</span> <span class="o">=</span> <span class="k">new</span> <span class="err">\\</span><span class="nf">DateTimeImmutable</span><span class="p">(</span><span class="s1">'now'</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">MapTest</span> <span class="kd">extends</span> <span class="nc">TestCase</span>\n<span class="p">{</span>\n <span class="cd">/** @test */</span>\n <span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">adds</span><span class="err"> </span><span class="n">marker</span><span class="err"> </span><span class="n">to</span><span class="err"> </span><span class="n">the</span><span class="err"> </span><span class="nf">map</span><span class="p">()</span>\n <span class="p">{</span>\n <span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Map name'</span><span class="p">);</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">,</span> <span class="p">[</span><span class="mf">47.21725</span><span class="p">,</span> <span class="o">-</span><span class="mf">1.55336</span><span class="p">]);</span>\n \n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">assetTrue</span><span class="p">(</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">hasSameState</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">Marker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">,</span> <span class="p">[</span><span class="mf">47.21725</span><span class="p">,</span> <span class="o">-</span><span class="mf">1.55336</span><span class="p">]),</span> \n <span class="k">new</span> <span class="err">\\</span><span class="nf">DateTimeImmutable</span><span class="p">(</span><span class="s1">'now'</span><span class="p">)</span>\n <span class="p">)</span>\n <span class="p">)</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>When we run <code class="language-plaintext highlighter-rouge">MapTest</code> we get an error because we can predict to the millisecond when the marker was added to the map.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">-Map</span> Object &amp;000000003acad975000000006b83e943 <span class="o">()</span>\n+Map Object &amp;000000003acad936000000006b83e943 <span class="o">(</span>\n+ <span class="s1">'markerAddedAt'</span> <span class="o">=&gt;</span> DateTimeImmutable Object &amp;000000003acad946000000006b83e943 <span class="o">(</span>\n+ <span class="s1">'date'</span> <span class="o">=&gt;</span> <span class="s1">'2021-04-18 17:36:02.919004'</span>\n+ <span class="s1">'timezone_type'</span> <span class="o">=&gt;</span> 3\n+ <span class="s1">'timezone'</span> <span class="o">=&gt;</span> <span class="s1">'UTC'</span>\n+ <span class="o">)</span>\n+<span class="o">)</span>\n</code></pre></div></div>\n\n<p>To prevent this kind of problem, a good idea is to abstract time by introducing an interface that is responsible for time management.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">addMarker</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$name</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$location</span><span class="p">,</span> <span class="kt">Clock</span> <span class="nv">$clock</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markerAddedAt</span> <span class="o">=</span> <span class="nv">$clock</span><span class="o">-&gt;</span><span class="nf">now</span><span class="p">();</span>\n <span class="p">}</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, thanks to the <code class="language-plaintext highlighter-rouge">Clock</code> interface we will be able to create test doubles and easily test this method.</p>\n\n<h2 id="coupling-might-be-your-worst-enemy">Coupling might be your worst enemy</h2>\n\n<blockquote>\n <p>Coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)">Wikipedia</a></p>\n</blockquote>\n\n<p>As you have seen in the previous sections, objects should depend on abstractions instead of concrete implementations. Abstractions (e.g. interfaces) ease testing because your code is more modular. You can use test doubles to reduce the complexity and facilitate testing. Their goal is to mimic the behavior of real objects to replace a subpart of an algorithm.</p>\n\n<p>The following example shows that hardcoding object dependencies won’t help to create test doubles.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MyClass</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">ConcreteImplementation</span> <span class="nv">$concreteImplementation</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="c1">// Here we can only use these concrete implementations, if they use IO for instance you won't be able to test it.</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">concreteImplementation</span> <span class="o">=</span> <span class="nv">$concreteImplementation</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">anotherConcreteImplementation</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">AnotherConcreteImplementation</span><span class="p">();</span>\n \n <span class="c1">// Singleton pattern does not help because it hides object dependencies and makes them hard coded.</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nc">Connection</span><span class="o">::</span><span class="nf">getInstance</span><span class="p">();</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The solution is to use the dependency inversion pattern to remove hard coded dependencies introducing abstractions as much as possible.</p>\n\n<blockquote>\n <p>High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g., interfaces). Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Wikipedia</a></p>\n</blockquote>\n\n<p>In the following example, all class dependencies are interchangeable. So, you can easily create test doubles like fake, stub, or mocks to make sure your objects meet business expectations.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MyClass</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">ImplementationInterface</span> <span class="nv">$concreteImplementation</span><span class="p">,</span>\n <span class="kt">AnoherImplementationInterface</span> <span class="nv">$anotherConcreteImplementation</span><span class="p">,</span>\n <span class="kt">ConnectionInterface</span> <span class="nv">$connection</span>\n <span class="p">)</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">concreteImplementation</span> <span class="o">=</span> <span class="nv">$concreteImplementation</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">anotherConcreteImplementation</span> <span class="o">=</span> <span class="nv">$anotherConcreteImplementation</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nv">$connection</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Caution:</strong> That does not mean you should use interfaces everywhere! Knowing when to introduce new abstractions might be hard at the beginning, there is no magic recipe!</p>\n\n<p>Thanks to my proofreaders <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a> and <a href="https://twitter.com/jjanvier_">@jjanvier_</a>.</p>\n\n Mon, 03 May 2021 00:00:00 -0500\n https://arnolanglade.github.io/why-unit-testing-can-be-hard.html?s=feed\n https://arnolanglade.github.io/why-unit-testing-can-be-hard.html\n \n testing\n \n OOP\n \n \n \n \n \n Why you should not expose objects' state to test them\n <p>To introduce this topic, let’s have a look at the PHP documentation to understand how object comparison works using the comparison and identity operators.</p>\n\n<blockquote>\n <p>When using the comparison operator (==), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values (values are compared with ==), and are instances of the same class.</p>\n\n <p>When using the identity operator (===), object variables are identical if and only if they refer to the same instance of the same class.</p>\n\n <p><a href="https://www.php.net/manual/en/language.oop5.object-comparison.php">PHP documentation </a></p>\n</blockquote>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$object</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Object</span><span class="p">();</span>\n<span class="nv">$otherObject</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Object</span><span class="p">();</span>\n\n<span class="nv">$object</span> <span class="o">==</span> <span class="nv">$otherObject</span> <span class="c1">// true</span>\n<span class="nv">$object</span> <span class="o">===</span> <span class="nv">$otherObject</span> <span class="c1">// false </span>\n</code></pre></div></div>\n\n<p>I add an <code class="language-plaintext highlighter-rouge">equals</code> method to objects to handle object comparison. The purpose of this method is to compare an object state with another one. In the following example, I use the comparison operator (==) because I want to check if the objects have the same state no matter their references.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Email</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$email</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$email</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">email</span> <span class="o">=</span> <span class="nv">$email</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">equals</span><span class="p">(</span><span class="kt">Email</span> <span class="nv">$email</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span> <span class="o">==</span> <span class="nv">$email</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>There is another way to compare object state. Do you know that instances of the same class can access each other’s private members?</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Email</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">equals</span><span class="p">(</span><span class="kt">Email</span> <span class="nv">$email</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">email</span> <span class="o">===</span> <span class="nv">$email</span><span class="o">-&gt;</span><span class="n">email</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> This is really useful to compare Doctrine entities that have persistent collections. The error <code class="language-plaintext highlighter-rouge">Error: Nesting level too deep - recursive dependency?</code> is raised when we compare entities using the comparison operator (==). You should have a look at this <a href="https://www.richardlord.net/blog/php/php-nesting-level-too-deep-recursive-dependency.html">blog post</a> to understand why this error occured. Accessing private attributes let you use the identity operator (===) to prevent this error.</p>\n\n<p>By the way, entities are a bit special because an entity is an object that has an identity. It means that if we want to compare them we should compare their identities instead of their states.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">equals</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span><span class="o">-&gt;</span><span class="nf">equals</span><span class="p">(</span><span class="nv">$mapId</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>I add an extra method called <code class="language-plaintext highlighter-rouge">hasSameState</code> to entities to compare their states because entity state comparison remains really useful for testing.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">hasSameState</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span> <span class="o">==</span> <span class="nv">$map</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>For a long time, I used getters for testing purposes. I only knew this way to ensure objects had the right state.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Nantes'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">getName</span><span class="p">()</span><span class="o">-&gt;</span><span class="nf">shouldReturn</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">)</span> <span class="p">;</span>\n</code></pre></div></div>\n\n<p>It was a mistake because exposing objects’ state breaks data encapsulation. We should not know how objects work internally, we should only use their public API (public methods) to interact with them. But, if we need to build the <code class="language-plaintext highlighter-rouge">Map</code> object with something else than a string, this assertion will no longer be true. That will break all application tests and parts that use this getter! That’s not great! Object comparison I described previously helps to get rid of getters.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Nantes'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">hasSameState</span><span class="p">(</span><span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">))</span><span class="o">-&gt;</span><span class="nf">shouldReturn</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n</code></pre></div></div>\n\n<p>Now, the <code class="language-plaintext highlighter-rouge">Map</code> object is better designed. Its state is not exposed anymore which improves data encapsulation. It follows the “Tell don’t ask” principle because I don’t need to extract its internal state to test it. I only need to use its public API to check if it meets the business exceptions.</p>\n\n<p><strong>Tip:</strong> If you don’t want or if you can’t add a method to your objects that handles comparison you can still compare their instances to avoid adding getters.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span><span class="nv">$map</span><span class="p">,</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">));</span>\n</code></pre></div></div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 13 Apr 2021 00:00:00 -0500\n https://arnolanglade.github.io/you-should-not-expose-objects-state-to-test-them.html?s=feed\n https://arnolanglade.github.io/you-should-not-expose-objects-state-to-test-them.html\n \n testing\n \n OOP\n \n \n \n \n \n How did I organize my last Symfony projects?\n <p>In this blog post, I will explain how I organized my last Symfony projects. They are mainly inspired by Hexagonal and CQRS architecture. Keep in mind that I did not try to implement these architectures by the book, I only took some concepts that helped me to have a simple and clear codebase organization.</p>\n\n<p>If we have a look at the project’s root, nothing special happens, I kept all folders and files created during Symfony installation.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree <span class="nb">.</span> <span class="nt">-L</span> 1 \n├── bin\n├── composer.json\n├── composer.lock\n├── config\n├── features\n├── public\n├── src\n├── symfony.lock\n├── tests\n├── translations\n├── var\n└── vendor\n</code></pre></div></div>\n\n<p>In the next sections, we are going to see how I organized the src folder.</p>\n\n<h2 id="hexagonal-architecture">Hexagonal architecture</h2>\n\n<p>The foundation of the hexagonal architecture is the explicit separation between the domain (inside) and the infrastructure (outside). All dependencies are going from Infrastructure to the Domain.</p>\n\n<p>The domain is the part of the application that contains your business logic. It must reflect as much as possible the problem your application has to solve. This part of the application must not use IO, the infrastructure contains them all. For instance, IO are side effects like network calls, database queries, filesystem operations, actual timestamps or randomness..</p>\n\n<p>Based on that information my first decision was to split src into two areas: <code class="language-plaintext highlighter-rouge">Domain</code> and <code class="language-plaintext highlighter-rouge">Infrastructure</code>.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/ <span class="nt">-L</span> 1\napi/src/Domain/\n├── Domain\n└── Infrastructure\n</code></pre></div></div>\n\n<p><strong>Coupling rules:</strong></p>\n<ul>\n <li>Domain must not depend on the Infrastructure.</li>\n <li>Domain must not use IO</li>\n</ul>\n\n<p>I am not a big fan of the onion architecture because I want to keep my projects as simple as possible. Having a lot of layers can be really hard to maintain because you need to align the whole team on the coupling rules. Agreeing with yourself is not easy, so getting several people to agree may be really hard. Here, we only have a single rule.</p>\n\n<p>Sometimes, I needed to write libraries because I could not find any open source libraries that match my expectations. To avoid coding in the vendor directory, I introduced a third area called <code class="language-plaintext highlighter-rouge">Libraries</code> (this new area is optional). Those libraries may be used in the domain and the infrastructure but their usage should not break the coupling rules that are defined for those areas.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/ <span class="nt">-L</span> 1\napi/src/Domain/\n├── Domain\n├── Infrastructure\n└── Librairies\n</code></pre></div></div>\n\n<p><strong>Coupling rules:</strong></p>\n<ul>\n <li>Libraries must not depend on Domain and Infrastructure</li>\n</ul>\n\n<p>Finally, I created a “sub” area called <code class="language-plaintext highlighter-rouge">Application</code> in the infrastructure that contains all pieces of code needed to have an application up and running: framework code (Symfony kernel, framework customizations), data fixtures, and migration.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Infrastructure/Application <span class="nt">-L</span> 1 \napi/src/Infrastructure/Application\n├── Exception \n├── Fixture\n├── Kernel.php\n├── Migrations\n├── Security\n└── Kernel\n</code></pre></div></div>\n<p>In this example, <code class="language-plaintext highlighter-rouge">Exception</code> and <code class="language-plaintext highlighter-rouge">Security</code> folders contain framework customizations.</p>\n\n<h2 id="business-first">Business first</h2>\n\n<p>A really important thing for me is to drive codebase organization by business concepts. I don’t want to name folders and classes with technical patterns like factory or repository for instance. Non-tech people should be able to understand what a class does thanks to its name.</p>\n\n<h3 id="domain">Domain</h3>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain <span class="nt">-L</span> 1\napi/src/Domain\n├── Cartographer\n└── Map\n</code></pre></div></div>\n\n<p>Because I did not use any technical words to name folders we can easily imagine the project is about making maps. Now, let’s have a look inside the <code class="language-plaintext highlighter-rouge">Map</code> directory:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/Map <span class="nt">-L</span> 1\n├── CartographersAllowedToEditMap.php // Value object\n├── Description.php // Value object\n├── MapCreated.php // Event \n├── MapId.php // Value object\n├── MapName.php // Value object\n├── Map.php // Root aggregate\n├── Maps.php // Repository interface\n├── Marker // All classes to design Marker entity\n├── MarkerAddedToMap.php // Event\n├── MarkerDeletedFromMap.php // Event\n├── MarkerEditedOnMap.php // Event\n├── UnknownMap.php // Exception\n└── UseCase // Use cases orchestration\n</code></pre></div></div>\n\n<p>In this folder, we have all the pieces of code needed to design the <code class="language-plaintext highlighter-rouge">Map</code> aggregate. As you can see, I did not organize it by design patterns like <code class="language-plaintext highlighter-rouge">ValueObject</code>, <code class="language-plaintext highlighter-rouge">Event</code> or <code class="language-plaintext highlighter-rouge">Exception</code>.</p>\n\n<p>As you might have understood the <code class="language-plaintext highlighter-rouge">Map</code> entity has a one-to-many relationship with the Marker entity. All classes needed to modelize this entity are in the Marker folder and they are organized the same way as the <code class="language-plaintext highlighter-rouge">Map</code> directory.</p>\n\n<p>The <code class="language-plaintext highlighter-rouge">UseCase</code> folder gathers all pieces of code needed to orchestrate use cases like command, their handler and business validation.</p>\n\n<p><strong>Tip:</strong> I don’t suffix repositories by ‘Repository’ but I try to use a business concept to name them like <code class="language-plaintext highlighter-rouge">ProductCatalog</code> for a <code class="language-plaintext highlighter-rouge">Product</code> aggregate. If I can find a business concept to name it I use the plural of the aggregate because a repository is a collection of objects.</p>\n\n<h3 id="infrastructure">Infrastructure</h3>\n\n<p>I organize the root of the <code class="language-plaintext highlighter-rouge">Infrastructure</code> folder the same way as the <code class="language-plaintext highlighter-rouge">Domain</code> one.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Infrastructure <span class="nt">-L</span> 1 \napi/src/Infrastructure\n├── Application\n├── Cartographer\n└── Map\n</code></pre></div></div>\n\n<p>Now, let’s have a look at the <code class="language-plaintext highlighter-rouge">Map</code> directory:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Infrastructure/Map <span class="nt">-L</span> 1 \napi/src/Infrastructure/Map\n├── Storage\n└── UserInterface\n └── Web\n └── Cli\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">Storage</code> namespace gathers everything related to data storage like repositories, queries. The <code class="language-plaintext highlighter-rouge">UserInterface</code> namespace gathers everything related to ways to interact with the application like the WEB API (controllers) called by the front application or CLI (Symfony commands).</p>\n\n<h2 id="cqrs">CQRS</h2>\n\n<p>CQRS is the acronym for Command Query Responsibility Segregation. The main idea of CQRS is that you can use different models for writing (command) or reading (query) information. I like the idea of having two small and simple models dedicated to a precise purpose: reading or writing instead of having one big model. It can prevent your aggregate from becoming a god object because as things progress you can have many write and read use cases to handle.</p>\n\n<p>From this pattern, I decided to split the domain into two areas, the first one: <code class="language-plaintext highlighter-rouge">Command</code> and the second one: <code class="language-plaintext highlighter-rouge">Query</code>. It allows me to design a model with the same name for these reading or writing purposes.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/ <span class="nt">-L</span> 2\napi/src/Domain/\n├── Command\n│ ├── Cartographer\n│ └── Map\n└── Query\n ├── Cartographer\n └── Map\n</code></pre></div></div>\n\n<p><strong>Coupling rule:</strong></p>\n<ul>\n <li><code class="language-plaintext highlighter-rouge">Command</code> area must not depend on the <code class="language-plaintext highlighter-rouge">Query</code> area and the other way around.</li>\n</ul>\n\n<p><strong>Note:</strong> I did not make major changes in the infrastructure, the only change I made is to split the storage into two areas like the domain.</p>\n\n<p><strong>Caution:</strong> For those projects, I did not make any projections because my database schema remained simple so I did not need them. I only decided to split my models because my codebase was simple and clearer this way.</p>\n\n<h2 id="last-word">Last word</h2>\n<p>I tried for the last few years to find the perfect architecture but it does not exist. I just tried to use some architectural concepts that make me and my teammates comfortable to work on a daily basis. This project organization has been used for two projects that are in production. One of these projects is a side project I made for fun to create maps without Google Maps. The second was a professional project, real people use it on a daily basis.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 30 Mar 2021 00:00:00 -0500\n https://arnolanglade.github.io/how-did-I-organize-my-last-symfony-project.html?s=feed\n https://arnolanglade.github.io/how-did-I-organize-my-last-symfony-project.html\n \n software-architecture\n \n symfony\n \n \n \n \n \n Persisting entities without ORM\n <p>Today, I will talk about persisting entities without ORM. First, I will introduce the repository pattern because it provides a good abstraction to manage object persistence. Then, we will see what are the impacts on the entity design.</p>\n\n<h2 id="repository-pattern">Repository pattern</h2>\n\n<p>The repository design pattern can be used to manage entity persistence and retrieval. It behaves like a collection of objects and hides the complexity of their storage. It ensures a clean separation between the domain model (the entity) and the data model (SQL tables). The following example shows a basic repository interface. Thanks to the <code class="language-plaintext highlighter-rouge">Maps</code> interface we will be able to add and retrieve Map entities, no matter their storage.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">interface</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n <span class="cd">/**\n * @throws \\LogicException\n * @throws UnknownMap\n */</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">get</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">Map</span><span class="p">;</span>\n\n <span class="cd">/**\n * @throws \\LogicException\n */</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">add</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">void</span><span class="p">;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Caution:</strong> All <code class="language-plaintext highlighter-rouge">Maps</code> implementations should be tested with the same test because we need to be sure they behave the same way. It ensures the application works no matter the chosen implementation.</p>\n\n<p>Let’s see how we can implement this interface with PostgreSQL for instance. The <code class="language-plaintext highlighter-rouge">get</code> method is only responsible to get information from the database to build the map entity whereas the <code class="language-plaintext highlighter-rouge">add</code> method extracts the entity information to store them in the database.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PostgreSqlMaps</span> <span class="kd">implements</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nv">$connection</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">get</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">Map</span>\n <span class="p">{</span>\n <span class="nv">$sql</span> <span class="o">=</span> <span class="sh">&lt;&lt;&lt;SQL\n SELECT map."mapId", map.name\n FROM map\n WHERE map."mapId" = :mapId\n SQL;</span>\n\n <span class="nv">$statement</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="nv">$sql</span><span class="p">,</span> <span class="p">[</span><span class="s1">'mapId'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="nv">$mapId</span><span class="p">]);</span>\n\n <span class="k">if</span> <span class="p">(</span><span class="kc">false</span> <span class="o">===</span> <span class="nv">$map</span> <span class="o">=</span> <span class="nv">$statement</span><span class="o">-&gt;</span><span class="nf">fetchAssociative</span><span class="p">())</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="nc">UnknownMap</span><span class="o">::</span><span class="nf">withId</span><span class="p">(</span><span class="nv">$mapId</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="nv">$map</span><span class="p">[</span><span class="s1">'mapId'</span><span class="p">],</span> <span class="nv">$map</span><span class="p">[</span><span class="s1">'name'</span><span class="p">]);</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">add</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$sql</span> <span class="o">=</span> <span class="sh">&lt;&lt;&lt;SQL\n INSERT INTO map ("mapId", name)\n VALUES (:mapId, :name)\n ON CONFLICT ("mapId")\n DO UPDATE SET name = :name;\n SQL;</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="nv">$sql</span><span class="p">,</span> <span class="p">[</span><span class="s1">'mapId'</span> <span class="o">=&gt;</span> <span class="nv">$map</span><span class="p">,</span> <span class="s1">'name'</span> <span class="o">=&gt;</span> <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">name</span><span class="p">()]);</span>\n <span class="p">}</span>\n\n <span class="k">private</span> <span class="k">function</span> <span class="n">executeQuery</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$sql</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$data</span><span class="p">):</span> <span class="kt">Result</span>\n <span class="p">{</span>\n <span class="c1">// Execute query or throw logic exceptions if something goes wrong.</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> Thanks to the clause <a href="https://www.postgresql.org/docs/9.5/sql-insert.html">ON CONFLICT</a> we can easily insert or update data with a single query.</p>\n\n<h2 id="entity-design-impacts">Entity design impacts</h2>\n\n<p>Now we are able to persist and retrieve our map entity. Let’s study the impact on entity design.</p>\n\n<p>Let’s start with persistence. In the previous example, I used getters to get its properties but I am not a fan of the getter to be honest! Getters break data encapsulation because they expose object implementation details. They don’t follow the <a href="https://www.martinfowler.com/bliki/TellDontAsk.html">Tell don’t ask</a> principle because we should not ask about the object state to do something, we should tell the object to do something for us. I like adding a <code class="language-plaintext highlighter-rouge">toState</code> method that is responsible to turn the entity into an associative array.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">toState</span><span class="p">():</span> <span class="kt">array</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="p">[</span>\n <span class="s1">'mapId'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span><span class="p">,</span>\n <span class="s1">'name'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">,</span>\n <span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>So I just need to call the <code class="language-plaintext highlighter-rouge">toState</code> method instead of getters, this method returns data expected by the <code class="language-plaintext highlighter-rouge">executeQuery</code> method.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PostgreSqlMaps</span> <span class="kd">implements</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">add</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="nv">$sql</span><span class="p">,</span> <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">toState</span><span class="p">());</span>\n <span class="p">}</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Let’s continue with retrieval. If we have a look at the <code class="language-plaintext highlighter-rouge">Map</code>constructor method we can see that a <code class="language-plaintext highlighter-rouge">MapInitialized</code> event is recorded there. Houston, we have a problem! When we build an entity from its state (data stored somewhere) we don’t want to record any event because nothing happens. So, we need to find a solution to avoid recording those events.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">,</span>\n <span class="kt">MapName</span> <span class="nv">$name</span>\n<span class="p">)</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span> <span class="o">=</span> <span class="nv">$mapId</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">recordEvent</span><span class="p">(</span><span class="k">new</span> <span class="nc">MapInitialized</span><span class="p">(</span>\n <span class="nv">$mapId</span><span class="p">,</span>\n <span class="nv">$name</span>\n <span class="p">));</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>I like adding a named constructor called <code class="language-plaintext highlighter-rouge">fromState</code> to the entity. This constructor is responsible for building the aggregate from the state. Moreover, named constructors are explicit and give developers information about when to use them. In the following example, after calling the <a href="https://arnolanglade.github.io/build-object-using-php.html">primary constructor</a> we call the <code class="language-plaintext highlighter-rouge">eraseRecordedEvents</code> method to reset events before returning the object in the right state.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">fromState</span><span class="p">(</span><span class="kt">array</span> <span class="nv">$state</span><span class="p">):</span> <span class="kt">self</span>\n<span class="p">{</span>\n <span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="nv">$state</span><span class="p">[</span><span class="s1">'mapId'</span><span class="p">]),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$state</span><span class="p">[</span><span class="s1">'name'</span><span class="p">])</span>\n <span class="p">);</span>\n\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">eraseRecordedEvents</span><span class="p">();</span>\n\n <span class="k">return</span> <span class="nv">$map</span><span class="p">;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>So, the only change in the repository is to build the <code class="language-plaintext highlighter-rouge">Map</code> entity from the named constructor.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PostgreSqlMaps</span> <span class="kd">implements</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">get</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">Map</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n\n <span class="k">return</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">fromState</span><span class="p">(</span><span class="nv">$map</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h2 id="last-word">Last word</h2>\n\n<p>I did a presentation about the repository design pattern at the Forum PHP in 2018. A video is only available in French <a href="https://www.youtube.com/watch?v=cYFKkhtIr8w&amp;ab_channel=AFUPPHP">here</a> but the slides are in English <a href="https://arnolanglade.gitlab.io/bad-or-good-repository/">here</a> (press “s” to display English notes). Even if this presentation was made for Doctrine ORM it gives a lot of information about the pattern.</p>\n\n<p><strong>Note:</strong> In this talk I spoke about generating the entity identity by the repository. To be honest, I stopped doing that because generating it from controllers is easier and makes the repository design simpler.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 23 Mar 2021 00:00:00 -0500\n https://arnolanglade.github.io/persisting-entities-without-orm.html?s=feed\n https://arnolanglade.github.io/persisting-entities-without-orm.html\n \n OOP\n \n design-patterns\n \n \n \n \n \n OOP: how to build an object\n <p>In this new blog post, I want to talk about object building more specifically about primary and secondary constructors. The primary constructor is the default way to build an object with all its dependencies. The secondary constructors provide other ways to build objects depending on use cases.</p>\n\n<p><strong>Note:</strong> I did not work on a PHP8 project yet so that is why I won’t talk about named arguments feature.</p>\n\n<h2 id="primary-constructor">Primary constructor</h2>\n\n<p>The PHP language provides a single way to build an object thanks to the <code class="language-plaintext highlighter-rouge">__construct()</code> method. I use this method to define the primary constructor of my classes to encapsulate all their dependencies.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">MapName</span> <span class="nv">$name</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">CartographersAllowedToEditMap</span> <span class="nv">$cartographersAllowedToEditMap</span><span class="p">;</span>\n <span class="cd">/** @var Marker[] */</span>\n <span class="k">private</span> <span class="kt">array</span> <span class="nv">$markers</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">MapName</span> <span class="nv">$name</span><span class="p">,</span>\n <span class="kt">CartographersAllowedToEditMap</span> <span class="nv">$cartographersAllowedToEditMap</span><span class="p">,</span>\n <span class="kt">Marker</span> <span class="mf">...</span><span class="nv">$markers</span>\n <span class="p">)</span> <span class="p">{</span> \n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">cartographersAllowedToEditMap</span> <span class="o">=</span> <span class="nv">$cartographersAllowedToEditMap</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markers</span> <span class="o">=</span> <span class="nv">$markers</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> If your objects encapsulate a collection of a specific type (like the <code class="language-plaintext highlighter-rouge">Marker</code> in this example), you can use variadic arguments to automatically validate each item of this collection. Here, we don’t need to iterate the collection to check the type of its items, the language does it for us.</p>\n\n<h2 id="secondary-constructor">Secondary constructor</h2>\n\n<p>The PHP language does not ease the data encapsulation because it only provides a single way to build objects but we should be able to define several constructors depending on all our use cases. How to solve this problem? Named constructors! Named constructors are static factories, in other words static methods that build the object itself.\nLet’s take an example with the map object. How to initialize a map without any marker?</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">initialize</span><span class="p">(</span>\n <span class="kt">string</span> <span class="nv">$name</span><span class="p">,</span>\n <span class="kt">array</span> <span class="nv">$cartographerAllowedToEditMap</span>\n <span class="p">):</span> <span class="kt">self</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$name</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">CartographersAllowedToEditMap</span><span class="p">(</span><span class="nv">$cartographerAllowedToEditMap</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Here, we added a named constructor called <code class="language-plaintext highlighter-rouge">initialize</code> to the <code class="language-plaintext highlighter-rouge">Map</code> class. It uses the primary constructor to build the map object with an empty collection of Marker objects.</p>\n\n<p><strong>Tip:</strong> Some developers change the visibility of the primary constructor method to private but I am not a big fan of that. I use object comparison to test objects to avoid the usage of getters. I like keeping my primary constructor public because it allows me to build objects in any state to compare them to other ones.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">adds</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="n">marker</span><span class="err"> </span><span class="n">on</span><span class="err"> </span><span class="n">the</span><span class="err"> </span><span class="nf">map</span><span class="p">()</span>\n<span class="p">{</span>\n <span class="nv">$actualMap</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">initialize</span><span class="p">(</span>\n <span class="s1">'Bons plans sur Nantes'</span><span class="p">,</span>\n <span class="p">[</span><span class="s1">'Arnaud'</span><span class="p">]</span>\n <span class="p">);</span>\n\n <span class="nv">$actualMap</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">);</span>\n\n <span class="nv">$expectedMap</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="s1">'Bons plans sur Nantes'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">CartographersAllowedToEditMap</span><span class="p">([</span><span class="s1">'Arnaud'</span><span class="p">]),</span>\n <span class="k">new</span> <span class="nc">Marker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">)</span>\n <span class="p">);</span>\n \n <span class="nf">assertSame</span><span class="p">(</span><span class="nv">$actualMap</span><span class="p">,</span> <span class="nv">$expectedMap</span><span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Wed, 10 Mar 2021 00:00:00 -0600\n https://arnolanglade.github.io/oop-how-to-build-an-object.html?s=feed\n https://arnolanglade.github.io/oop-how-to-build-an-object.html\n \n OOP\n \n design-patterns\n \n \n \n \n \n How to validate a command?\n <p>In my previous <a href="http://arnolanglade.github.io/command-handler-patterns.html">blog post</a>, I talked about command and command handler design patterns. I got several questions about data validation and how to give feedback to users. We are going to talk about several kinds of data validation in this blog post. We will start with domain validation, this validation ensures we can build our domain objects in a good state depending on business rules. Then, we will talk about command validation and how we can use it to give feedback to users when they submit data to the application.</p>\n\n<p>Let’s take the same example I used in my previous blog post: an account creation. To create an account, my business expert expects that I provide a username and a password. The username should have at least three characters and should be unique. The password should have at least eight characters, an uppercase letter, a lowercase letter, and a number.</p>\n\n<h2 id="domain-validation">Domain validation</h2>\n\n<p>How to make sure the domain objects follow the business rules? Value object will help us to achieve that. I <strong>strongly recommend you</strong> to wrap all primitives into value objects. It is a good way to introduce new types in your codebase, make it clearer and business-focused. And don’t forget, value objects <strong>cannot</strong> be built in a wrong state.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Username</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$username</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span><span class="err">\\</span><span class="nb">strlen</span><span class="p">(</span><span class="nv">$username</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="err">\\</span><span class="nf">InvalidArgumentException</span><span class="p">(</span><span class="s1">'The username is too short, it should contain at least 3 characters'</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">Password</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span><span class="mi">1</span> <span class="o">!==</span> <span class="err">\\</span><span class="nb">preg_match</span><span class="p">(</span><span class="s1">'#(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,}#'</span><span class="p">,</span> <span class="nv">$password</span><span class="p">))</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="err">\\</span><span class="nf">InvalidArgumentException</span><span class="p">(</span>\n <span class="s1">'The password must contain at least 8 characters, an uppercase letter, lowercase letter and a number'</span>\n <span class="p">);</span>\n <span class="p">}</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then we are able to modelize the <code class="language-plaintext highlighter-rouge">Account</code> aggregate using the <code class="language-plaintext highlighter-rouge">Username</code> and <code class="language-plaintext highlighter-rouge">Password</code> value objects.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Account</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Username</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">Password</span> <span class="nv">$password</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">Username</span> <span class="nv">$username</span><span class="p">,</span>\n <span class="kt">Password</span> <span class="nv">$password</span>\n <span class="p">)</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, we are sure that as developers we cannot instantiate the <code class="language-plaintext highlighter-rouge">Account</code> aggregate in a wrong state. In the next section, we are going to see how to use the domain objects to give users feedback about their data.</p>\n\n<h2 id="command-validation">Command validation</h2>\n\n<p>As I explained in my previous <a href="http://arnolanglade.github.io/command-handler-patterns.html">blog post</a>, an account creation is represented by a <code class="language-plaintext highlighter-rouge">CreateAnAccount</code> command with two properties: the username and the password. We need to validate them to create the account aggregate without any errors and tell users if they provided valid data to perform this action. The command validation will be done by the Symfony validator. Don’t hesitate to have a look at the <a href="https://symfony.com/doc/current/validation.html">validator documentation</a> if you are not familiar with it.</p>\n\n<p>First, we will use the callback constraint to make sure the username and password follow the patterns given by the business expert. Thanks to annotation we will configure the validator to call a static method to validate command properties. I will call them “static validators“ in this blog post.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="cd">/** @Assert\\Callback({"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\UsernameShouldBeValid", "validate"}) */</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="cd">/** @Assert\\Callback({"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\PasswordShouldBeValid", "validate"}) */</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then, it is time to create those static validators. We just need to instantiate our value objects and check if they throw exceptions to catch them and turn them into violations.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">UsernameShouldBeValid</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">ExecutionContextInterface</span> <span class="nv">$context</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="k">try</span> <span class="p">{</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$username</span><span class="p">);</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="err">\\</span><span class="nc">InvalidArgumentException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>\n <span class="nv">$context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'account.usernameShouldBeValid'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">PasswordShouldBeValid</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">,</span> <span class="kt">ExecutionContextInterface</span> <span class="nv">$context</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="k">try</span> <span class="p">{</span>\n <span class="k">new</span> <span class="nc">Password</span><span class="p">(</span><span class="nv">$password</span><span class="p">);</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="err">\\</span><span class="nc">InvalidArgumentException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>\n <span class="nv">$context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'account.passwordShouldBeValid'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>For more complex use cases you can call any methods on value objects, but you need to keep in mind that you cannot inject services into those static validators.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="kt">BookFlightTicket</span> <span class="nv">$flightTicket</span><span class="p">,</span> <span class="kt">ExecutionContextInterface</span> <span class="nv">$context</span><span class="p">):</span> <span class="kt">void</span>\n<span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span>\n <span class="o">!</span><span class="nc">Date</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="nv">$flightTicket</span><span class="o">&gt;</span><span class="n">departureDate</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">laterThan</span><span class="p">(</span>\n <span class="nc">Date</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="nv">$flightTicket</span><span class="o">&gt;</span><span class="n">arrivalDate</span><span class="p">)</span>\n <span class="p">)</span>\n <span class="p">)</span> <span class="p">{</span>\n <span class="nv">$context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'flightTicket.dateShouldBeValid'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The first step is done! Thanks to those static validators, we apply domain validation on command properties to ensure we can instantiate domain objects. But, domain validation only works with a single account because the account aggregate only represents the account of a single user. For instance, an account cannot validate if a username is unique because it needs to be aware of the rest of the created account.</p>\n\n<p>To check if a username is used by another user we will need to ask the repository if an account already exists with the given username. That’s why we will need to create a custom validation constraint because those constraints are declared as services, and they can depend on other application services.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cd">/** @Annotation */</span>\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">UsernameShouldBeUnique</span> <span class="kd">extends</span> <span class="nc">Constraint</span>\n<span class="p">{</span>\n<span class="p">}</span>\n\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">UsernameShouldBeUniqueValidator</span> <span class="kd">extends</span> <span class="nc">ConstraintValidator</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span> <span class="o">=</span> <span class="nv">$accounts</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="nv">$username</span><span class="p">,</span> <span class="kt">Constraint</span> <span class="nv">$constraint</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nv">$constraint</span> <span class="k">instanceof</span> <span class="nc">UsernameShouldBeUnique</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">UnexpectedTypeException</span><span class="p">(</span><span class="nv">$constraint</span><span class="p">,</span> <span class="nc">UsernameShouldBeUnique</span><span class="o">::</span><span class="n">class</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">try</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span><span class="o">-&gt;</span><span class="nf">getByUsername</span><span class="p">(</span><span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$username</span><span class="p">));</span>\n\n <span class="c1">// an exception is thrown if an account does not exist so we don’t add violation</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'account.usernameShouldBeUnique'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">UnknownAccount</span> <span class="nv">$exception</span><span class="p">)</span> <span class="p">{</span>\n <span class="p">}</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Finally, we need to configure the validator to apply this new constraint to the username property.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cd">/**\n * @Assert\\GroupSequence({"CreateAnAccount", "Business"})\n */</span>\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="cd">/** \n * @Assert\\Callback({"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\UsernameShouldBeValid", "validate"})\n * @Domain\\Account\\UseCase\\ValidationRule\\UsernameShouldBeUnique(groups={"Business"})\n */</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$username</span><span class="p">;</span>\n \n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Caution:</strong> we need to apply static validators before applying custom constraints because we need to be sure we can instantiate all domain objects without raising any error. For instance, the instantiation of <code class="language-plaintext highlighter-rouge">Username</code> in <code class="language-plaintext highlighter-rouge">UsernameShouldBeUniqueValidator</code> must not raise any error because the goal of this constraint is not to check if the username contains at least three characters but if the username is already used. It can be done with <a href="https://symfony.com/doc/current/validation/sequence_provider.html">GroupSequence</a>. This validator feature allows adding groups to constraints and defining the validation constraint execution order.</p>\n\n<p>Now, this is the end of the story! If commands are invalid, we just need to serialize violations, give them to your front application, and print errors to users.</p>\n\n<h2 id="last-word">Last word</h2>\n\n<p>This might not be the only way to validate data but it worked on my previous project. Even if I use a service to validate my command I try to use as many domain objects as possible to avoid reinventing the wheel. I hope it answers Baptiste Langlade’s <a href="https://twitter.com/Baptouuuu/status/1364945053236494336">question</a> on Twitter. If you wonder, Baptiste is not my brother ;).</p>\n\n<p>Thanks to my proofreaders <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a> and <a href="https://twitter.com/jjanvier_">@jjanvier_</a>.</p>\n\n Thu, 04 Mar 2021 00:00:00 -0600\n https://arnolanglade.github.io/how-to-validate-a-command.html?s=feed\n https://arnolanglade.github.io/how-to-validate-a-command.html\n \n command-bus\n \n design-patterns\n \n \n \n \n \n Command and command handler design pattern\n <p>This pattern is really interesting; it can help you handle use cases. A command represents the user’s intent, while the command handler performs the actions needed to achieve the use case. Let’s dig a bit into these two concepts.</p>\n\n<h2 id="what-is-a-command">What is a command?</h2>\n\n<p>A command is an object used to encapsulate all the information needed to perform an action. This design pattern is used to represent user intents, and the command is given to a command handler.</p>\n\n<p>A command is often designed as a Data Transfer Object (DTO), which is an object without any behavior (a data structure). The most important design rule to consider is that a command should be easily serializable. This way, it can be sent to a queue such as RabbitMQ or pub-sub to be handled asynchronously.</p>\n\n<h2 id="what-is-a-command-handler">What is a command handler?</h2>\n\n<p>A command handler is just a callable that executes all the actions needed to fulfill a user’s intent. As you may understand, this design pattern is perfect for managing your business use cases.</p>\n\n<h2 id="how-does-it-work">How does it work?</h2>\n\n<p><img src="images/posts/command-handler/explain-command-handler.svg" alt="Command handler design pattern" /></p>\n\n<p>This pattern has some rules. The first one is that a command can be handled by a single command handler because there is only a single way to handle a use case. The second rule is that a command handler should receive a valid command. Validating the command ensures that the user provides the correct data to prevent the handling from failing. It also helps to provide early feedback to the user about the data they provided.</p>\n\n<p>The command is only a DTO that carries data while the command handler is responsible to handle use cases.</p>\n\n<h2 id="how-to-use-it">How to use it?</h2>\n\n<p>Let’s consider a simple example: creating an account. Our business expert expects users to provide an email and a password to create an account for login purposes. We will create a command named <code class="language-plaintext highlighter-rouge">CreateAnAccount</code> and its handler, <code class="language-plaintext highlighter-rouge">CreateAnAccountHandler</code>.\nFirst, we need to create a command named <code class="language-plaintext highlighter-rouge">CreateAnAccount</code> to represent the user’s intent.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="kt">readonly</span> <span class="n">string</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="k">public</span> <span class="kt">readonly</span> <span class="n">string</span> <span class="nv">$password</span><span class="p">;</span>\n \n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">)</span> \n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Next, we need to create a command handler to manage this use case. The command handler can be a function or an invocable object. It should return nothing (void) to be handled asynchronously as we don’t know when it will be processed and can’t expect an instant result. Using the command data, we perform all actions needed to handle the use case. In our example, we create an account aggregate and pass it to the account repository.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccountHandler</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span> <span class="o">=</span> <span class="nv">$accounts</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">CreateAnAccount</span> <span class="nv">$createAnAccount</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$account</span> <span class="o">=</span> <span class="nc">Account</span><span class="o">::</span><span class="nf">create</span><span class="p">(</span>\n <span class="nv">$createAnAccount</span><span class="o">-&gt;</span><span class="nf">username</span><span class="p">(),</span>\n <span class="nv">$createAnAccount</span><span class="o">-&gt;</span><span class="nf">password</span><span class="p">()</span>\n <span class="p">);</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span><span class="o">-&gt;</span><span class="nf">add</span><span class="p">(</span><span class="nv">$account</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Finally, let’s stick those pieces of code together in a controller (this example is made with a Symfony Framework). This controller receives JSON-encoded data to create a command, which is then validated and passed to the handler</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n \n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">Request</span> <span class="nv">$request</span><span class="p">):</span> <span class="kt">Response</span>\n <span class="p">{</span>\n <span class="nv">$command</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">serializer</span><span class="o">-&gt;</span><span class="nf">deserialize</span><span class="p">(</span>\n <span class="nv">$request</span><span class="o">-&gt;</span><span class="nf">getContent</span><span class="p">(),</span>\n <span class="nc">CreateAnAccount</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>\n <span class="s1">'json'</span>\n <span class="p">);</span>\n \n <span class="nv">$violations</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">validator</span><span class="o">-&gt;</span><span class="nf">validate</span><span class="p">(</span><span class="nv">$command</span><span class="p">);</span>\n \n <span class="k">if</span> <span class="p">(</span><span class="mi">0</span> <span class="o">&lt;</span> <span class="nv">$violations</span><span class="o">-&gt;</span><span class="nb">count</span><span class="p">())</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">BadRequestHttpException</span><span class="p">(</span><span class="cm">/*json encoded violation*/</span><span class="p">);</span>\n <span class="p">}</span>\n \n <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">createAnAccountHandler</span><span class="p">)(</span><span class="nv">$command</span><span class="p">);</span>\n \n <span class="k">return</span> <span class="k">new</span> <span class="nc">JsonResponse</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nc">Response</span><span class="o">::</span><span class="no">HTTP_CREATED</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n</code></pre></div></div>\n<p><strong>Tip:</strong> : To simplify command creation, you can use libraries such as the Symfony Serializer component. It eases object creation from a set of data (e.g., JSON), making the process easier and faster.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$createAccount</span> <span class="o">=</span> <span class="nv">$serializer</span><span class="o">-&gt;</span><span class="nf">deserialize</span><span class="p">(</span>\n <span class="s1">'{“username”:”arnaud”, “password”:“password”}'</span><span class="p">,</span>\n <span class="nc">CreateAnAccount</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>\n <span class="s1">'json'</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p>Tip: To avoid reinventing the wheel, you can leverage libraries like the Symfony Validator component to validate the command.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$violation</span> <span class="o">=</span> <span class="nv">$validator</span><span class="o">-&gt;</span><span class="nf">validate</span><span class="p">(</span><span class="nv">$createAccount</span><span class="p">);</span>\n</code></pre></div></div>\n\n<p>I’ve written a dedicated blog post explaining how to validate a command:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/how-to-validate-a-command.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/data-validation.webp" alt="How to validate a command?" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">How to validate a command?</span>\n </span>\n </a>\n</div>\n\n<h2 id="how-to-simplify-that">How to simplify that?</h2>\n\n<p>To simplify this controller, consider using a command bus, which is responsible for finding the right handler for a given command. For more information about this pattern, I’ve written a dedicated blog post explaining how it works:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-bus-design-pattern.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-bus/command-bus.svg" alt="The command bus design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">The command bus design pattern</span>\n </span>\n </a>\n</div>\n\n<p>The following example is built with <a href="https://symfony.com/doc/current/components/messenger.html">Symfony Messenger</a>.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">Request</span> <span class="nv">$request</span><span class="p">):</span> <span class="kt">Response</span>\n<span class="p">{</span>\n <span class="nv">$command</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">serializer</span><span class="o">-&gt;</span><span class="nf">deserialize</span><span class="p">(</span>\n <span class="nv">$request</span><span class="o">-&gt;</span><span class="nf">getContent</span><span class="p">(),</span>\n <span class="nc">CreateAnAccount</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>\n <span class="s1">'json'</span>\n <span class="p">);</span>\n \n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">commandBus</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nv">$command</span><span class="p">);</span>\n \n <span class="k">return</span> <span class="k">new</span> <span class="nc">JsonResponse</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nc">Response</span><span class="o">::</span><span class="no">HTTP_CREATED</span><span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Where is the command validation in this example? Command buses are often built with middleware, making them highly configurable. To ensure that all commands are valid before passing them to a command handler, we need to add middleware to the command bus for command validation.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">ValidationMiddleware</span> <span class="kd">implements</span> <span class="nc">MiddlewareInterface</span>\n<span class="p">{</span>\n <span class="c1">// …</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">handle</span><span class="p">(</span><span class="kt">Envelope</span> <span class="nv">$envelope</span><span class="p">,</span> <span class="kt">StackInterface</span> <span class="nv">$stack</span><span class="p">):</span> <span class="kt">Envelope</span>\n <span class="p">{</span>\n <span class="nv">$message</span> <span class="o">=</span> <span class="nv">$envelope</span><span class="o">-&gt;</span><span class="nf">getMessage</span><span class="p">();</span> \n <span class="nv">$violations</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">validator</span><span class="o">-&gt;</span><span class="nf">validate</span><span class="p">(</span><span class="nv">$message</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nv">$groups</span><span class="p">);</span>\n <span class="k">if</span> <span class="p">(</span><span class="err">\\</span><span class="nb">count</span><span class="p">(</span><span class="nv">$violations</span><span class="p">))</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">ValidationFailedException</span><span class="p">(</span><span class="nv">$message</span><span class="p">,</span> <span class="nv">$violations</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="nv">$stack</span><span class="o">-&gt;</span><span class="nb">next</span><span class="p">()</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nv">$envelope</span><span class="p">,</span> <span class="nv">$stack</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> Take a look at this blog post if you need to manage user permissions. Adding a middleware to the command bus can enhance the security of your application:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/how-to-handle-user-permissions-through-command-bus-middleware.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/how-to-handle-permissions-through-command-bus-middleware.webp" alt="How to handle user permissions through command bus middleware" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">How to handle user permissions through command bus middleware</span>\n </span>\n </a>\n</div>\n\n<h2 id="my-last-thoughts">My last thoughts</h2>\n\n<p>In many applications,I have seen a lot of classes named managers or services (e.g., AccountService, AccountManager) that gather all use case management into a single class. While this approach might be effective initially as development progresses, these classes tend to grow larger and larger, and become a “god object.” This makes maintenance challenging, reduces readability, and can quickly turn into a dump. I believe this pattern can address these issues.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Thu, 25 Feb 2021 00:00:00 -0600\n https://arnolanglade.github.io/command-handler-patterns.html?s=feed\n https://arnolanglade.github.io/command-handler-patterns.html\n \n command-bus\n \n design-patterns\n \n \n \n \n \n\n","url":"/feed.xml","relative_path":"_pages/feed.xml"},{"draft":false,"categories":[],"layout":"default","permalink":"/","title":"Home","content_blocks":[{"_bookshop_name":"hero","title":"Hi there, I am Arnaud!","description_html":"

\n I am a software architect, and technical coach. I focus on understanding business needs to find the best solution. I love everything that ends with *DD such as DDD, BDD and TDD. These tools and all eXtreme Programming values help me to build robust and maintainable software. Last but not least, teamwork is essential: «alone we go faster, together we go further».\n

","image":"/images/me-home.webp","image_alt":"Arnaud Langlade's picture","cta_button":"Contact me","cta_button_link":"/contact/","works_button":"About me","works_button_link":"/about"},{"_bookshop_name":"services-section"},{"_bookshop_name":"testimonials-section","link_url":"/experiences"},{"_bookshop_name":"blog-section","link_url":"/blog"},{"_bookshop_name":"talks-section","link_url":"/talks"}],"slug":"index","ext":".html","tags":[],"excerpt":"","date":"2024-01-02 05:30:02 -0600","content":"","url":"/","relative_path":"_pages/index.html"},{"draft":false,"categories":[],"layout":"default","title":"The mikadoApp","content_blocks":[{"_bookshop_name":"page-heading","title":"The mikadoApp"},{"_bookshop_name":"content","content":"## The mikado method\n\nThe Mikado method takes its name from the Mikado game, where the goal is to remove one stick without disturbing the others. The Mikado method has the same philosophy. It aims to make small incremental improvements to a project without breaking the existing codebase.\n\nOla Ellnestam and Daniel Brolund developed the Mikado Method based on their experience in resolving technical debt in complex legacy systems. They published a book called [The Mikado Method](https://www.manning.com/books/the-mikado-method)\n\nThis method simplifies refactoring. You can continuously improve your codebase instead of stacking a lot of changes which can’t be merged because the test suites are broken. It’s better to regularly merge small changes that improve your codebase quality. This method is ideal for brownfield development. It enables you to add new features or alter existing ones without breaking the rest of the application. Moreover, it facilitates the improvement of the application's architecture while allowing the delivery of new features concurrently.\n\nFor more information, have a look at my blog post on the [Mikado Method](/mikado-method.html)\n\n## Try the MikadoApp\nTry the Mikado App online. For now, I am only using the Vercel free plan, meaning the application may be slow.\n\n
\n \n \n \n \n Try the MikadoApp\n \n
\n\n\nThis project is open source, so don’t hesitate to contribute to the application to improve it! Submit an issue for bugs and share your ideas to enhance the application. Pull requests are very welcome too. The source code is available on\nGitHub.\n\n
\n \n \n Sources on GitHub\n \n
\n\n## How to use the MikadoApp\nLet’s take an example: MySQL doesn’t match the project's needs; you want to migrate your application to PostgreSQL.\nOn the homepage of the Mikado App, enter your objective. Explain what you want to do and click on the “Start” button to begin working.\n\n![describe objective](/images/mikado-app/describe-objective.webp)\n\nThen you arrive on the mikado graph page. You can split your objective into small steps called prerequisites. To achieve the database migration, we first need to install the database and update the repositories due to the usage of SQL queries specific to MySQL.\n\nClick on the 'Add a prerequisite' button to open the prerequisite addition form. Then, describe the actions required to complete the prerequisite. Finally, click on the 'Add' button to add the prerequisite to the Mikado Graph:\n\n![add prerequisite](/images/mikado-app/add-prerequisite.webp)\n\nYou can create as many prerequisites as you want. Don’t forget that small steps are easier to take! As you can see in the following screenshot, the prerequisite bubble has an orange background, indicating indicating the prerequisites have the status ‘To do’:\n\n![prerequisite list](/images/mikado-app/prerequisite-list.webp)\n\nAfter adding prerequisites, select one from the list and click on the “Start exploring” button to start experimenting with things to solve it. The background color of the prerequisite changes to blue, indicating that the prerequisite status is now “Experimenting,” meaning you are actively working on it.\n\nNow, you have two choices: the first one is to click on the “Add a prerequisite” button to split the prerequisite into smaller steps.\n\n![prequisite buble](/images/mikado-app/prequisite-buble.webp)\n\nThe second option is to click on 'Commit your changes' when you finish it and proceed to the next one on the list.\n\n![prerequisite completed](/images/mikado-app/prerequisite-completed.webp)\n\nContinue resolving all prerequisites until the end. When all prerequisites are done, your objective is completed!\n\n![objective completed](/images/mikado-app/objective-completed.webp)\n"},{"_bookshop_name":"blog-section","link_url":"/blog"},{"_bookshop_name":"newsletter"}],"slug":"mikado-app","ext":".html","tags":[],"excerpt":"","date":"2024-01-02 05:30:02 -0600","content":"","url":"/mikado-app/","relative_path":"_pages/mikado-app.html","permalink":null},{"draft":false,"categories":[],"layout":"default","title":"Anaud Langlade's newsletter","content_blocks":[{"_bookshop_name":"page-heading","title":""},{"_bookshop_name":"newsletter"},{"_bookshop_name":"blog-section"}],"slug":"newsletter","ext":".html","tags":[],"excerpt":"","date":"2024-01-02 05:30:02 -0600","content":"","url":"/newsletter/","relative_path":"_pages/newsletter.html","permalink":null},{"draft":false,"categories":[],"layout":"default","title":"Subscription Confirmed - Arnaud Langlade","content_blocks":[{"_bookshop_name":"page-heading","title":"Subscription Confirmed","description":"

\n Your subscription to the newsletter has been confirmed.\n

\n Thank you for subscribing!\n

"},{"_bookshop_name":"blog-section","title":"Recent Posts","link_url":"/blog","show_posts":true}],"slug":"subscription-confirmed","ext":".html","tags":[],"excerpt":"","date":"2024-01-02 05:30:02 -0600","content":"","url":"/subscription-confirmed/","relative_path":"_pages/subscription-confirmed.html","permalink":null},{"draft":false,"categories":[],"layout":"default","title":"Arnaud Langlade's talks","description":"Here are my talks. I love sharing my knowledge about software engineering such as architectural design patterns, software testing, methodologies and so on.","content_blocks":[{"_bookshop_name":"page-heading","title":"My talks"},{"_bookshop_name":"talks-list","show_talks":true},{"_bookshop_name":"blog-section","link_url":"/blog"},{"_bookshop_name":"newsletter"}],"slug":"talks","ext":".html","tags":[],"excerpt":"","date":"2024-01-02 05:30:02 -0600","content":"","url":"/talks/","relative_path":"_pages/talks.html","permalink":null}],"talks":[{"draft":false,"categories":[],"layout":"talk","title":"Programmation STUPID vs SOLID","conference":"Bordeaux PHP Meetup","image":"meetup-php.png","permalink":"/talks/:title:output_ext","date":"2014-01-01 00:00:00 -0600","slug":"meetup-php","ext":".md","tags":[],"excerpt":"

Slides

\n","content":"

Slides

\n\n\n","url":"/talks/meetup-php.html","relative_path":"_talks/2014-01-01-meetup-php.md"},{"draft":false,"categories":[],"layout":"talk","title":"Développer avec le sylius resourcebundle","conference":"Symfony live Paris 2015","conference_link":"https://live.symfony.com/2015-paris","image":"symfony-live.jpg","permalink":"/talks/:title:output_ext","description":"The resource bundle easy CRUD and persistence for Symfony applications.","keyword":"sylius,resource bundle,crud,symfony,rad","date":"2015-03-01 00:00:00 -0600","slug":"symfony-live-2015","ext":".md","tags":[],"excerpt":"

The resource bundle easy CRUD and persistence for Symfony applications.

\n","content":"

The resource bundle easy CRUD and persistence for Symfony applications.

\n\n

During our work on Sylius, the core team noticed a lot of duplicated code across all controllers. The core team started looking for good solution of the problem. The core team is not big fans of administration generators (they’re cool, but not for our usecase!) - the core team wanted something simpler and more flexible.

\n\n

Another idea was to not limit ourselves to one persistence backend. Initial implementation included custom manager classes, which was quite of overhead, so the core team decided to simply stick with Doctrine Common Persistence interfaces. If you are using Doctrine ORM or any of the ODM’s, you’re already familiar with those concepts. Resource bundle relies mainly on ObjectManager and ObjectRepository interfaces.

\n\n

The last annoying problem this bundle is trying to solve, is having separate “backend” and “frontend” controllers, or any other duplication for displaying the same resource, with different presentation (view). The core team also wanted an easy way to filter some resources from list, sort them or display by id, slug or any other criteria - without having to defining another super simple action for that purpose.

\n\n

Videos

\n\n\n\n

Slides

\n\n\n\n

Resources

\n\n

\n Bundle documentation

\n\n

\n Github repository

\n\n

\n Sylius website

\n","url":"/talks/symfony-live-2015.html","relative_path":"_talks/2015-03-01-symfony-live-2015.md"},{"draft":false,"categories":[],"layout":"talk","title":"Php trollons, mais trollons bien!","conference":"Bdx.io 2015","conference_link":"https://www.bdxio.fr","image":"bdxio.jpg","permalink":"/talks/:title:output_ext","date":"2015-10-01 00:00:00 -0500","slug":"bdxio-2015","ext":".md","tags":[],"excerpt":"

Slides

\n","content":"

Slides

\n\n\n","url":"/talks/bdxio-2015.html","relative_path":"_talks/2015-10-01-bdxio-2015.md"},{"draft":false,"categories":[],"layout":"talk","title":"Code me a HR!","conference":"PHPtour 2017","conference_link":"https://event.afup.org/phptournantes2017","homepage":false,"image":"afup-day.png","permalink":"/talks/:title:output_ext","description":"I explain how to refactor an application that uses anaemic models to rich models. I introduce some design patterns like the repository, handling use cases with a command handler and the basics of CQRS.","keywords":"rich model,anemic model,ddd,cqrs,aggregate,command bus,command,command handler","date":"2017-01-01 00:00:00 -0600","slug":"php-tour-2017","ext":".md","tags":[],"excerpt":"

I explain how to refactor an application that uses anaemic models to rich models. I introduce some design patterns like the repository, handling use cases with a command handler and the basics of CQRS.

\n","content":"

I explain how to refactor an application that uses anaemic models to rich models. I introduce some design patterns like the repository, handling use cases with a command handler and the basics of CQRS.

\n\n

Videos

\n\n\n\n

Slides

\n\n\n\n

Resources

\n\n

\n Code example

\n","url":"/talks/php-tour-2017.html","relative_path":"_talks/2017-01-01-php-tour-2017.md"},{"draft":false,"categories":[],"layout":"talk","title":"What is the difference between a good and a bad repository?","conference":"Forum PHP 2018","conference_link":"https://event.afup.org/forumphp2018","homepage":true,"image":"forum-php.png","permalink":"/talks/:title:output_ext","description":"I explain what is the repository pattern and how to design it thanks to Doctrine. I gave some tips to query data without struggling with the ORM.","keywords":"doctrine, repository, design pattern, query function, cqrs, forum php","date":"2018-10-01 00:00:00 -0500","slug":"forum-php-2018","ext":".md","tags":[],"excerpt":"

I explain what is the repository pattern and how to design it thanks to Doctrine. I gave some tips to query data without struggling with the ORM.

\n","content":"

I explain what is the repository pattern and how to design it thanks to Doctrine. I gave some tips to query data without struggling with the ORM.

\n\n

Videos

\n\n\n\n

Slides

\n\n\n\n

Resources

\n\n

\n Code example

\n\n

\n Speaker interview

\n","url":"/talks/forum-php-2018.html","relative_path":"_talks/2018-10-01-forum-php-2018.md"},{"draft":false,"categories":[],"layout":"talk","title":"Example Mapping: ease business knowledge sharing with your team","conference":"Agile Adour #2","conference_link":"https://lameleeadour.com/evenements/agile-adour-2/","image":"agile-adour.png","permalink":"/talks/:title:output_ext","keywords":"agile adour,example mapping,bdd,behavior driven development,agile adour,no estimate,team collaboration,sticky note,small story,domain problem","description":"I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team's understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.","date":"2022-12-01 00:00:00 -0600","slug":"agile-adour-2","ext":".md","tags":[],"excerpt":"

I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team’s understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.

\n","content":"

I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team’s understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.

\n\n

Slides

\n\n\n","url":"/talks/agile-adour-2.html","relative_path":"_talks/2022-12-01-agile-adour-2.md"},{"draft":false,"categories":[],"layout":"talk","title":"Example Mapping: ease business knowledge sharing with your team","conference":"Agile tour Rennes 2022","conference_link":"https://agiletour.agilerennes.org/","homepage":true,"image":"agile-tour-rennes.jpg","keywords":"agile tour rennes,example mapping,bdd,behavior driven development,agile tour rennes,no estimate,team collaboration,sticky note,small story,domain problem","description":"I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team's understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.","date":"2022-12-16 00:00:00 -0600","slug":"agile-tour-rennes-2022","ext":".md","tags":[],"excerpt":"

I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team’s understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.

\n","content":"

I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team’s understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.

\n\n

Slides

\n\n\n","url":"/talks/agile-tour-rennes-2022.html","relative_path":"_talks/2022-12-16-agile-tour-rennes-2022.md","permalink":null},{"draft":false,"categories":[],"layout":"talk","title":"Unit testing: essential and complicated at the same time","conference":"Alpes Craft 2023","conference_link":"https://www.alpescraft.fr","homepage":true,"image":"alpes-craft.png","keywords":"test,unit,unit test,dependency inversion,encapsulation,tdd,srp,composition,coupling","description":"When I started coding I could develop for hours without executing my code. Then, I needed to debug it for hours. It wasn't funny! I discovered what was testing and I understood its benefits. However, it wasn't easy to write my first tests. We can make many mistakes that make tests hard to write and maintain. I would like to present to you what I have learned over the last few years to help you write tests.","date":"2023-06-01 00:00:00 -0500","slug":"alpes-craft-2023","ext":".md","tags":[],"excerpt":"

When I started coding I could develop for hours without executing my code. Then, I needed to debug it for hours. It wasn’t funny! I discovered what was testing and I understood its benefits. However, it wasn’t easy to write my first tests. We can make many mistakes that make tests hard to write and maintain. I would like to present to you what I have learned over the last few years to help you write tests.

\n","content":"

When I started coding I could develop for hours without executing my code. Then, I needed to debug it for hours. It wasn’t funny! I discovered what was testing and I understood its benefits. However, it wasn’t easy to write my first tests. We can make many mistakes that make tests hard to write and maintain. I would like to present to you what I have learned over the last few years to help you write tests.

\n\n

Slides

\n\n\n","url":"/talks/alpes-craft-2023.html","relative_path":"_talks/2023-06-01-alpes-craft-2023.md","permalink":null},{"draft":false,"categories":[],"layout":"talk","title":"Example Mapping: ease business knowledge sharing with your team","conference":"Sunny tech 2023","conference_link":"https://sunny-tech.io/","homepage":false,"image":"sunny-tech.webp","keywords":"sunny tech,example mapping,bdd,behavior driven development,no estimate,team collaboration,sticky note,small story,domain problem","description":"I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team's understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.","date":"2023-06-30 00:00:00 -0500","slug":"sunny-tech-2023","ext":".md","tags":[],"excerpt":"

I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team’s understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.

\n","content":"

I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team’s understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.

\n\n

Videos

\n\n\n\n

Slides

\n\n\n","url":"/talks/sunny-tech-2023.html","relative_path":"_talks/2023-06-30-sunny-tech-2023.md","permalink":null},{"draft":false,"categories":[],"layout":"talk","title":"Unit testing: essential and complicated at the same time","conference":"Agile Tour Bordeaux 2023","conference_link":"https://agiletourbordeaux.fr","homepage":false,"image":"agile-tour-bordeaux.webp","keywords":"test,unit,unit test,dependency inversion,encapsulation,tdd,srp,composition,coupling","description":"When I started coding I could develop for hours without executing my code. Then, I needed to debug it for hours. It wasn't funny! I discovered what was testing and I understood its benefits. However, it wasn't easy to write my first tests. We can make many mistakes that make tests hard to write and maintain. I would like to present to you what I have learned over the last few years to help you write tests.","date":"2023-09-27 00:00:00 -0500","slug":"agile-tour-bordeaux","ext":".md","tags":[],"excerpt":"

When I started coding I could develop for hours without executing my code. Then, I needed to debug it for hours. It wasn’t funny! I discovered what was testing and I understood its benefits. However, it wasn’t easy to write my first tests. We can make many mistakes that make tests hard to write and maintain. I would like to present to you what I have learned over the last few years to help you write tests.

\n","content":"

When I started coding I could develop for hours without executing my code. Then, I needed to debug it for hours. It wasn’t funny! I discovered what was testing and I understood its benefits. However, it wasn’t easy to write my first tests. We can make many mistakes that make tests hard to write and maintain. I would like to present to you what I have learned over the last few years to help you write tests.

\n\n

Videos

\n\n\n\n

Slides

\n\n\n","url":"/talks/agile-tour-bordeaux.html","relative_path":"_talks/2023-09-27-agile-tour-bordeaux.md","permalink":null}],"testimonials":[{"draft":false,"categories":[],"layout":"default","name":"Arnaud LEMAIRE","position":"VP/Chief Architect at Sunday","homepage":true,"social_media_link":"https://www.linkedin.com/in/lilobase/","blurb":"Arnaud est un développeur exceptionnel, dont l'autonomie et l'initiative ont marqué son passage dans nos équipes. Sa capacité à prendre en charge des projets de A à Z ainsi que son esprit d'analyse et de synthèse en font un très bon leader technique. Si vous avez la chance d'avoir Arnaud dans votre équipe, vous verrez rapidement son impact positif. Je recommande Arnaud avec enthousiasme.","title":"40 Sunday","slug":"40-sunday","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/testimonials/40-sunday.html","relative_path":"_testimonials/40-sunday.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Denis Migot","position":"Engineer Manager at Sunday","homepage":false,"social_media_link":"https://www.linkedin.com/in/denis-migot","blurb":"J'ai eu la chance de travailler avec Arnaud pendant plusieurs mois au sein de Sunday. Je dis bien 'chance' car j'ai appris beaucoup à ses côtés, que ce soit sur l'exercice de son métier que sur l'environnement nécessaire au bon exercice de son métier. Je recommande donc chaudement Arnaud qui, au-delà de ses connaissances multiples et de son expertise profonde, est un collègue très agréable avec qui travailler !","title":"50 Sunday","slug":"50-sunday","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/testimonials/50-sunday.html","relative_path":"_testimonials/50-sunday.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Laurent Verdier","position":"Web developer at Palo IT","homepage":false,"social_media_link":"https://www.linkedin.com/in/lverdier/","blurb":"It was my pleasure to work in pair-programming with Arnaud for 3 months. His mastery of TDD and his ability to guide his teammates into it made the whole experience extremely profitable and allowed to produce a very well-decoupled, expressive code. We could rely a lot on his ability to split a big feature into smaller steps, without being confused by the general complexity of the task at hand. Finally, his constant focus on building iteratively things that work and bring value make him a 5* asset in a software development team.","title":"55 Laurent","slug":"55-laurent","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/testimonials/55-laurent.html","relative_path":"_testimonials/55-laurent.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Arnaud Faissolle","position":"Engineer Manager at Akeneo","social_media_link":"https://www.linkedin.com/in/arnaud-faissolle-249315","blurb":"Arnaud is a very talentuous senior software engineer with robust and proven experience. Arnaud, as leader of a development squad, has successfully delivered a SaaS native platform from first steps of product ideation all the way to the SaaS platform in production. Thanks to Arnaud broad technical expertise and smart human touch, he has been able to lead, coach and grow multiple members of the squad (product manager, software engineer, DevOps). While being very demanding for himself, Arnaud is very pleasant toward his team members and fun to work with.","title":"60 Akeneo Shared Catalog","slug":"60-akeneo-shared-catalog","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/testimonials/60-akeneo-shared-catalog.html","relative_path":"_testimonials/60-akeneo-shared-catalog.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Nicolas Dupont","position":"Co-founder at Akeneo","homepage":true,"social_media_link":"https://www.linkedin.com/in/nicolasdupontakeneo","blurb":"Arnaud is a great software engineer. He led the design and delivery of valuable features and capabilities in our product offer. He introduced, advocated, and embodied many excellent practices like domain-driven design, event storming, and more. His passion for clean architecture and quality positively influenced our entire product development team..","title":"70 Akeneo Pim","slug":"70-akeneo-pim","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/testimonials/70-akeneo-pim.html","relative_path":"_testimonials/70-akeneo-pim.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Paweł Jędrzejewski","position":"Founder at Sylius","social_media_link":"https://www.linkedin.com/in/pjedrzejewski","blurb":"Arnaud has been a great Open Source collaborator and developer in the early days of Sylius. Skilled with BDD tools and modern development techniques. Highly recommended!","title":"80 Sylius","slug":"80-sylius","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/testimonials/80-sylius.html","relative_path":"_testimonials/80-sylius.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Boris Schapira","position":"Project manager","social_media_link":"https://www.linkedin.com/in/borisschapira","blurb":"J'ai travaillé pendant plusieurs années chez Clever Age en même temps qu'Arnaud. Nous avons souvent évolué sur des projets différents, mais avons eu quelques occasions de travailler ensemble, notamment sur des démarrages de projets Symfony où l'expertise d'Arnaud était très appréciée, puisqu'il était capable de comprendre les problématiques métiers que nous rencontrions et de nous proposer la juste couche d'abstraction pour y répondre, afin de partir sur une architecture logicielle dont la complexité était adaptée. Si l'occasion venait à ne présenter, je travaillerais à nouveau avec Arnaud avec plaisir, et confiance.","title":"90 Clever Age","slug":"90-clever-age","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/testimonials/90-clever-age.html","relative_path":"_testimonials/90-clever-age.md","permalink":null}],"services":[{"draft":false,"categories":[],"layout":"default","name":"Software architect","image":"build","blurb":"I can help your company to build solid software foundations and organize your teams to keep shipping more features faster. I like understanding business problems thanks to event storming or example mapping to find the right solution.","title":"01 Architect","slug":"01-architect","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/services/01-architect.html","relative_path":"_services/01-architect.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Technical coach","image":"contact","blurb":"I can join your team as a technical coach to help you grow your teams. I will mentor them on software crafting practices, focusing on high code quality, software testing, pair/ensemble programming, etc.","title":"02 Technical Coach","slug":"02-technical-coach","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/services/02-technical-coach.html","relative_path":"_services/02-technical-coach.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Lead software engineer","image":"desktop","blurb":"I can lead your team as a lead software engineer to craft robust and sustainable software: implement quality processes, design the application's architectural foundations, and guide the team to produce high-quality, tested code that met business requirements.","title":"03 Software Engineer","slug":"03-software-engineer","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/services/03-software-engineer.html","relative_path":"_services/03-software-engineer.md","permalink":null}],"experiences":[{"draft":false,"categories":[],"layout":"default","name":"Input Output (IOHK)","position":"Senior Software engineer","image":"/images/experiences/iogk.webp","tags":["Node","React"],"homepage":true,"link":"https://iohk.io/","blurb":"OHK is one of the world's foremost research and engineering companies in the field of blockchain infrastructure. IOHK is the company entrusted by the Cardano Foundation for the development of the Cardano blockchain.","title":"20 Iogk","slug":"20-iogk","ext":".md","excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/experiences/20-iogk.html","relative_path":"_experiences/20-iogk.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Sunday","position":"Senior Software engineer","image":"/images/experiences/sunday.webp","tags":["Java","Node","React"],"homepage":true,"link":"https://sundayapp.com","blurb":"Sunday is a payment system designed for restaurants, enabling millions of people to save time at the end of their meals through a QR code that can be scanned to settle the bill.","title":"30 Sunday","slug":"30-sunday","ext":".md","excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/experiences/30-sunday.html","relative_path":"_experiences/30-sunday.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Akeneo","position":"(Lead|Staff) Software engineer","image":"/images/experiences/akeneo.webp","tags":["PHP"],"homepage":true,"link":"https://www.akeneo.com","blurb":"Akeneo, a global leader in Product Experience Management (PXM), empowers businesses to enhance their growth opportunities through a consistent and compelling product experience across all sales channels.","title":"50 Akeneo Pim","slug":"50-akeneo-pim","ext":".md","excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/experiences/50-akeneo-pim.html","relative_path":"_experiences/50-akeneo-pim.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Groupe Sud Ouest Interactive","position":"Software engineer at Clever Age","image":"/images/experiences/sud-ouest.webp","tags":["PHP"],"homepage":true,"link":"https://www.groupesudouest.com/","blurb":"The Sud Ouest Group is an independent group specialized in information, communication, and services, whose media brands Sud Ouest, Charente libre and La république des Pyrénées are closely tied to their respective regions.\"","title":"60 Sud Ouest","slug":"60-sud-ouest","ext":".md","excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/experiences/60-sud-ouest.html","relative_path":"_experiences/60-sud-ouest.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Sylius","position":"Core team member","image":"/images/experiences/sylius.webp","tags":["PHP","Javascript"],"homepage":true,"link":"https://sylius.com","blurb":"As a member of the Sylius core team, I was involved in the development of Sylius. Sylius is an open-source e-commerce framework that simplifies the creation of online stores.","title":"70 Sylius","slug":"70-sylius","ext":".md","excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/experiences/70-sylius.html","relative_path":"_experiences/70-sylius.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Royal Canin - EasyPack","position":"Lead software engineer at Galilée","image":"/images/experiences/royal-canin.webp","tags":["PHP","Javascript"],"link":"https://www.royalcanin.com","blurb":"Easypack is the tool that enables the Packaging department to automate the packaging production process for the entire brand's product line. Based on a marketing production workflow management software (Dalim ES) Easypack is deployed worldwide for all stakeholders connected to Royal Canin","title":"80 Royal Canin","slug":"80-royal-canin","ext":".md","excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/experiences/80-royal-canin.html","relative_path":"_experiences/80-royal-canin.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Prisma media - CMonOeuvre.com","position":"Software engineer at Galilée","image":"/images/experiences/prisma-media.webp","tags":["PHP","Javascript"],"link":"https://www.prismamedia.com","blurb":"CmonOeuvre is a web-to-print store that enables online creation of canvases, postcards, and other formats using high-quality professional photos provided by magazines such as GEO, RMN, and National Geographic, which are part of the Prisma Media Group.","title":"90 Prisma Presse","slug":"90-prisma-presse","ext":".md","excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/experiences/90-prisma-presse.html","relative_path":"_experiences/90-prisma-presse.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Télécoms sans frontières","position":"Telecommunication technician","image":"/images/experiences/tsf.webp","tags":["PHP","Javascript"],"homepage":true,"link":"https://www.tsfi.org","blurb":"Télécoms Sans Frontières (TSF) is the leading emergency telecommunications NGO. During humanitarian crises, TSF enables affected individuals to reconnect with their loved ones. The organization also sets up emergency communication centers to assist local and international humanitarian actors.","title":"99 Tsf","slug":"99-tsf","ext":".md","excerpt":"\n","date":"2024-01-02 05:30:02 -0600","content":"\n","url":"/experiences/99-tsf.html","relative_path":"_experiences/99-tsf.md","permalink":null}],"data":{"newsletter":{"newsletter_title":"Newsletter: Be the first to know!","newsletter_description":"Subscribe to my newsletter for updates on my latest blog posts, tech releases, and exclusive content. Stay ahead in the coding game!","newsletter_identifier":"https://gmail.us13.list-manage.com/subscribe/post","newsletter_button":"Subscribe"},"social_links":{"social":[{"icon":"twitter","link":"https://twitter.com/arnolanglade","alt":"twitter"},{"icon":"linkedin","link":"https://www.linkedin.com/in/arnolanglade","alt":"linkedin"},{"icon":"bluesky","link":"https://bsky.app/profile/arnolanglade.bsky.social","alt":"bluesky"},{"icon":"mastodon","link":"https://mastodon.social/@arnolanglade","alt":"mastodon"},{"icon":"github","link":"https://github.com/arnolanglade","alt":"github"},{"icon":"youtube","link":"https://www.youtube.com/@arnolanglade","alt":"youtube"},{"icon":"rss","link":"/feed.xml","alt":"rss"}]},"navigation":{"menu__settings":{"menu__items":[{"title":"Home","url":"/"},{"title":"About me","submenu":[{"title":"About me","url":"/about/"},{"title":"My experiences","url":"/experiences/"},{"title":"My talks","url":"/talks/"}]},{"title":"Blog","url":"/blog/"},{"title":"MikadoApp","url":"/mikado-app/"},{"title":"Contact","url":"/contact/"}]}},"general_settings":{"name":"Langlade Arnaud","title":"Arnaud Langlade - Senior software engineer, software architect, and technical coach","description":"Arnaud Langlade - I am a software architect, and technical coach. I focus on understanding business needs to find the best solution. I love everything that ends with *DD such as DDD, BDD and TDD. These tools and all eXtreme Programming values help me to build robust and maintainable software. Last but not least, teamwork is essential: «alone we go faster, together we go further».","keywords":"arnaud langlade,langlade,freelancer,software engineer,architect,technical coach,software,oop,blog,talk,tdd,bdd,ddd,event storming,example mapping,arnolanglade","social_media_share_image":"/images/me-home.webp","disqus-identifier":"arnaudlanglade"},"footer":{"footer_menu__settings":{"menu__items":[{"title":"Home","url":"/"},{"title":"About me","url":"/about/"},{"title":"My experiences","url":"/experiences/"},{"title":"My talks","url":"/talks/"},{"title":"Blog","url":"/blog/"},{"title":"MikadoApp","url":"/mikado-app/"},{"title":"Contact","url":"/contact/"}]},"copyright_text_html":"

2021 © Langlade Arnaud. Template by CloudCannon.

"}},"baseurl":null,"title":"Arnaud Langlade"}} \ No newline at end of file +{"site":{"posts":[{"draft":false,"categories":[],"layout":"post","title":"Command and command handler design pattern","date":"2021-02-25 00:00:00 -0600","image":"command-handler/command-handler.webp","image_credit":"redaquamedia","tags":["command-bus","design-patterns"],"keywords":"design patterns,software,software architecture,command,command handler,command bus","description":"Discover the command design pattern in software development. Learn how commands represent user intents, handled by command handlers. Learn practical tips, examples, and insights for efficient command validation.","slug":"command-handler-patterns","ext":".md","excerpt":"

This pattern is really interesting; it can help you handle use cases. A command represents the user’s intent, while the command handler performs the actions needed to achieve the use case. Let’s dig a bit into these two concepts.

\n","content":"

This pattern is really interesting; it can help you handle use cases. A command represents the user’s intent, while the command handler performs the actions needed to achieve the use case. Let’s dig a bit into these two concepts.

\n\n

What is a command?

\n\n

A command is an object used to encapsulate all the information needed to perform an action. This design pattern is used to represent user intents, and the command is given to a command handler.

\n\n

A command is often designed as a Data Transfer Object (DTO), which is an object without any behavior (a data structure). The most important design rule to consider is that a command should be easily serializable. This way, it can be sent to a queue such as RabbitMQ or pub-sub to be handled asynchronously.

\n\n

What is a command handler?

\n\n

A command handler is just a callable that executes all the actions needed to fulfill a user’s intent. As you may understand, this design pattern is perfect for managing your business use cases.

\n\n

How does it work?

\n\n

\"Command

\n\n

This pattern has some rules. The first one is that a command can be handled by a single command handler because there is only a single way to handle a use case. The second rule is that a command handler should receive a valid command. Validating the command ensures that the user provides the correct data to prevent the handling from failing. It also helps to provide early feedback to the user about the data they provided.

\n\n

The command is only a DTO that carries data while the command handler is responsible to handle use cases.

\n\n

How to use it?

\n\n

Let’s consider a simple example: creating an account. Our business expert expects users to provide an email and a password to create an account for login purposes. We will create a command named CreateAnAccount and its handler, CreateAnAccountHandler.\nFirst, we need to create a command named CreateAnAccount to represent the user’s intent.

\n\n
final class CreateAnAccount\n{\n   public readonly string $username;\n   public readonly string $password;\n   \n   public function __construct(string $username, string $password) \n   {\n       $this->username = $username;\n       $this->password = $password;\n   }\n}\n
\n\n

Next, we need to create a command handler to manage this use case. The command handler can be a function or an invocable object. It should return nothing (void) to be handled asynchronously as we don’t know when it will be processed and can’t expect an instant result. Using the command data, we perform all actions needed to handle the use case. In our example, we create an account aggregate and pass it to the account repository.

\n\n
final class CreateAnAccountHandler\n{\n   private Accounts $accounts;\n\n   public function __construct(Accounts $accounts)\n   {\n       $this->accounts = $accounts;\n   }\n\n   public function __invoke(CreateAnAccount $createAnAccount): void\n   {\n       $account = Account::create(\n           $createAnAccount->username(),\n           $createAnAccount->password()\n       );\n\n       $this->accounts->add($account);\n   }\n}\n
\n\n

Finally, let’s stick those pieces of code together in a controller (this example is made with a Symfony Framework). This controller receives JSON-encoded data to create a command, which is then validated and passed to the handler

\n\n
final class CreateAnAccount\n{\n    // ...\n    \n    public function __invoke(Request $request): Response\n    {\n        $command = $this->serializer->deserialize(\n            $request->getContent(),\n            CreateAnAccount::class,\n            'json'\n        );\n        \n        $violations = $this->validator->validate($command);\n        \n        if (0 < $violations->count()) {\n           throw new BadRequestHttpException(/*json encoded violation*/);\n        }\n        \n        ($this->createAnAccountHandler)($command);\n        \n        return new JsonResponse(null, Response::HTTP_CREATED);\n    }\n}\n\n
\n

Tip: : To simplify command creation, you can use libraries such as the Symfony Serializer component. It eases object creation from a set of data (e.g., JSON), making the process easier and faster.

\n\n
$createAccount = $serializer->deserialize(\n    '{“username”:”arnaud”, “password”:“password”}',\n    CreateAnAccount::class,\n    'json'\n);\n
\n\n

Tip: To avoid reinventing the wheel, you can leverage libraries like the Symfony Validator component to validate the command.

\n\n
$violation = $validator->validate($createAccount);\n
\n\n

I’ve written a dedicated blog post explaining how to validate a command:

\n\n
\n \n \n \"How\n \n \n How to validate a command?\n \n \n
\n\n

How to simplify that?

\n\n

To simplify this controller, consider using a command bus, which is responsible for finding the right handler for a given command. For more information about this pattern, I’ve written a dedicated blog post explaining how it works:

\n\n
\n \n \n \"The\n \n \n The command bus design pattern\n \n \n
\n\n

The following example is built with Symfony Messenger.

\n\n
public function __invoke(Request $request): Response\n{\n    $command = $this->serializer->deserialize(\n        $request->getContent(),\n        CreateAnAccount::class,\n        'json'\n    );\n    \n    $this->commandBus->handle($command);\n    \n    return new JsonResponse(null, Response::HTTP_CREATED);\n}\n
\n\n

Where is the command validation in this example? Command buses are often built with middleware, making them highly configurable. To ensure that all commands are valid before passing them to a command handler, we need to add middleware to the command bus for command validation.

\n\n
class ValidationMiddleware implements MiddlewareInterface\n{\n    // …\n\n    public function handle(Envelope $envelope, StackInterface $stack): Envelope\n    {\n        $message = $envelope->getMessage();        \n        $violations = $this->validator->validate($message, null, $groups);\n        if (\\count($violations)) {\n            throw new ValidationFailedException($message, $violations);\n        }\n\n        return $stack->next()->handle($envelope, $stack);\n    }\n}\n
\n\n

Tip: Take a look at this blog post if you need to manage user permissions. Adding a middleware to the command bus can enhance the security of your application:

\n\n
\n \n \n \"How\n \n \n How to handle user permissions through command bus middleware\n \n \n
\n\n

My last thoughts

\n\n

In many applications,I have seen a lot of classes named managers or services (e.g., AccountService, AccountManager) that gather all use case management into a single class. While this approach might be effective initially as development progresses, these classes tend to grow larger and larger, and become a “god object.” This makes maintenance challenging, reduces readability, and can quickly turn into a dump. I believe this pattern can address these issues.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/command-handler-patterns.html","relative_path":"_posts/2021-02-25-command-handler-patterns.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"How to validate a command?","description":"Domain validation ensures your aggregate cannot be built in an invalid state but that is not enough to give good feedback to the end users. Validating commands is the best to prevent their processing if data given by users are wrong.","date":"2021-03-04 00:00:00 -0600","image":"data-validation.webp","image_credit":"heapdump","tags":["command-bus","design-patterns"],"keywords":"oop,design patterns,software,software architecture,command,command handler,command bus,data validation,domain validation","slug":"how-to-validate-a-command","ext":".md","excerpt":"

In my previous blog post, I talked about command and command handler design patterns. I got several questions about data validation and how to give feedback to users. We are going to talk about several kinds of data validation in this blog post. We will start with domain validation, this validation ensures we can build our domain objects in a good state depending on business rules. Then, we will talk about command validation and how we can use it to give feedback to users when they submit data to the application.

\n","content":"

In my previous blog post, I talked about command and command handler design patterns. I got several questions about data validation and how to give feedback to users. We are going to talk about several kinds of data validation in this blog post. We will start with domain validation, this validation ensures we can build our domain objects in a good state depending on business rules. Then, we will talk about command validation and how we can use it to give feedback to users when they submit data to the application.

\n\n

Let’s take the same example I used in my previous blog post: an account creation. To create an account, my business expert expects that I provide a username and a password. The username should have at least three characters and should be unique. The password should have at least eight characters, an uppercase letter, a lowercase letter, and a number.

\n\n

Domain validation

\n\n

How to make sure the domain objects follow the business rules? Value object will help us to achieve that. I strongly recommend you to wrap all primitives into value objects. It is a good way to introduce new types in your codebase, make it clearer and business-focused. And don’t forget, value objects cannot be built in a wrong state.

\n\n
final class Username\n{\n    private string $username;\n\n    public function __construct(string $username)\n    {\n        if (\\strlen($username) < 3) {\n            throw new \\InvalidArgumentException('The username is too short, it should contain at least 3 characters');\n        }\n\n        $this->username = $username;\n    }\n}\n\nfinal class Password\n{\n    private string $password;\n\n    public function __construct(string $password)\n    {\n        if (1 !== \\preg_match('#(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,}#', $password)) {\n            throw new \\InvalidArgumentException(\n                'The password must contain at least 8 characters, an uppercase letter, lowercase letter and a number'\n            );\n        }\n\n        $this->password = $password;\n    }\n}\n
\n\n

Then we are able to modelize the Account aggregate using the Username and Password value objects.

\n\n
final class Account\n{\n    private Username $username;\n    private Password $password;\n\n    public function __construct(\n        Username $username,\n        Password $password\n    ) {\n        $this->username = $username;\n        $this->password = $password;\n    }\n}\n
\n\n

Now, we are sure that as developers we cannot instantiate the Account aggregate in a wrong state. In the next section, we are going to see how to use the domain objects to give users feedback about their data.

\n\n

Command validation

\n\n

As I explained in my previous blog post, an account creation is represented by a CreateAnAccount command with two properties: the username and the password. We need to validate them to create the account aggregate without any errors and tell users if they provided valid data to perform this action. The command validation will be done by the Symfony validator. Don’t hesitate to have a look at the validator documentation if you are not familiar with it.

\n\n

First, we will use the callback constraint to make sure the username and password follow the patterns given by the business expert. Thanks to annotation we will configure the validator to call a static method to validate command properties. I will call them “static validators“ in this blog post.

\n\n
final class CreateAnAccount\n{\n    /** @Assert\\Callback({\"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\UsernameShouldBeValid\", \"validate\"}) */\n    private string $username;\n    /** @Assert\\Callback({\"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\PasswordShouldBeValid\", \"validate\"}) */\n    private string $password;\n}\n
\n\n

Then, it is time to create those static validators. We just need to instantiate our value objects and check if they throw exceptions to catch them and turn them into violations.

\n\n
final class UsernameShouldBeValid\n{\n    public static function validate(string $username, ExecutionContextInterface $context): void\n    {\n        try {\n            new Username($username);\n        } catch (\\InvalidArgumentException $e) {\n            $context->buildViolation('account.usernameShouldBeValid')\n                ->addViolation();\n        }\n    }\n}\n\nfinal class PasswordShouldBeValid\n{\n    public static function validate(string $password, ExecutionContextInterface $context): void\n    {\n        try {\n            new Password($password);\n        } catch (\\InvalidArgumentException $e) {\n            $context->buildViolation('account.passwordShouldBeValid')\n                ->addViolation();\n        }\n    }\n}\n
\n\n

For more complex use cases you can call any methods on value objects, but you need to keep in mind that you cannot inject services into those static validators.

\n\n
public static function validate(BookFlightTicket $flightTicket, ExecutionContextInterface $context): void\n{\n    if (\n    !Date::fromString($flightTicket>departureDate)->laterThan(\n        Date::fromString($flightTicket>arrivalDate)\n    )\n    ) {\n        $context->buildViolation('flightTicket.dateShouldBeValid')\n            ->addViolation();\n    }\n}\n
\n\n

The first step is done! Thanks to those static validators, we apply domain validation on command properties to ensure we can instantiate domain objects. But, domain validation only works with a single account because the account aggregate only represents the account of a single user. For instance, an account cannot validate if a username is unique because it needs to be aware of the rest of the created account.

\n\n

To check if a username is used by another user we will need to ask the repository if an account already exists with the given username. That’s why we will need to create a custom validation constraint because those constraints are declared as services, and they can depend on other application services.

\n\n
/** @Annotation */\nfinal class UsernameShouldBeUnique extends Constraint\n{\n}\n\nfinal class UsernameShouldBeUniqueValidator extends ConstraintValidator\n{\n    private Accounts $accounts;\n\n    public function __construct(Accounts $accounts)\n    {\n        $this->accounts = $accounts;\n    }\n\n    public function validate($username, Constraint $constraint): void\n    {\n        if (!$constraint instanceof UsernameShouldBeUnique) {\n            throw new UnexpectedTypeException($constraint, UsernameShouldBeUnique::class);\n        }\n\n        try {\n            $this->accounts->getByUsername(new Username($username));\n\n            // an exception is thrown if an account does not exist so we don’t add violation\n            $this->context->buildViolation('account.usernameShouldBeUnique')\n                ->addViolation();\n        } catch (UnknownAccount $exception) {\n        }\n    }\n}\n
\n\n

Finally, we need to configure the validator to apply this new constraint to the username property.

\n\n
/**\n * @Assert\\GroupSequence({\"CreateAnAccount\", \"Business\"})\n */\nfinal class CreateAnAccount\n{\n    /** \n     * @Assert\\Callback({\"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\UsernameShouldBeValid\", \"validate\"})\n     * @Domain\\Account\\UseCase\\ValidationRule\\UsernameShouldBeUnique(groups={\"Business\"})\n     */\n    private string $username;\n    \n    // ...\n}\n
\n\n

Caution: we need to apply static validators before applying custom constraints because we need to be sure we can instantiate all domain objects without raising any error. For instance, the instantiation of Username in UsernameShouldBeUniqueValidator must not raise any error because the goal of this constraint is not to check if the username contains at least three characters but if the username is already used. It can be done with GroupSequence. This validator feature allows adding groups to constraints and defining the validation constraint execution order.

\n\n

Now, this is the end of the story! If commands are invalid, we just need to serialize violations, give them to your front application, and print errors to users.

\n\n

Last word

\n\n

This might not be the only way to validate data but it worked on my previous project. Even if I use a service to validate my command I try to use as many domain objects as possible to avoid reinventing the wheel. I hope it answers Baptiste Langlade’s question on Twitter. If you wonder, Baptiste is not my brother ;).

\n\n

Thanks to my proofreaders @LaureBrosseau and @jjanvier_.

\n","url":"/how-to-validate-a-command.html","relative_path":"_posts/2021-03-04-how-to-validate-a-command.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"OOP: how to build an object","description":"Object-oriented programming: primary and secondary constructors. The primary constructor is the default way to build an object with all its dependencies. The secondary constructors provide other ways to build objects depending on use cases.","date":"2021-03-10 00:00:00 -0600","image":"build-object.webp","image_credit":"danist07","tags":["OOP","design-patterns"],"keywords":"software,oop,design patterns,primary constructor, secondary constructor","slug":"oop-how-to-build-an-object","ext":".md","excerpt":"

In this new blog post, I want to talk about object building more specifically about primary and secondary constructors. The primary constructor is the default way to build an object with all its dependencies. The secondary constructors provide other ways to build objects depending on use cases.

\n","content":"

In this new blog post, I want to talk about object building more specifically about primary and secondary constructors. The primary constructor is the default way to build an object with all its dependencies. The secondary constructors provide other ways to build objects depending on use cases.

\n\n

Note: I did not work on a PHP8 project yet so that is why I won’t talk about named arguments feature.

\n\n

Primary constructor

\n\n

The PHP language provides a single way to build an object thanks to the __construct() method. I use this method to define the primary constructor of my classes to encapsulate all their dependencies.

\n\n
final class Map\n{\n   private MapName $name;\n   private CartographersAllowedToEditMap $cartographersAllowedToEditMap;\n   /** @var Marker[] */\n   private array $markers;\n\n   public function __construct(\n       MapName $name,\n       CartographersAllowedToEditMap $cartographersAllowedToEditMap,\n       Marker ...$markers\n   ) {  \n       $this->name = $name;\n       $this->cartographersAllowedToEditMap = $cartographersAllowedToEditMap;\n       $this->markers = $markers;\n   }\n}\n
\n\n

Tip: If your objects encapsulate a collection of a specific type (like the Marker in this example), you can use variadic arguments to automatically validate each item of this collection. Here, we don’t need to iterate the collection to check the type of its items, the language does it for us.

\n\n

Secondary constructor

\n\n

The PHP language does not ease the data encapsulation because it only provides a single way to build objects but we should be able to define several constructors depending on all our use cases. How to solve this problem? Named constructors! Named constructors are static factories, in other words static methods that build the object itself.\nLet’s take an example with the map object. How to initialize a map without any marker?

\n\n
final class Map\n{\n    public static function initialize(\n       string $name,\n       array $cartographerAllowedToEditMap\n    ): self {\n       return new self(\n           new MapName($name),\n           new CartographersAllowedToEditMap($cartographerAllowedToEditMap),\n       );\n    }\n}\n
\n\n

Here, we added a named constructor called initialize to the Map class. It uses the primary constructor to build the map object with an empty collection of Marker objects.

\n\n

Tip: Some developers change the visibility of the primary constructor method to private but I am not a big fan of that. I use object comparison to test objects to avoid the usage of getters. I like keeping my primary constructor public because it allows me to build objects in any state to compare them to other ones.

\n\n
function it adds a marker on the map()\n{\n   $actualMap = Map::initialize(\n       'Bons plans sur Nantes',\n       ['Arnaud']\n   );\n\n   $actualMap->addMarker('Bubar');\n\n   $expectedMap = new Map(\n       new MapName('Bons plans sur Nantes'),\n       new CartographersAllowedToEditMap(['Arnaud']),\n       new Marker('Bubar')\n   );\n   \n   assertSame($actualMap, $expectedMap);\n}\n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/oop-how-to-build-an-object.html","relative_path":"_posts/2021-03-10-oop-how-to-build-an-object.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Persisting entities without ORM","description":"The repository pattern provides a good abstraction to manage object persistence. Even if a lot of projects use an ORM, persisting entities do not necessarily require it.","date":"2021-03-23 00:00:00 -0500","image":"persisting-entity-without-orm.webp","image_credit":"tofi","tags":["OOP","design-patterns"],"keywords":"software,oop,repository,design patterns,orm,persistence,sql,database","slug":"persisting-entities-without-orm","ext":".md","excerpt":"

Today, I will talk about persisting entities without ORM. First, I will introduce the repository pattern because it provides a good abstraction to manage object persistence. Then, we will see what are the impacts on the entity design.

\n","content":"

Today, I will talk about persisting entities without ORM. First, I will introduce the repository pattern because it provides a good abstraction to manage object persistence. Then, we will see what are the impacts on the entity design.

\n\n

Repository pattern

\n\n

The repository design pattern can be used to manage entity persistence and retrieval. It behaves like a collection of objects and hides the complexity of their storage. It ensures a clean separation between the domain model (the entity) and the data model (SQL tables). The following example shows a basic repository interface. Thanks to the Maps interface we will be able to add and retrieve Map entities, no matter their storage.

\n\n
interface Maps\n{\n   /**\n    * @throws \\LogicException\n    * @throws UnknownMap\n    */\n   public function get(MapId $mapId): Map;\n\n   /**\n    * @throws \\LogicException\n    */\n   public function add(Map $map): void;\n}\n
\n\n

Caution: All Maps implementations should be tested with the same test because we need to be sure they behave the same way. It ensures the application works no matter the chosen implementation.

\n\n

Let’s see how we can implement this interface with PostgreSQL for instance. The get method is only responsible to get information from the database to build the map entity whereas the add method extracts the entity information to store them in the database.

\n\n
class PostgreSqlMaps implements Maps\n{\n   private Connection $connection;\n\n   public function __construct(Connection $connection)\n   {\n       $this->connection = $connection;\n   }\n\n   public function get(MapId $mapId): Map\n   {\n       $sql = <<<SQL\n           SELECT map.\"mapId\", map.name\n           FROM map\n           WHERE map.\"mapId\" = :mapId\n       SQL;\n\n       $statement = $this->executeQuery($sql, ['mapId' => (string) $mapId]);\n\n       if (false === $map = $statement->fetchAssociative()) {\n           throw UnknownMap::withId($mapId);\n       }\n\n       return new Map($map['mapId'], $map['name']);\n   }\n\n   public function add(Map $map): void\n   {\n       $sql = <<<SQL\n           INSERT INTO map (\"mapId\", name)\n           VALUES (:mapId, :name)\n           ON CONFLICT (\"mapId\")\n           DO UPDATE SET name = :name;\n       SQL;\n\n       $this->executeQuery($sql, ['mapId' => $map, 'name' => $map->name()]);\n   }\n\n   private function executeQuery(string $sql, array $data): Result\n   {\n       // Execute query or throw logic exceptions if something goes wrong.\n   }\n}\n
\n\n

Tip: Thanks to the clause ON CONFLICT we can easily insert or update data with a single query.

\n\n

Entity design impacts

\n\n

Now we are able to persist and retrieve our map entity. Let’s study the impact on entity design.

\n\n

Let’s start with persistence. In the previous example, I used getters to get its properties but I am not a fan of the getter to be honest! Getters break data encapsulation because they expose object implementation details. They don’t follow the Tell don’t ask principle because we should not ask about the object state to do something, we should tell the object to do something for us. I like adding a toState method that is responsible to turn the entity into an associative array.

\n\n
final class Map\n{\n   public function toState(): array\n   {\n      return [\n          'mapId' => (string) $this->mapId,\n          'name' => (string) $this->name,\n      ];\n   }\n}\n
\n\n

So I just need to call the toState method instead of getters, this method returns data expected by the executeQuery method.

\n\n
class PostgreSqlMaps implements Maps\n{\n   // ...\n   public function add(Map $map): void\n   {\n       // ...\n       $this->executeQuery($sql, $map->toState());\n   }\n   // ...\n}\n
\n\n

Let’s continue with retrieval. If we have a look at the Mapconstructor method we can see that a MapInitialized event is recorded there. Houston, we have a problem! When we build an entity from its state (data stored somewhere) we don’t want to record any event because nothing happens. So, we need to find a solution to avoid recording those events.

\n\n
public function __construct(\n   MapId $mapId,\n   MapName $name\n) {\n   $this->mapId = $mapId;\n   $this->name = $name;\n\n   $this->recordEvent(new MapInitialized(\n       $mapId,\n       $name\n   ));\n}\n
\n\n

I like adding a named constructor called fromState to the entity. This constructor is responsible for building the aggregate from the state. Moreover, named constructors are explicit and give developers information about when to use them. In the following example, after calling the primary constructor we call the eraseRecordedEvents method to reset events before returning the object in the right state.

\n\n
public static function fromState(array $state): self\n{\n   $map = new self(\n       new MapId($state['mapId']),\n       new MapName($state['name'])\n   );\n\n   $map->eraseRecordedEvents();\n\n   return $map;\n}\n
\n\n

So, the only change in the repository is to build the Map entity from the named constructor.

\n\n
class PostgreSqlMaps implements Maps\n{\n\n   public function get(MapId $mapId): Map\n   {\n       // ...\n\n       return Map::fromState($map);\n   }\n}\n
\n\n

Last word

\n\n

I did a presentation about the repository design pattern at the Forum PHP in 2018. A video is only available in French here but the slides are in English here (press “s” to display English notes). Even if this presentation was made for Doctrine ORM it gives a lot of information about the pattern.

\n\n

Note: In this talk I spoke about generating the entity identity by the repository. To be honest, I stopped doing that because generating it from controllers is easier and makes the repository design simpler.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/persisting-entities-without-orm.html","relative_path":"_posts/2021-03-23-persisting-entities-without-orm.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"How did I organize my last Symfony projects?","description":"Return of experience: In this blog post, I will explain how I organized my last Symfony projects. They are mainly inspired by Hexagonal and CQRS architecture.","date":"2021-03-30 00:00:00 -0500","image":"project-symfony-organization.webp","image_credit":"alexkixa","tags":["software-architecture","symfony"],"keywords":"software,software architecture,symfony,cqrs,php,hexagonal architecture,port adapters,rex","slug":"how-did-I-organize-my-last-symfony-project","ext":".md","excerpt":"

In this blog post, I will explain how I organized my last Symfony projects. They are mainly inspired by Hexagonal and CQRS architecture. Keep in mind that I did not try to implement these architectures by the book, I only took some concepts that helped me to have a simple and clear codebase organization.

\n","content":"

In this blog post, I will explain how I organized my last Symfony projects. They are mainly inspired by Hexagonal and CQRS architecture. Keep in mind that I did not try to implement these architectures by the book, I only took some concepts that helped me to have a simple and clear codebase organization.

\n\n

If we have a look at the project’s root, nothing special happens, I kept all folders and files created during Symfony installation.

\n\n
tree . -L 1                       \n├── bin\n├── composer.json\n├── composer.lock\n├── config\n├── features\n├── public\n├── src\n├── symfony.lock\n├── tests\n├── translations\n├── var\n└── vendor\n
\n\n

In the next sections, we are going to see how I organized the src folder.

\n\n

Hexagonal architecture

\n\n

The foundation of the hexagonal architecture is the explicit separation between the domain (inside) and the infrastructure (outside). All dependencies are going from Infrastructure to the Domain.

\n\n

The domain is the part of the application that contains your business logic. It must reflect as much as possible the problem your application has to solve. This part of the application must not use IO, the infrastructure contains them all. For instance, IO are side effects like network calls, database queries, filesystem operations, actual timestamps or randomness..

\n\n

Based on that information my first decision was to split src into two areas: Domain and Infrastructure.

\n\n
tree src/Domain/ -L 1\napi/src/Domain/\n├── Domain\n└── Infrastructure\n
\n\n

Coupling rules:

\n\n\n

I am not a big fan of the onion architecture because I want to keep my projects as simple as possible. Having a lot of layers can be really hard to maintain because you need to align the whole team on the coupling rules. Agreeing with yourself is not easy, so getting several people to agree may be really hard. Here, we only have a single rule.

\n\n

Sometimes, I needed to write libraries because I could not find any open source libraries that match my expectations. To avoid coding in the vendor directory, I introduced a third area called Libraries (this new area is optional). Those libraries may be used in the domain and the infrastructure but their usage should not break the coupling rules that are defined for those areas.

\n\n
tree src/Domain/ -L 1\napi/src/Domain/\n├── Domain\n├── Infrastructure\n└── Librairies\n
\n\n

Coupling rules:

\n\n\n

Finally, I created a “sub” area called Application in the infrastructure that contains all pieces of code needed to have an application up and running: framework code (Symfony kernel, framework customizations), data fixtures, and migration.

\n\n
tree src/Infrastructure/Application -L 1 \napi/src/Infrastructure/Application\n├── Exception \n├── Fixture\n├── Kernel.php\n├── Migrations\n├── Security\n└── Kernel\n
\n

In this example, Exception and Security folders contain framework customizations.

\n\n

Business first

\n\n

A really important thing for me is to drive codebase organization by business concepts. I don’t want to name folders and classes with technical patterns like factory or repository for instance. Non-tech people should be able to understand what a class does thanks to its name.

\n\n

Domain

\n\n
tree src/Domain -L 1\napi/src/Domain\n├── Cartographer\n└── Map\n
\n\n

Because I did not use any technical words to name folders we can easily imagine the project is about making maps. Now, let’s have a look inside the Map directory:

\n\n
tree src/Domain/Map -L 1\n├── CartographersAllowedToEditMap.php   // Value object\n├── Description.php   // Value object\n├── MapCreated.php   // Event \n├── MapId.php   // Value object\n├── MapName.php   // Value object\n├── Map.php   // Root aggregate\n├── Maps.php   // Repository interface\n├── Marker    // All classes to design Marker entity\n├── MarkerAddedToMap.php   // Event\n├── MarkerDeletedFromMap.php   // Event\n├── MarkerEditedOnMap.php   // Event\n├── UnknownMap.php   // Exception\n└── UseCase    // Use cases orchestration\n
\n\n

In this folder, we have all the pieces of code needed to design the Map aggregate. As you can see, I did not organize it by design patterns like ValueObject, Event or Exception.

\n\n

As you might have understood the Map entity has a one-to-many relationship with the Marker entity. All classes needed to modelize this entity are in the Marker folder and they are organized the same way as the Map directory.

\n\n

The UseCase folder gathers all pieces of code needed to orchestrate use cases like command, their handler and business validation.

\n\n

Tip: I don’t suffix repositories by ‘Repository’ but I try to use a business concept to name them like ProductCatalog for a Product aggregate. If I can find a business concept to name it I use the plural of the aggregate because a repository is a collection of objects.

\n\n

Infrastructure

\n\n

I organize the root of the Infrastructure folder the same way as the Domain one.

\n\n
tree src/Infrastructure -L 1            \napi/src/Infrastructure\n├── Application\n├── Cartographer\n└── Map\n
\n\n

Now, let’s have a look at the Map directory:

\n\n
tree src/Infrastructure/Map -L 1 \napi/src/Infrastructure/Map\n├── Storage\n└── UserInterface\n        └── Web\n        └── Cli\n
\n\n

The Storage namespace gathers everything related to data storage like repositories, queries. The UserInterface namespace gathers everything related to ways to interact with the application like the WEB API (controllers) called by the front application or CLI (Symfony commands).

\n\n

CQRS

\n\n

CQRS is the acronym for Command Query Responsibility Segregation. The main idea of CQRS is that you can use different models for writing (command) or reading (query) information. I like the idea of having two small and simple models dedicated to a precise purpose: reading or writing instead of having one big model. It can prevent your aggregate from becoming a god object because as things progress you can have many write and read use cases to handle.

\n\n

From this pattern, I decided to split the domain into two areas, the first one: Command and the second one: Query. It allows me to design a model with the same name for these reading or writing purposes.

\n\n
tree src/Domain/ -L 2\napi/src/Domain/\n├── Command\n│   ├── Cartographer\n│   └── Map\n└── Query\n    ├── Cartographer\n    └── Map\n
\n\n

Coupling rule:

\n\n\n

Note: I did not make major changes in the infrastructure, the only change I made is to split the storage into two areas like the domain.

\n\n

Caution: For those projects, I did not make any projections because my database schema remained simple so I did not need them. I only decided to split my models because my codebase was simple and clearer this way.

\n\n

Last word

\n

I tried for the last few years to find the perfect architecture but it does not exist. I just tried to use some architectural concepts that make me and my teammates comfortable to work on a daily basis. This project organization has been used for two projects that are in production. One of these projects is a side project I made for fun to create maps without Google Maps. The second was a professional project, real people use it on a daily basis.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/how-did-I-organize-my-last-symfony-project.html","relative_path":"_posts/2021-03-30-how-did-I-organize-my-last-symfony-project.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Why you should not expose objects' state to test them","description":"Exposing the object's state to test them is not a good idea. Comparing object instances is better because it avoids breaking encapsulation and it does not have any impact on their design.","date":"2021-04-13 00:00:00 -0500","image":"test-comparison.webp","image_credit":"jdent","tags":["testing","OOP"],"keywords":"software,testing,unit test,oop,encapsulation,ask don't tell","slug":"you-should-not-expose-objects-state-to-test-them","ext":".md","excerpt":"

To introduce this topic, let’s have a look at the PHP documentation to understand how object comparison works using the comparison and identity operators.

\n","content":"

To introduce this topic, let’s have a look at the PHP documentation to understand how object comparison works using the comparison and identity operators.

\n\n
\n

When using the comparison operator (==), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values (values are compared with ==), and are instances of the same class.

\n\n

When using the identity operator (===), object variables are identical if and only if they refer to the same instance of the same class.

\n\n

PHP documentation

\n
\n\n
$object = new Object();\n$otherObject = new Object();\n\n$object == $otherObject // true\n$object === $otherObject // false \n
\n\n

I add an equals method to objects to handle object comparison. The purpose of this method is to compare an object state with another one. In the following example, I use the comparison operator (==) because I want to check if the objects have the same state no matter their references.

\n\n
final class Email\n{\n   private string $email;\n\n   public function __construct(string $email)\n   {\n       $this->email = $email;\n   }\n\n   public function equals(Email $email): bool\n   {\n       return $this == $email;\n   }\n}\n
\n\n

There is another way to compare object state. Do you know that instances of the same class can access each other’s private members?

\n\n
final class Email\n{\n   public function equals(Email $email): bool\n   {\n       return $this->email === $email->email;\n   }\n}\n
\n\n

Tip: This is really useful to compare Doctrine entities that have persistent collections. The error Error: Nesting level too deep - recursive dependency? is raised when we compare entities using the comparison operator (==). You should have a look at this blog post to understand why this error occured. Accessing private attributes let you use the identity operator (===) to prevent this error.

\n\n

By the way, entities are a bit special because an entity is an object that has an identity. It means that if we want to compare them we should compare their identities instead of their states.

\n\n
final class Map\n{\n   private MapId $mapId;\n\n   public function equals(MapId $mapId): bool\n   {\n       return $this->mapId->equals($mapId);\n   }\n}\n
\n\n

I add an extra method called hasSameState to entities to compare their states because entity state comparison remains really useful for testing.

\n\n
final class Map\n{\n   public function hasSameState(Map $map): bool\n   {\n       return $this == $map;\n   }\n}\n
\n\n

For a long time, I used getters for testing purposes. I only knew this way to ensure objects had the right state.

\n\n
$map = new Map('Best places at Nantes');\n\n$map->rename('Best places at Bordeaux');\n\n$map->getName()->shouldReturn('Best places at Bordeaux') ;\n
\n\n

It was a mistake because exposing objects’ state breaks data encapsulation. We should not know how objects work internally, we should only use their public API (public methods) to interact with them. But, if we need to build the Map object with something else than a string, this assertion will no longer be true. That will break all application tests and parts that use this getter! That’s not great! Object comparison I described previously helps to get rid of getters.

\n\n
$map = new Map('Best places at Nantes');\n\n$map->rename('Best places at Bordeaux');\n\n$map->hasSameState(new Map('Best places at Bordeaux'))->shouldReturn(true);\n
\n\n

Now, the Map object is better designed. Its state is not exposed anymore which improves data encapsulation. It follows the “Tell don’t ask” principle because I don’t need to extract its internal state to test it. I only need to use its public API to check if it meets the business exceptions.

\n\n

Tip: If you don’t want or if you can’t add a method to your objects that handles comparison you can still compare their instances to avoid adding getters.

\n\n
Assert::equals($map, new Map('Best places at Bordeaux'));\n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/you-should-not-expose-objects-state-to-test-them.html","relative_path":"_posts/2021-04-15-you-should-not-expose-objects-state-to-test-them.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Why unit testing can be hard?","description":"Testing can be really difficult for beginners. The main reason is that your code probably uses IO. This blog post gives you tips about improving your code design to ease testing.","date":"2021-05-03 00:00:00 -0500","image":"why-unit-testing-can-be-hard.webp","image_credit":"craftedbygc","tags":["testing","OOP"],"keywords":"software,testing,unit test,coupling,io,dependency inversion","slug":"why-unit-testing-can-be-hard","ext":".md","excerpt":"
\n

Unit tests are typically automated tests written and run by software developers to ensure that a section of an application (known as the “unit”) meets its design and behaves as intended

\n\n

Wikipedia

\n
\n","content":"
\n

Unit tests are typically automated tests written and run by software developers to ensure that a section of an application (known as the “unit”) meets its design and behaves as intended

\n\n

Wikipedia

\n
\n\n

I remember when I started to test my code it was really hard! It was mainly because I misunderstood some basics like what testing was about and the need of well-designed code. Unit tests ensure your code works as expected, but we often forget that unit testing is also the simplest way to have quick feedback during development phase.

\n\n

In this blog post, I will share what I learned to easily unit test my codebases.

\n\n

Test your public methods

\n\n

Objects should be seen as black boxes. Public methods are the only way to interact with objects, while private and protected methods are implementation details. We should not pay attention to how objects work internally. That’s why we don’t test private and protected methods. If you need to test them, that’s a design smell! Your objects might do too many things and they probably do not respect the Single Responsibility Principle.

\n\n
\n

The single-responsibility principle (SRP) is a computer-programming principle that states that every class in a computer program should have responsibility over a single part of that program’s functionality, which it should encapsulate.

\n\n

Wikipedia

\n
\n\n

Actually, it is better to have several small objects solving simple problems instead of having god objects that are doing everything the wrong way. If your objects become too big, split them into smaller ones because they are easier to maintain and to test.

\n\n

Do not unit test code that uses IOs

\n\n
\n

Input/output (I/O, or informally io or IO) is the communication between an information processing system, such as a computer, and the outside world, possibly a human or another information processing system.

\n\n

Wikipedia

\n
\n\n

For example, IO are side effects like: network calls, database queries, filesystem operations, actual timestamps or randomness.

\n\n

Do not deal with the outside

\n\n

The code covered by unit tests should not depend on the outside world like databases, external services and so on. Unit tests should not require any application setup, they have to remain as simple as possible. Their goal is to give you quick feedback by checking that a small piece of code (a unit) matches a business expectation. If you want to be sure that all application parts are well integrated with the outside world, you have to use an integration test.

\n\n

The following example shows a piece of code that depends on the external service. Here, we can’t build the Map object without a working database.

\n\n
final class HandleMarkerAddition\n{\n   private Connection $connection;\n\n   public function __construct(Connection $connection)\n   {\n       $this->connection = $connection;\n   }\n\n   public function __invoke(AddMarkerToMap $command): void\n   {\n       $mapState = $this->connection->executeQuery('SELECT ... FROM ...', [$command->mapId()]);\n\n       $map = Map::fromState($mapState);\n       $map->addMarker($command->name(), $command->location());\n\n       $this->connection->executeQuery('INSERT INTO ...', $map->toState()]);\n   }\n}\n
\n\n

The goal of this piece of code is to add a marker to a Map object, no matter how the object is stored. Tests that cover this class should focus on business use cases instead of technical details. A solution would be to use a repository design pattern to hide the map storage logic. The class will better follow the Single Responsable Principle because it will only handle the marker addition use case whereas the map repository will be in charge of storing data.

\n\n
final class HandleMarkerAddition\n{\n   private Maps $maps;\n\n   public function __construct(Maps $maps)\n   {\n       $this->maps = $maps;\n   }\n\n   public function __invoke(AddMarkerToMap $command): void\n   {\n       $map = $this->maps->get($command->mapId());\n       $map->addMarker($command->name(), $command->location());\n\n       $this->maps->add($map);\n   }\n}\n
\n\n

With this new design, it is easier to test this class. Thanks to the Maps interface , we are able to simply create test doubles for the map repository.

\n\n
// `PostgreSQLMaps` is the implementation used by default on the production\n$maps = new PostgreSQLMaps();\n(new HandleMarkerAddition($postgreSQLMaps)($command);\n\n// `InMemoryMaps` is an implementation that keeps map objects in memory for testing \n$maps = new InMemoryMaps();\n(new HandleMarkerAddition($inMemoryMaps)($command);\n\n// In both cases we can retrieve the Map object from the repository to check the map has the new marker.\n$map = $maps->get($command->mapId());\n$map->hasSameState(new Map('Best place', new Marker(/* … */))) // should return true;\n\n
\n\n

Do not deal with randomness

\n\n

Randomness makes your code unpredictable. To simply test a piece of code you should be able to predict its result. To ease unit testing your code should avoid using randomness as much as possible.

\n\n

The following example shows a piece of code that uses randomness.

\n\n
final class HashedPassword\n{\n   // ... \n\n   public function __construct(string $hash)\n   {\n       $this->hash = $hash;\n   }\n\n\n   public static function fromString(string $password): self\n   {\n       $hash = \\password_hash($password, PASSWORD_BCRYPT);\n\n       return new self($hash);\n   }\n\n   // ...\n}\n\nclass HashedPasswordTest extends TestCase\n{\n    /** @test */\n    function it builds a password from a string()\n    {\n        $this->assertEquals(\n            $this::fromString('Password1'),\n            new HashedPassword('$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu')\n        );\n    }\n}\n
\n\n

When we run HashedPasswordTest we get an error because the password_hash generates a random salt to hash the password. The problem is that the password_hash function cannot return the same hash for a given password. Each time you call this function a different hash will be returned.

\n\n
-Password Object &000000006e7168e60000000023b11bb2 (\n-    'hash' => '$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'\n+Password Object &000000006e7168210000000023b11bb2 (\n+    'hash' => '$2y$10$b/9GX4grnt4gH5cm8FzzSuUNGGQUiA/w.5HdKNEsW3dHtSUeTMXgK'\n
\n\n

The simplest solution would be to hardcode the salt to make sure the hash_password returns the same hash every time but this is not a good design. This would weaken the password generation because we need to test it. Another way would be to extract the hash generation in another place.

\n\n
final class HashedPassword\n{\n   // ...\n   public static function fromString(string $password, PasswordEncryptor $passwordEncryptor): self\n   {\n       $hash = $passwordEncryptor->hash($password);\n\n       return new self($hash);\n   }\n   // ...\n}\n
\n\n

The PasswordEncryptor interface makes test doubles creation possible. Now, we just need to create a fake object to test this method.

\n\n
final class FakePasswordEncryptor implements PasswordEncryptor\n{\n    public function hash(): string\n    {\n        return '$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu';\n    }\n\n}\n\nclass HashedPasswordTest extends TestCase\n{\n   /** @test */\n   function it builds a password from a string()\n   {\n        $fakePasswordEncryptor = new FakePasswordEncryptor();\n\n        $this->assertEquals(\n            this::fromString('Password1', $fakePasswordEncryptor),\n            new HashedPassword('$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu')\n        );\n   }\n}\n
\n\n

Avoid actual datetimes

\n\n

With actual datetimes, we have the same problem as with randomness, neither can be predicted.

\n\n

The following example shows you that actual datetimes are not predictable like hash_password in the previous section.

\n\n
final class Map\n{\n   // ...\n   public function __construct(\\DateTimeImmutable $markerAddedAt = null, Marker ...$makers)\n   {\n       // ...\n   }\n\n   public function addMarker(string $name, array $location): void\n   {\n       // ...\n       $this->markerAddedAt = new \\DateTimeImmutable('now');\n   }\n}\n\nclass MapTest extends TestCase\n{\n    /** @test */\n    function it adds marker to the map()\n    {\n        $map = new Map('Map name');\n        $map->addMarker('Bubar', [47.21725, -1.55336]);\n        \n        $this->assetTrue(\n            $map->hasSameState(\n                new Map(\n                    new Marker('Bubar', [47.21725, -1.55336]), \n                    new \\DateTimeImmutable('now')\n                )\n            )\n        );\n    }\n}\n
\n\n

When we run MapTest we get an error because we can predict to the millisecond when the marker was added to the map.

\n\n
-Map Object &000000003acad975000000006b83e943 ()\n+Map Object &000000003acad936000000006b83e943 (\n+    'markerAddedAt' => DateTimeImmutable Object &000000003acad946000000006b83e943 (\n+        'date' => '2021-04-18 17:36:02.919004'\n+        'timezone_type' => 3\n+        'timezone' => 'UTC'\n+    )\n+)\n
\n\n

To prevent this kind of problem, a good idea is to abstract time by introducing an interface that is responsible for time management.

\n\n
final class Map\n{\n  // ...\n  public function addMarker(string $name, array $location, Clock $clock): void\n  {\n      // ...\n      $this->markerAddedAt = $clock->now();\n  }\n   // ...\n}\n
\n\n

Now, thanks to the Clock interface we will be able to create test doubles and easily test this method.

\n\n

Coupling might be your worst enemy

\n\n
\n

Coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.

\n\n

Wikipedia

\n
\n\n

As you have seen in the previous sections, objects should depend on abstractions instead of concrete implementations. Abstractions (e.g. interfaces) ease testing because your code is more modular. You can use test doubles to reduce the complexity and facilitate testing. Their goal is to mimic the behavior of real objects to replace a subpart of an algorithm.

\n\n

The following example shows that hardcoding object dependencies won’t help to create test doubles.

\n\n
class MyClass\n{\n   public function __construct(ConcreteImplementation $concreteImplementation)\n   {\n       // Here we can only use these concrete implementations, if they use IO for instance you won't be able to test it.\n       $this->concreteImplementation = $concreteImplementation;\n       $this->anotherConcreteImplementation = new AnotherConcreteImplementation();\n      \n       // Singleton pattern does not help because it hides object dependencies and makes them hard coded.\n       $this->connection = Connection::getInstance();\n   }\n}\n
\n\n

The solution is to use the dependency inversion pattern to remove hard coded dependencies introducing abstractions as much as possible.

\n\n
\n

High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g., interfaces). Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.

\n\n

Wikipedia

\n
\n\n

In the following example, all class dependencies are interchangeable. So, you can easily create test doubles like fake, stub, or mocks to make sure your objects meet business expectations.

\n\n
class MyClass\n{\n   public function __construct(\n       ImplementationInterface $concreteImplementation,\n       AnoherImplementationInterface $anotherConcreteImplementation,\n       ConnectionInterface $connection\n   ) {\n       $this->concreteImplementation = $concreteImplementation;\n       $this->anotherConcreteImplementation = $anotherConcreteImplementation;\n       $this->connection = $connection;\n   }\n}\n
\n\n

Caution: That does not mean you should use interfaces everywhere! Knowing when to introduce new abstractions might be hard at the beginning, there is no magic recipe!

\n\n

Thanks to my proofreaders @LaureBrosseau and @jjanvier_.

\n","url":"/why-unit-testing-can-be-hard.html","relative_path":"_posts/2021-05-04-why-unit-testing-can-be-hard.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Objective: set up your projects more easily","description":"Setting up a project locally should be easy to let devs focus on delivering value. Makefile can provide an abstraction to simplify their installation and hide the complexity.","date":"2021-06-02 00:00:00 -0500","image":"set-up-your-projects-more-easily.webp","image_credit":"intelligenciya","tags":["makefile"],"keywords":"makefile,software,setup,installation","slug":"objective-set-up-your-projects-more-easily","ext":".md","excerpt":"

For the last decade I worked on several more or less complex projects. I often had problems with their installation. Sometimes, the project was not documented or the existing documentation was not up to date. I had to run commands but I did not understand all of them. When I got errors it was hard to understand what happened. That was not always simple.

\n","content":"

For the last decade I worked on several more or less complex projects. I often had problems with their installation. Sometimes, the project was not documented or the existing documentation was not up to date. I had to run commands but I did not understand all of them. When I got errors it was hard to understand what happened. That was not always simple.

\n\n

During my last projects, I used makefile to provide an abstraction to simplify their installation and hide complexity. It let me install projects with a single command and provided a minimal set of targets which made my daily work easier.

\n\n

How does makefile work?

\n\n

A makefile is a set of “rules” that looks like:

\n\n
target: prerequisites prerequisites\n        recipe\n        recipe\n        ...\n
\n\n

A target is the name of a file (or a folder) that is generated by make. It could also be the name of an action to perform but you need to declare it as PHONY.

\n\n

A prerequisite are the files (or folders) needed to create the target, you can see them as target dependencies.

\n\n

A recipe are all actions executed when the target is run. Caution: you need to indent all recipes using a “real” tab character otherwise you will get errors.

\n\n
.env:\n     cp .env.dist .env\n
\n\n

If the .env file does not exist, the recipe will be carried out, but if it does exist the recipe won’t be executed #magic.

\n\n
.PHONY: cache\ncache: .env\n      bin/console c:c\n
\n\n

The cache target does not target a file. Declaring this target as PHONY allows having a file named cache in the same directory as the Makefile.

\n\n

Note: If the .env file does not exist the .env target will be performed before the cache target.

\n\n

Let’s take an example

\n\n

For instance, a project orchestrated by docker-compose having:

\n\n\n

Caution: I will only speak about projects setup for dev purposes. I won’t talk about making docker images ready for production.

\n\n

Let’s start installing the project dependencies. The following targets install project dependencies if they have not been downloaded yet. They can guess if they are outdated to upgrade them thanks to target prerequisites. Another interesting thing is that nothing will be done if dependencies are already installed and up to date.

\n\n
# Front\nweb/yarn.lock: web/package.json\n  docker-compose run --rm node yarn install\n\nweb/node_modules: web/yarn.lock\n  docker-compose run --rm node yarn install --frozen-lockfile\n  docker-compose run --rm node yarn check --integrity\n\n# back\napi/composer.lock: api/composer.json\n  docker-compose run --rm fpm composer update\n\napi/vendor: api/composer.lock\n  docker-compose run --rm fpm composer install\n\n
\n\n

Then, we need to “up” all docker-compose services: the web server, the PHP process manager, the datatable, and the node to run the front application in development mode.

\n\n
.PHONY: up\nup:\n  docker-compose up -d\n
\n\n
docker-compose ps                                              \n         Name                        Command               State                                     Ports                                   \n---------------------------------------------------------------------------------------------------------------------------------------------                                                     \nmy-maps-node              docker-entrypoint.sh yarn  ...   Up                                                                                \nmy-maps-web               nginx -g daemon off;             Up      80/tcp                                                                    \nmy-maps_database_1        docker-entrypoint.sh postgres    Up      5432/tcp                                                                  \nmy-maps_fpm_1             php-fpm -F                       Up                                                                           \n
\n\n

The last thing to do is to create the database schema using Doctrine migration.

\n\n
.PHONY: db-migration\ndb-migration: api/vendor\n  docker-compose run --rm fpm bin/console doctrine:migrations:migrate --no-interaction\n
\n\n

Tip: To ease my daily work, I like introducing other targets like db target that resets database quickly or fixture to load some data fixtures.

\n\n
.PHONY: db\ndb: api/vendor\n  docker-compose run --rm fpm bin/console doctrine:database:drop --force --no-interaction\n  docker-compose run --rm fpm bin/console doctrine:database:create --no-interaction\n\n.PHONY: fixtures\nfixtures: api/vendor\n  docker-compose run --rm fpm bin/console project:fixtures:load\n
\n\n

Now, we have all atomic targets to set up all parts of the application. Another interesting thing with make, is that it can run several targets within a single command make up api/vendor web/node_modules.This is pretty useful to create scenarios. For instance, to set up and run the project I only need to run the following command:

\n\n
make up api/vendor web/node_modules db db-migration fixtures\n
\n\n

But it works with everything:

\n\n
make db db-migration fixtures\nmake api/vendor web/node_modules\n
\n\n

To make your day-to-day basis, you can introduce targets that run those scenarios.

\n\n
# It builds and runs the application\n.PHONY: app-dev\napp-dev: up api/vendor web/node_modules db db-migration fixtures\n\n# It resets the database\n.PHONY: db-reset\ndb-reset: db db-migration fixtures\n\n# It resets the database\n.PHONY: dependencies\ndependencies: api/vendor web/node_modules\n
\n\n

Tip: I advise you to introduce the minimum set of targets into the makefile. Keep it simple! Don’t forget that everyone uses it! To let developers have their custom targets you may want to include custom makefiles using include. Don’t forget to add an entry into .ignore to avoid committing those files. Now, developers can create their own makefile with their personal targets.

\n\n

One last word

\n\n

Makefile is only a solution, this is not THE solution. The important thing to keep in mind is that you should be able to easily run your project to reduce the developer’s mental load and let them focus on the right thing. It will improve the day-to-day basis and make newcomers’ onboarding easier.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/objective-set-up-your-projects-more-easily.html","relative_path":"_posts/2021-06-02-objective-set-up-your-projects-more-easily.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"The command bus design pattern","description":"The goal of command and the event bus is to deliver a command or an event to its handler(s). Events and commands are objects used to encapsulate information needed to achieve an action (a command) or to tell what happened in the system (an event).","date":"2022-09-12 00:00:00 -0500","image":"command-bus/command-bus.svg","keywords":"software,software architecture,design patterns,command bus,event bus,bus,middleware","tags":["command-bus","design-patterns"],"slug":"command-bus-design-pattern","ext":".md","excerpt":"

Note: Before reading this blog post, if you don’t know what a command and a command handler are, I advise you to first read the blog post I’ve written about those design patterns. It will help you to understand this new article:

\n","content":"

Note: Before reading this blog post, if you don’t know what a command and a command handler are, I advise you to first read the blog post I’ve written about those design patterns. It will help you to understand this new article:

\n\n
\n \n \n \"Command\n \n \n Command and command handler design pattern\n \n \n
\n\n

What is a bus?

\n\n

Let’s start with the basics, what is a bus? In computer science, a bus is a system that connects several components and transfers data between them. In software, those components are called middleware. A middleware processes an incoming request and returns a response. As you can see in the schema below, the main advantage of a bus is that it is highly customizable as you can add as many middleware as you want.

\n\n

\"A

\n\n

In the next sections, we will speak about the command bus which is often associated with an event bus. Using an event bus is not mandatory but we will see how it will make your application more modular and evolutive. Their goal is to deliver a command or an event to their handler(s). Events and commands are objects used to encapsulate information needed to achieve an action (a command) or to tell what happened in the system (an event).

\n\n

The command bus

\n\n

Quick reminder about command and command handler: A command represents a user’s intent. The data carried by the command has to be valid. It can be only handled by only one handler that is just a callable that will perform the user action.

\n\n

Now, we will build a command bus following the same architecture that I described in the previous section. The only difference is that the command bus will return void. As commands canmight be handled asynchronously, we don’t want to wait for the result of the command processing.

\n\n

\"A

\n\n

Let’s see the most common middleware used to build a command bus. The first one is probably the “logging middleware”. It helps to make your application observable and it is really useful for bug hunting. Then the “validation middleware” ensures that the command is valid before giving it to the handler. Its purpose is to stop the command processing if data is invalid. It is pretty convenient because it avoids validating them manually. When your application uses a database, the “transaction middleware” wraps the handler execution into a SQL transaction. It makes sure all database changes are done, otherwise it rollbacks the transaction. Finally, the last middleware is responsible for finding and executing the handler that matches the command.

\n\n

The event bus

\n\n

An event represents something that happened in the application. Unlike a command, an event can be handled by several handlers. Listening to events allows us to enhance existing features or add new ones very quickly. Several teams can listen to the same event to perform additional tasks depending on business needs. It makes applications more evolutive without adding accidental complexity and lets your team work isolated from each other.

\n\n

Tip: I would like to encourage you to mainly use business-oriented events instead of technical ones. They clearly describe what happened from a business point of view. For example, NewAccountHasBeenCreated is more understandable than ResourceCreated with a resource property equal to ‘Account’

\n\n

Even if the event bus is built the same way as the command bus we don’t need all the different middleware. We don’t need the validation middleware because events are generated by the aggregates with value objects. Those objects ensure domain invariant which means they are always valid. We also don’t need the transactional middleware because the event will be processed into the transaction begun during the command processing. Moreover, depending on your business needs you may not want to process events into this transaction. Let’s take a simple example. After creating an account, an event AccountCreated is dispatched, then a welcome email is sent during AccountCreated processing. If the email sending fails, do we want to roll back the account creation? Not sure! In that case, you need to speak with your product manager to decide how to process this event.

\n\n

As I said previously, events are recorded by aggregates and they should be business oriented. I will share with you two ways to dispatch events into the event bus.

\n\n

\"A

\n\n

Solution 1: You can collect them from your repository if no errors have been raised during the aggregate persisting and then dispatch them.

\n\n

Solution 2: The other solution is to collect events from the command handler. The handler can return them, and then the “handle command” middleware catches and dispatches them.

\n\n

Note: My previous blog post about the command and command handler pattern said that a command handler should return void. Here, the idea is that the command bus should return void only the “handle command” should be aware of the result of the handler execution.

\n\n

I’ve written a bunch of articles about how to handle a command, validate its data, handle user permissions, and so on. Take a look at these articles:

\n\n
\n \n \n \"See\n \n \n See all blog posts about command handling.\n \n \n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/command-bus-design-pattern.html","relative_path":"_posts/2022-09-12-command-bus-design-pattern.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"How to handle user permissions through command bus middleware","description":"Applying user permissions might be very complex and can lead to introducing a lot of accidental complexity to your application. Adding a middleware to your command bus can solve this issue.","date":"2022-09-26 00:00:00 -0500","image":"how-to-handle-permissions-through-command-bus-middleware.webp","image_credit":"kellysikkema","keywords":"software,software architecture,design patterns,command bus,permissions,security,bus,middleware","tags":["command-bus"],"slug":"how-to-handle-user-permissions-through-command-bus-middleware","ext":".md","excerpt":"

Applying user permissions might be very complex and can lead to introducing a lot of accidental complexity to your application. In this blog post, I want to share with you how to do it by simply adding a middleware to your command bus.

\n","content":"

Applying user permissions might be very complex and can lead to introducing a lot of accidental complexity to your application. In this blog post, I want to share with you how to do it by simply adding a middleware to your command bus.

\n\n

Note: If you’re not familiar with this pattern, please have a look at this blog post, it explains what a command bus and a middleware are.

\n\n

Let’s imagine a basic use case: an application with two kinds of users: regular ones and admins. We want to allow certain actions only to admin users.

\n\n

First, I will introduce an interface OnlyPerformedByAdministrator that will be implemented by the command restricted to the admin users.

\n\n
interface OnlyPerformedByAdministrator\n{\n    public function username(): string;\n}\n\nclass CreateNewProduct implements OnlyPerformedByAdministrator\n{\n    // ...\n    public function username(): string\n    {\n        return $this->username;\n    }\n}\n
\n\n

Then, we will add a CheckAccessPermission middleware to the command bus that will check if the user can execute an action. If he/she can’t, an AccessDenied exception will be thrown. It will be caught later in the execution flow to be turned into something that will be understandable to the user.

\n\n
final class AccessDenied extends \\Exception\n{\n}\n\nclass CheckAccessPermission implements Middleware\n{\n    public function __construct(private Users $users) {}\n\n    final public function handle(Command $command, Middleware $next): void\n    {\n        $user = $this->users->get(new Username($command->username()));\n        if ($command instanceof OnlyPerformedByAdministrator && !$user->isAdmin()) {\n            throw new AccessDenied();\n        }\n\n        $next->handle($command);\n    }\n}\n
\n\n

This middleware will stop the command processing if an error is raised. We need to catch this exception to return a 403 HTTP response in the web controller, or to return a status code greater than 0 in the CLI command.

\n\n
final class WebToggleCartographerPremiumStatus\n{\n    public function __construct(private CommandBus $commandBus) {}\n    \n    public function __invoke(Request $request): Response\n    {\n        try {\n            $this->commandBus->handle(new CreateNewProduct(/** ... */));\n        } catch (AccessDenied) {\n            throw new Response(403, 'Access denied');\n        }\n\n        return new Response(200);\n    }\n}\n
\n\n

Why do I handle permissions with a middleware?

\n\n

I decided to add a middleware to the command bus because it ensures that permissions are checked no matter where commands are dispatched. For example: from the web controller or a CLI command. Moreover, I don’t depend on a security library or any framework configuration. All permission business rules are coded in the domain.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/how-to-handle-user-permissions-through-command-bus-middleware.html","relative_path":"_posts/2022-09-26-how-to-handle-user-permissions-through-command-bus-middleware.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Increase your test quality thanks to builders or factories","description":"Bad tests are hard to maintain and they slow down your productivity. Test code quality is as important as production code. The builder or factory patterns can help you to improve your test code quality. It will ease test refactoring and make tests more readable.","date":"2022-10-10 00:00:00 -0500","image":"increase-your-test-quality-thanks-to-builders-or-factories.webp","image_credit":"thoughtcatalog","keywords":"testing,test,software,design pattern,code quality","tags":["testing"],"slug":"increase-your-test-quality-thanks-to-builders-or-factories","ext":".md","excerpt":"

In a previous blog post, I explained why it’s better to compare object instances instead of exposing their state to test them. This avoids breaking encapsulation and it does not have any impact on their design.

\n","content":"

In a previous blog post, I explained why it’s better to compare object instances instead of exposing their state to test them. This avoids breaking encapsulation and it does not have any impact on their design.

\n\n

Let’s take an example! My side project allows me to create maps to remember places I have been. A map has a name and, as a cartographer, I am allowed to rename it. Real basic use case but more than enough! The following test ensures I can rename this map:

\n\n
$map = new Map(\n    new MapId('e9a01a8a-9d40-476e-a946-06b159cd484a'),\n    new Username('Pepito'),\n    new MapName('Bordeaux city'),\n    new Description('Good places in Anglet'),\n    Tag::city(),\n    MarkerList::empty(),\n);\n\n$map->rename('Anglet city');\n\nAssert::equals(\n    $map,\n    new Map(\n        new MapId('e9a01a8a-9d40-476e-a946-06b159cd484a'),\n        new Username('Pepito'),\n        new MapName('Anglet city'),\n        new Description('Good places in Anglet'),\n        Tag::city(),\n        MarkerList::empty(),\n    )\n);\n
\n\n

We can see that comparing object instances is great for encapsulation because we don’t expose the object’s state but this makes the test less readable. Here, the only thing we want to focus on is the value of MapName. The values of the other value object are only noise because they are not useful for this test. But, this is not the only drawback of this test. What happens if you want to add an extra property to the Map object? In this case, we will need to refactor all the tests that create a map object. It might be easily doable in small projects but it can become messy for big ones.

\n\n

Now, let’s show how we can improve this test. The title of my blogpost can give you a huge hint on the solution. We will add a named constructor called whatever to the Map object to centralize the object construction. Named constructors are static factories that build the object itself.

\n\n
class Map \n{\n    /** @internal */\n    public static function whatever(\n        string $mapId = 'e9a01a8a-9d40-476e-a946-06b159cd484a',\n        string $addedBy = 'Pepito',\n        string $name = 'Anglet city',\n        string $description = 'Good places in Anglet',\n        string $tag = 'city',\n        array $markers = [],\n    ): self {\n        return new self(\n            new MapId($mapId),\n            new Username($addedBy),\n            new MapName($name),\n            new Description($description),\n            new Tag($tag),\n            new MarkerList($markers),\n        );\n    }\n}\n
\n\n

Tip: I like to add a @internal annotation to remind all teammates that the object constructor should only be used in tests.

\n\n

The value object instantiation is delegated to the whatever constructor. I try to use primitive data types like arguments as much as possible, it makes me write less code and it’s easier to read. All constructor arguments have a default value, then I can override a given value depending on the needs thanks to the named argument feature.

\n\n
$map =  Map::whatever(name: 'Bordeaux city');\n\n$map->rename('Anglet city');\n\nAssert::equals(\n    $map,\n    Map::whatever(name: 'Anglet city')\n);\n
\n\n

Now, the test is clear and focuses on the right thing. Everyone can easily understand it, and it will help your teammates to grasp the code you wrote. Refactoring will be simplified as you only have to rewrite the whatever constructor if the signature of the primary constructor of Map changes.

\n\n

I know that some people won’t like the idea of adding a method to objects only for testing purposes. If you don’t like that, you can replace this static factory with a builder.

\n\n
class MapBuilder\n{\n    private string $mapId = 'e9a01a8a-9d40-476e-a946-06b159cd484a';\n    private string $addedBy = 'Pepito';\n    private string $name = 'Anglet city';\n    private string $description = 'Good places in Anglet';\n    private string $tag = 'city';\n    private array $markers = [];\n\n    public function identifiedBy(string $mapId): self\n    {\n        $this->mapId = $mapId;\n        \n        return $this;\n    }\n\n    public function named(string $name): self\n    {\n        $this->name = $name;\n\n        return $this;\n    }\n\n    // ... other setters ....\n\n    public function build(): Map {\n        return new Map(\n            new MapId($this->mapId),\n            new Username($this->addedBy),\n            new MapName($this->name),\n            new Description($this->description),\n            new Tag($this->tag),\n            new MarkerList($this->markers),\n        );\n    }\n}\n
\n\n

Then your test will look like this:

\n\n
$map =  (new MapBuilder())->named('Bordeaux city')->build();\n\n$map->rename('Anglet city');\n\nAssert::equals(\n    $map,\n    (new MapBuilder())->named('Anglet city')->build()\n);\n
\n\n

Tip: Read or anemic models don’t have logic to ensure they are built in a good way. If you use this method for them you can add some logic to your builder/factories to ensure they are created with consistent data. It will make your tests stronger.

\n\n

Final thought

\n\n

Builders or factories ease test refactoring and make tests more readable. Don’t forget that bad test suites are a nightmare to maintain and can drastically slow down your delivery. Taking care of your test quality will help you to ship fast. Moreover, good tests are free documentation.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/increase-your-test-quality-thanks-to-builders-or-factories.html","relative_path":"_posts/2022-10-10-increase-your-test-quality-thanks-to-builders-or-factories.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"How I have learned programming by myself","description":"Learning is an important part of our job. It is not that easy when you don’t know where to start, especially if you're self-taught like me. I share what I did to learn software development for the last 15 years in this blog post.","date":"2022-10-17 00:00:00 -0500","image":"how-I-have-learned-programming-by-myself.webp","image_credit":"thoughtcatalog","keywords":"learning,knowledge,software,continuous learning,self taught,mentor,open source,conference,books,burnout,training","tags":["learning"],"slug":"how-I-have-learned-programming-by-myself","ext":".md","excerpt":"

I am, what we call, a self-taught. I studied telecommunications and networks at school, unfortunately, I only learned the basics of programming. I had to learn and improve my skills by myself for many years during my free time. I did not take the easiest path to learn! That’s why I wanted to share with you my own experience and what I did to learn software development. I hope this post will help some of you.

\n","content":"

I am, what we call, a self-taught. I studied telecommunications and networks at school, unfortunately, I only learned the basics of programming. I had to learn and improve my skills by myself for many years during my free time. I did not take the easiest path to learn! That’s why I wanted to share with you my own experience and what I did to learn software development. I hope this post will help some of you.

\n\n

Find a mentor

\n\n

In the beginning, even though I knew some basics of programming I was a bit lost. I wasn’t able to build an application end to end and I did not know which subject I had to study to solve that. That’s why I advise junior engineers to find at least one mentor. A mentor can teach you what is important like how to test, design patterns, software architecture, and so on. A mentor will help you focus on the right topics like how to build robust applications instead of focusing on hype technologies.

\n\n

Tip: If you’re a junior, I would recommend you focus on testing: TDD will help you to design your code step by step. Architectural patterns like hexagonal architecture will help you to decouple your code from IO. Agile: eXtreme programming will help you to reduce the cost of changes by having multiple short development cycles rather than a long one.

\n\n

Play and have fun with a side project

\n\n

You can have strong constraints at work, so it can be really hard to try new things because of bad processes, bad code quality, impossible deadlines etc. I have worked on several side projects for the last 10 years. I tried twice to release an application for a French NGO to manage their volunteer data. Then I tried to make an application to organize my trips. The last one is about making maps to remember places I have been. I learned a lot from those projects, they let me try what I read in blog posts, books or what I saw in conferences without any pressure of production. The funny thing is that I learned more from failures. Only my last side project “mymaps” is live, I did not release the other ones! This is because they were only playgrounds rather than real projects. They helped me understand why being pragmatic is important, focusing only on technical aspects does not help to build an application. Keep in mind that a good codebase is not the only thing you need to make a successful project.

\n\n

Contribute to an open-source project

\n\n

I worked on Sylius which is an open-source e-commerce framework. The community of Sylius is great. I learned a lot of good practices like testing, code review and behaviour-driven development for instance. I mainly worked on the SyliusResourceBundle which is a library that eases CRUD management. During this period, I was working for a web agency, it helped me to be more efficient at work and ship projects faster.

\n\n

Caution: Many companies use open-source projects but they don’t contribute to them. I was happy to contribute to this project during my free time, but you should negotiate allocated time with your company to help those projects if they help you deliver value to your customers.

\n\n

I would like to thank Pawel for making me a core team member. Contributing to Sylius has opened many doors to me.

\n\n

Thanks to what I have done in that library, I had the chance to do my first conference (Symfony live) as a speaker. That was so great! I was so excited and terrified at the same time. Then I got hired by a french startup Akeneo to work on an open-source PIM (Product Information Management). I only worked for service companies before Akeneo, this experience made me discover what was software edition.

\n\n

Attend conferences and meetups

\n\n

Attending conferences is a great way to learn and open your mind to new things. You can have a chat with other attendees during breaks as well. It is a good way to meet new people and to have interesting talks. One of my favourite conferences is newcraft, its local edition at Bordeaux was really great too.

\n\n

When you will be comfortable the next step will be to do a presentation. Preparing a talk is good to dive into the topic you will present and formalize your ideas. Even if you know this topic, it may not be that easy to clearly explain it to someone else. Don’t be shy, submit your talks! A lot of conference organizations help new speakers. I did not think too much when I submitted my first talk. I thought it wouldn’t be selected but I received an email that said my talk was accepted. I was so happy and excited! I realized what happened and I really started to panic (true story, a little panic attack) so I started to work on my talk to be ready for D-day. You can have a look at my talks.

\n\n

Read books

\n\n

Another way to learn is through books. This is a good way to shut down your computer while still learning new things about software engineering.

\n\n

Tip: Some books in my library: Accelerate, Extreme Programming Explained, Domain-Driven Design Distilled, Patterns, Principles, and Practices of Domain-Driven Design, Elegant Objects and so on.

\n\n

Final thoughts

\n\n

A few weeks ago, I saw some software engineers saying on social media that we should self-train in our free time. Learning in your free time will help you progress faster but it can be time and energy consuming. Don’t forget that burnouts are real. One of my friends experienced burnout and couldn’t do anything for almost a year, he was completely out of energy.

\n\n

I also had to take several breaks in my learning process to avoid going to the dark side of the force. Only do things when you want in your free time! Don’t put pressure on yourself! And keep in mind that learning should be fun!

\n\n

Learning is a part of your job. Companies should let you learn during business hours. On a day-to-day basis, pair and mob programming is a good way to learn and challenge your ideas. Your company should train you as well. For instance, Mathias Noback gave us some training when I was at Akeneo. I learned a lot from him, and I definitely recommend him!

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/how-I-have-learned-programming-by-myself.html","relative_path":"_posts/2022-10-17-how-I-have-learned-programming-by-myself.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"My feedback about example mapping","description":"Example mapping is a good way to align the team's understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.","date":"2022-10-31 00:00:00 -0500","image":"example-mapping/my-feedback-about-example-mapping.webp","image_credit":"amandagraphc","keywords":"example mapping,bdd,behavior driven development,no estimate,team collaboration,sticky note,small story,domain problem","tags":["BDD","methodology"],"slug":"my-feedback-about-example-mapping","ext":".md","excerpt":"

Example mapping is a workshop that gathers tech and non-tech people to ensure everyone has the same understanding of the domain problem. It also helps clarify the acceptance criteria for a given story. Because it’s always better to understand what is expected and raise all bottlenecks before developing a story.

\n","content":"

Example mapping is a workshop that gathers tech and non-tech people to ensure everyone has the same understanding of the domain problem. It also helps clarify the acceptance criteria for a given story. Because it’s always better to understand what is expected and raise all bottlenecks before developing a story.

\n\n

Disclaimer! I won’t explain how to run such a workshop, you can easily find a bunch of articles on the web. You can also have a look at these slides, they come from one of my talks about example mapping if you’re not familiar with it. In this blog article, I want to share with you my experience on Example Mapping and how it helps me to prepare and organize the team’s work.

\n\n

Caution: A little while ago, I got feedback from Bruno Boucard about using sticky notes. He advised me to use index cards instead of sticky notes. The workshop attendees can put them on a table and easily move them, unlike stick notes. I speak about sticky notes in this blog post because I only practiced this workshop remotely using tools like Miro.

\n\n

Who will attend the workshop?

\n\n

The methodology recommends to involve at least the product managers, developers and testers. The goal of example mapping is that the product manager shares the problem with the person(s) who will solve it. I will go further, you can invite anyone who wants to understand what you are doing. It is a good way to share knowledge.

\n\n

During my last year at Akeneo, I worked on a new product called Shared Catalogs. All my teammates including devs, product manager, and engineering managers were newcomers. Even if they were really well onboarded on Akeneo’s products, they had a micro vision of what Akeneo PIM did, and the software’s functional perimeter was pretty huge. At this time, I was working at Akeneo for 4 years, andI had a good understanding of the product. During the example mapping sessions I shared as much knowledge as possible with my teammates, it helped the team to quickly improve their functional skills.

\n\n

When do we plan it?

\n\n

From my experience, a 30-minute slot is a good tradeoff. It’s not too long and you can easily illustrate the main business rules of the story and detect all bottlenecks. With a 30-minute meeting, you’re sure that your teammates will stay focused, especially when you work remotely. Having regular and short workshops is better than doing a big and long one.

\n\n

Depending on their roles, some team members can be really busy. For instance, I worked with several PMs who were often in meetings and it was really hard to catch them. To be sure that everyone can be available, each team member booked a 30 minutes slot after the daily meeting. Doing an example mapping was not mandatory, we only did the workshop if we needed to prepare stories.

\n\n

How organize the team

\n\n

The attendees can have different roles: onek person writes sticky notes, another animates the workshop and the others ask questions and drive the person who writes sticky notes. I think it is important to switch his/her role each session to keep everyone involved during the workshop.

\n\n

I worked with some product managers and domain experts who wanted to contribute and write sticky notes. It is not a good idea because they should focus on sharing the knowledge and let the rest of the team grasp the business expectations. You won’t help someone if you do his/her job.

\n\n

How to start

\n\n

Writing the title of a story on a yellow sticky note is pretty simple but I sometimes had difficulties getting the business rules and the examples listed. Especially, when you are doing this workshop with a team for the first time. I found out that it was easier to sometimes start by writing the example first or sometimes by writing the business rules first.

\n\n

First option: start by writing the business rules and then write the examples if your team is comfortable with the exercise and your product manager has a clear vision of what is expected.

\n\n

Second option: start by writing examples and then extract business rules from examples if your team is not comfortable with the workshop or if your product manager needs to explore a topic and he/she waits for your feedback. It will let you and your teammates speak, and understand what is going on. When you have enough examples and your understanding of business is better you can extract the business rules.

\n\n

Don’t be afraid if it is a bit complicated to be efficient in the beginning. One day, my teammates and I prepared a story about exporting a CSV file, quite simple, right? We only needed to “take data from the DB and build a file” but it wasn’t that simple! We turned this “simple” story into at least 15 stories. We discovered a lot of “hidden” business rules. We thought it was a story but it was an epic…

\n\n

How to write example

\n\n

Don’t try to write gherkins scenarios at all costs because it can be time-consuming. The goal of this workshop is to ensure all teammates grasp what the business expects and it is the right time to raise all problems and incomprehension.

\n\n

The simplest format I used to define the example looked like the Given / When / Then but a really simplified version.

\n\n

\"Simplified

\n\n

Sometimes it can be more readable to draw something.

\n\n

\"Draw

\n\n

Don’t limit yourself, if you prefer another format, use it. The most important thing is that everyone understands what is expected.

\n\n

Don’t forget red sticky notes

\n\n

Avoid endless debates! Don’t hesitate to use red sticky notes if your teammates disagree on something. Keep in mind that your product manager can’t answer all questions during the workshops. It’s normal, the product manager is not a super(wo)man! Thus, add a red sticky note and take time to think about it, he/she’ll answer all questions in the next session.

\n\n

Have small stories

\n\n

I like to talk with the PM when the story is ready to be developed (when there are no more red stickies and when all teammates are OK with it). I usually challenge him/her to know which business rules are really mandatory and which ones are nice-to-have. It ensures your stories are really small and it eases the prioritization. You can focus on what is really important and keep what is nice-to-have for later.

\n\n

Tip: If your story has too many business rules, it’s a smell! That means you should split it into small ones. It will be easier to ship several small stories than a big one. If a business rule has too many examples, that’s a smell too. You might have missed some business rules.

\n\n

\"Split

\n\n

I am not a big fan of estimates, it’s a waste of time. We should focus on understanding the problem we want to solve, instead of giving figures that will probably be wrong. Having a really small story will help you to be more predictive. You can count the stories done during a time frame and easily forecast what your team will be able to do during the next iteration.

\n\n

Final thoughts

\n\n

The first example mapping workshop can be complex but don’t give up. The more you practice, the more comfortable your team will be with the workshop. Example mapping is a good way to align the team’s understanding with the stakeholders expectations. It will help your team to better collaborate and break all silos between all kinds of positions in your team. Last but not least, it will help you refine your stories and improve your backlog prioritization.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/my-feedback-about-example-mapping.html","relative_path":"_posts/2022-10-31-my-feedback-about-example-mapping.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"What is the event sourcing pattern?","description":"Event sourcing consists in storing all changes that happened to the application state as a sequence of events instead of only storing the current state of the application. The sum of all events makes the current application state.","date":"2022-11-28 00:00:00 -0600","image":"what-is-the-event-sourcing-pattern.webp","image_credit":"vitsinkevich","keywords":"software,software architecture,design patterns,es,event sourcing,table soccer","tags":["software-architecture"],"slug":"what-is-the-event-sourcing-pattern","ext":".md","excerpt":"

Event sourcing consists in storing all changes that happened to an application as a sequence of events instead of only storing the current state of the application. The sum of all events is the current application state. When I heard about this pattern a few years ago, I was really confused. I used to only persist the current application state in a database and that was fine! So I asked myself do I need that?

\n","content":"

Event sourcing consists in storing all changes that happened to an application as a sequence of events instead of only storing the current state of the application. The sum of all events is the current application state. When I heard about this pattern a few years ago, I was really confused. I used to only persist the current application state in a database and that was fine! So I asked myself do I need that?

\n\n

I will show you an example to help you understand what this pattern stands for. People used to explain it with a bank account but I wanted to find something funnier: a table soccer game. A complete example is available on a Github repository:

\n\n
\n \n \n \"Have\n \n \n Have a look at the GitHub repository\n \n \n
\n\n

Let’s start! A group of developers who are fans of table soccer wants to create an application to see who’s the best player. They decided to save the results of matches and rank themselves.

\n\n
export class Game {\n    constructor(\n        private redTeam: Team,\n        private blueTeam: Team,\n        private gameScore: Score,\n    ) {}\n\n    public recordScore(redPlayerScore: number, bluePlayerScore: number) {\n        return new Game(\n            this.redTeam,\n            this.blueTeam,\n            new Score(redPlayerScore, bluePlayerScore),\n        );\n    }\n\n    // example: ['arn0', 'momos', 'Popeye', 'coco', 10, 1]\n    public toState(): [string, string, string, string, number, number] {\n        return [\n            ...this.redTeam.toState(),\n            ...this.blueTeam.toState(),\n            ...this.gameScore.toState()\n        ];\n    }\n}\n
\n\n

The Game Aggregate has a recordScore method to record the score at the end of the game. Then we get the current state of Game with the toState method to save it in the database.

\n\n

That works perfectly for the one versus one games but what happens for two versus two games? Let’s focus on one of the players, we will call him Popeye. Actually, Popeye is not a really good player even if he is full of goodwill. He is smart, he always wants to play with the best player to have more chances to win. We cannot know who is the best player with only the result of the game. Who has really scored? Popeye or its teammate?

\n\n

Event sourcing is the solution. Instead of saving the score of the game, we will store what really happens. We will refactor the Game aggregate to make it compliant with the event sourcing pattern.

\n\n

First, we will rework the aggregate construction. We still want to encapsulate its current state but we want to record all events that happened too. In the following example, we added an events argument to the primary constructor and a named constructor (secondary construct) called start to the Game class. From a business point of view, its goal is to initialize the game and from a technical point of view, it lets us record the GameStarted event.

\n\n
export class Game {\n    constructor(\n        private redTeam: Team,\n        private blueTeam: Team,\n        private gameScore: Score,\n        private events: Event[] = []\n    ) {}\n    \n    public static start(\n        redAttacker: Player,\n        redDefender: Player,\n        blueAttacker: Player,\n        blueDefender: Player\n    ): Game {\n        const redTeam = Team.ofTwoPlayer(redAttacker, redDefender);\n        const blueTeam = Team.ofTwoPlayer(blueAttacker, blueDefender);\n\n        return new Game(\n            redTeam,\n            blueTeam,\n            Score.playersHaveNotScored(),\n            [new GameStarted(redTeam, blueTeam)],\n        );\n    }\n}\n
\n\n

Then we will add a new method to Game to record all goals scored by any players. That will let us know who is the best striker in the game. In the following example, we record two events: GoalScored and GameEnded. The first one is recorded every time a player scores and the second one is recorded when the first team has 10 points meaning the game is over.

\n\n
export class Game { \n   // …\n   public goalScoredBy(player: Player): Game {\n        const teamColor = this.redTeam.isTeammate(player) ? TeamColor.Red : TeamColor.Blue;\n        const gameScore = this.gameScore.increase(teamColor);\n\n        this.events.push(new GoalScored(teamColor, player, gameScore))\n\n        if (!gameScore.canIncrease(teamColor)) {\n            this.events.push(new GameEnded(this.redTeam, this.blueTeam, gameScore))\n        }\n\n        return new Game(\n            this.redTeam,\n            this.blueTeam,\n            gameScore,\n            this.events,\n        );\n    }\n    // …\n}\n
\n\n

Note: We can drop the recordScore method because we won’t want to only record the score of the game at the end of the game.

\n\n

Finally, the last thing to refactor is the persistence mechanism. We need to rework the toState because we won’t store a snapshot of the Game state but we want to save all events raised during the game. This method will return all serialized events and metadata like the name of the aggregate. Normally, we should persist some extra metadata like the aggregate id or the date when the event has been raised. Then, those data will be used in the Game repository to persist changes in the database.

\n\n
export class Game { \n    // …\n    public toState(): [[string, string]] {\n        return this.events.map((event: Event) => ['Game', event.toState()]);\n    }\n    // …\n}\n
\n\n

Last thing, we will add a named constructor to be able to build the object from the persisted state (a list of events). The fromEvents will iterate on all events to compute and set the current state of a game.

\n\n
export class Game { \n    // …\n    public static fromEvents(events: Event[]): Game {\n        let redTeam, blueTeam, score;\n        events.forEach((event: Event) => {\n            switch (true) {\n                case event instanceof GameStarted:\n                    redTeam = event.redTeam;\n                    blueTeam = event.blueTeam;\n                    break;\n                case event instanceof GameEnded:\n                    score = event.score;\n                    break;\n            }\n\n        });\n\n        return new Game(redTeam, blueTeam, score, events);\n    }\n    // …\n}\n
\n\n

Now, we have all the data we need to know if Popeye really helps his teammate. In the following code example, we can see that Momos and arn0 were not in a good shape. Coco and Popeye won easily but we can see that Popeye did not score. Perhaps, he is a good defender, who knows?

\n\n
let game = Game.startTwoVersusTwo('arn0', 'momos', 'Popeye', 'coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('momos')\ngame = game.goalScoredBy('arn0')\ngame = game.goalScoredBy('arn0')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('momos')\ngame = game.goalScoredBy('momos')\ngame = game.goalScoredBy('arn0')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\ngame = game.goalScoredBy('coco')\n
\n\n

I explained to you how to save Game aggregate events and create the aggregate from events in the previous sections of the blog post. The last missing feature is the leaderboard! How to create it? It won’t be as simple as querying a SQL table in the database because we need to get all game events for each game and compute them to know who is the better striker. Even though it can be fast in the beginning, the more games you have, the longer it will be.

\n\n

To prevent this problem, we need to create data projections. That means we will compute a representation of the data we want to query from the event stream. We will compute the new projection of the leaderboard each time a game ends.

\n\n

Last but not least, We often associate CQRS with the event sourcing pattern even if there are two different patterns.

\n\n

Don’t forget that a complete example is available on a Github repository.

\n\n
\n \n \n \"Have\n \n \n Have a look at the GitHub repository\n \n \n
\n\n

Any resemblance to real and actual names is purely coincidental!

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/what-is-the-event-sourcing-pattern.html","relative_path":"_posts/2022-11-28-what-is-the-event-sourcing-pattern.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Hexagonal architecture by example","description":"The hexagonal architecture, or ports and adapters architecture, is an architectural pattern used in software design. It aims at creating loosely coupled application components that can be easily connected to their software environment by means of ports and adapters.","date":"2023-01-09 00:00:00 -0600","image":"hexagonal-architecture/hexagonal-architect-by-example.webp","image_credit":"kmitchhodge","keywords":"architectural pattern,design pattern,hexagonal architecture,port adapter architecture,domain,infrastructure,user interface,software","tags":["software-architecture"],"slug":"hexagonal-architect-by-example","ext":".md","excerpt":"

In this blog post, I would like to explain the basics of hexagonal architecture thanks to a simple example: a product catalogue. The catalogue manager can add new products through a user interface and the nightly cron task imports new products from the ERP.

\n","content":"

In this blog post, I would like to explain the basics of hexagonal architecture thanks to a simple example: a product catalogue. The catalogue manager can add new products through a user interface and the nightly cron task imports new products from the ERP.

\n\n

Before going deeper into hexagonal architecture, let’s see what we need to create the product management application. We need two entry points: the first one will be consumed by the graphical client and the other one will be used by the cron task. Then, we will need another piece of code which will be in charge of persisting product data into storage.

\n\n

\"Application

\n\n

What is hexagonal architecture?

\n\n
\n

The hexagonal architecture, or ports and adapters architecture, is an architectural pattern used in software design. It aims at creating loosely coupled application components that can be easily connected to their software environment by means of ports and adapters. This makes components exchangeable at any level and facilitates test automation.

\n\n

Wikipedia

\n
\n\n

There are three main areas in the hexagonal architecture:\nThe primary adapters (user interface) are the whole application entry points that can be consumed by clients like a UI or a CLI.\nThe secondary adapters (infrastructure) connect the application to tools like the database, file system, etc.\nThe domain is all pieces of code that represent the problem we are solving. This part must be side-effect free (it must not use any tools).

\n\n

Domain

\n\n

The domain is the area where we solve our business problems no matter the technical constraints. We can start by designing the product aggregate.

\n\n
type Name = string;\ntype Description = string;\n\nexport class Product {\n    constructor(\n        private name: Name,\n        private description: Description\n    ) {}\n\n    toState(): string[] {\n        return [this.name, this.description];\n    }\n}\n
\n\n

As I said, we need to save products into the database but we don’t mind if the database is PostgreSQL, MySQL or whatever in the domain. We will define an abstraction (an interface) to avoid accessing any technical asset from the domain. This interface which is called a port will specify how to store a new product from a business point of view. This is nothing more than applying the dependency inversion design pattern.

\n\n
export interface ProductCatalog {\n    add(product: Product): void\n}\n
\n\n

What about testing?

\n\n

Moving IO as far as possible from your domain code is really convenient because it eases unit testing. We will mainly test this part of the application with unit testing. It offers a very short feedback loop, it will help you to design your domain step by step without setting up the whole application.

\n\n

Tip: I’ve written a blog post about unit testing that explains why testing can be hard. It mainly gives you tips to move IO outside your code to make it testable.

\n\n
\n \n \n \"Why\n \n \n Why unit testing can be hard?\n \n \n
\n\n

Coupling rules

\n\n

The domain code must not use any IO: any tools like your database, randomness, or actual datetime, nor depend on the primary and the secondary adapters. We will explain what they are in the next sections.

\n\n

Secondary adapters (Infrastructure)

\n\n

The secondary or driven adapters implement the ports defined in the domain. In our example, the adapter will be a PostgresProductCatalog class that implements the ProductCatalog interface (port). Its purpose will be to store product data in a database.

\n\n
class PostgresProductCatalog implements ProductCatalog {\n    constructor(private pg: Client) {}\n\n    add(product: Product) {\n        this.pg.query(\n            'INSERT INTO product (name, properties) VALUES ($1, $2)',\n            product.toState()\n        );\n    }\n}\n
\n\n

An advantage of this architecture is that we can simply delay choices. At the beginning of a project, it may be hard to choose the right tools because you still need to learn and understand the business. In that case, you can implement an in-memory adapter, it will work the same way as the previous one but it will only keep product aggregate in memory.

\n\n
class InMemoryProductCatalog implements ProductCatalog {\n    private products: Product[];\n\n    add(product: Product) {\n        this.products = [product, ...this.products];\n    }\n}\n
\n\n

Tip: This adapter can be used in your test suites because it lets you bypass your tools constraints like foreign key constraints when we use a database, for instance.

\n\n

What about testing?

\n\n

The part of the application is mainly covered by “integration” or “contract” tests. Those tests ensure that the tools used by the application work as expected. For example, you are able to save and query your database.

\n\n

Tip: I encourage you to test all implementations of a given port with the same test because it will ensure they work the same way.

\n\n

Coupling rules

\n\n

The infrastructure code only depends on the domain code.

\n\n

Primary adapters (User interface)

\n\n

The primary adapters or driving adapters are entry points that describe how the application is consumed by the clients. Their purpose is to tell the domain what to do. Actually, it can be a Web controller or CLI command for instance.

\n\n

In our example, we need two adapters: a web controller and a CLI command. Both of them will execute the same action, they will save product data but they have different input and output. The first one takes JSON and returns an HTTP response and the second one takes input and returns code status.

\n\n
try {\n    this.productCatalog.add(new Product(\n        request.get('name'), // get name argument for cli command\n        request.get('description'), // get description argument for cli command\n    ))\n\n    return new HttpResponse(201); // return 0 for cli command\n} catch (Error) {\n    return new HttpResponse(500); // return 1 for cli command\n}\n
\n\n

As you see, the only differences are the input and output of the adapter. We need to refactor this code to avoid duplication between both primary adapters. It should be extracted into a dedicated business service.

\n\n

Tip: These business services can be written using the command and command handler patterns. I’ve written a blog post that explains these design patterns:

\n\n
\n \n \n \"Command\n \n \n Command and command handler design pattern\n \n \n
\n\n

I’ve written a bunch of articles about how to handle a command, validate its data, handle user permissions, and so on. Take a look at these articles:

\n\n
\n \n \n \"See\n \n \n See all blog posts about command handling.\n \n \n
\n\n

What about testing?

\n\n

There are several ways to test primary adapters.

\n\n

First option: the easiest one, your application only has one primary adapter. I advise you to write an acceptance test that boots the application and checks that the whole application works for each business use case.

\n\n

Second option: the complex one, your application has several primary adapters like our example (web and CLI). I advise you to check that your command handler works as expected thanks to an acceptance. That way you ensure your handler will work as expected for both adapters. Thus, you can write a test to ensure that the adapters return the right output (HTTP response or code status) depending on the case.

\n\n

Coupling rules

\n\n

The user interface code only depends on the domain code.

\n\n

Flow of control

\n\n

\"Hexgonal

\n\n

The application flow goes from the user interface (1) through the domain (2) to the infrastructure (3) then goes back through the domain (2) to the user interface (4).

\n\n

Example: The UI sends data to an HTTP controller (1), then a product aggregate is created (2), then the repository saves data into the database (3), and finally the web controller sends a 200 HTTP response (4). We don’t need step (2) because nothing happens in the domain after the product creation.

\n\n

Code organization

\n\n

The domain contains the aggregates, ports, business services and so on. Most importantly, they must not use IO and must be business oriented.

\n\n

The infrastructure contains all secondary adapters that use external tools (IO) like your database.

\n\n

The user interface contains all primary adapters that are the application entry points. Users and machines use them to interact with the application.

\n\n
src\n├── domain\n│   ├── ProductCatalog.ts\n│   └── Product.ts\n├── infra\n│   ├── InMemoryProductCatalog.ts\n│   └── PostgresProductCatalog.ts\n└── user-interface\n    ├── CliCreateProduct.ts\n    └── WebCreateProduct.ts\n
\n\n

Note: I decided to split each class/interface into a dedicated module because I wanted to show you where things are. Feel free to organize your module as you wish.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/hexagonal-architect-by-example.html","relative_path":"_posts/2023-01-09-hexagonal-architect-by-example.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"What is the difference between CQS and CQRS patterns?","description":"CQS and CQRS are misunderstood design patterns. They are more simple than people think! CQS is about dividing an object's methods into two categories: commands and queries while CQRS is about separating query and command into two objects.","date":"2023-02-06 00:00:00 -0600","image":"what-is-the-difference-between-cqs-and-cqrs-patterns.webp","image_credit":"mihaistrompl","keywords":"cqs,cqrs,design pattern,software","tags":["software-architecture","design-patterns"],"slug":"what-is-the-difference-between-cqs-and-cqrs-patterns","ext":".md","excerpt":"

I recently found out that I did not grasp those design patterns. There are a lot of resources on the Internet about them but they are not always accurate. That’s a shame because they are pretty simple. I will share my understanding of them with you.

\n","content":"

I recently found out that I did not grasp those design patterns. There are a lot of resources on the Internet about them but they are not always accurate. That’s a shame because they are pretty simple. I will share my understanding of them with you.

\n\n

What is Command Query Segregation (CQS)?

\n\n
\n

The fundamental idea is that we should divide an object’s methods into two sharply separated categories:

\n \n\n

Martin Fowler

\n
\n\n

This concept is not specific to Object Oriented Programming but improves the object’s design. The object methods only have a single purpose: reading or changing the object state. We can see an object as a living entity. We can ask a question to someone because we need information. For example, we can ask someone what time it is. This is a query. We can ask someone to do something, we don’t expect an answer but we want to get the job done. For example, we can ask a child to finish his/her spinach. This is a command.

\n\n

We can apply this pattern to any object: like an aggregate. Let’s take an example! I would like to add markers on a map and then I would like to find which markers are the closest to a specific location (GPS Coordinates).\nk

\n
class Map {\n    addMarker(label: string, latitude: number, longitude: number): void {\n        // ...\n    }\n\n    findClosestMarkers(location: Location): Marker[] {\n        // ...\n    }\n}\n
\n\n

The addMarker method is in charge of mutating the object state without returning any result, while the ‘findClosestMarkers’ method finds the right markers without changing the object’s state. This object follows the CQS definition.

\n\n

Let’s go further. If we design our aggregates following the CQS pattern, we should apply it to the classes that handle use cases.

\n\n
interface MapService {\n    addMarkerToTheMap(label: string, latitude: number, longitude: number); void\n    findAllMarkersCloseToLocation(): Marker[]\n}\n
\n\n

This ensures there is no inconsistency in the codebase. The business services use and manipulate the aggregates. For example, if the MapService.addMarkerToTheMap method returns a result, it might mean that the Map.addMarker method will need to return the expected result.

\n\n

What is Command Query Responsibility Segregation (CQRS)?

\n\n
\n

Starting with CQRS, CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).

\n\n

Greg Young

\n
\n\n

Note: Greg Young’s blog does not exist anymore but his blog posts are still available thanks to archived.org.

\n\n

CQRS is the separation of command and query into two different objects instead of only one. MapService does not follow the CQRS pattern because it has a query and a command. We need to cut this object in half.

\n\n
interface MapReadService {\n    addMarkerToTheMap(label: string, latitude: number, longitude: number); void\n}\n\ninterface MapWriteService {\n    findAllMarkersCloseToLocation(): Marker[]\n}\n
\n\n

That’s pretty simple, right? Anyway, we don’t need to introduce complicated things in our application to use this tactical design pattern. We don’t need a write and a read model,\na command and query bus, an event sourcing architecture or multiple databases. Greg Young published this blog post in 2012 to explain what CQRS was not about.

\n\n
\n

CQRS is not a silver bullet

\n\n

CQRS is not a top level architecture

\n\n

CQRS is not new

\n\n

CQRS is not shiny

\n\n

CQRS will not make your jump shot any better

\n\n

CQRS is not intrinsically linked to DDD

\n\n

CQRS is not Event Sourcing

\n\n

CQRS does not require a message bus

\n\n

CQRS is not a guiding principle / CQS is

\n\n

CQRS is not a good wife

\n\n

CQRS is learnable in 5 minutes

\n\n

CQRS is a small tactical pattern

\n\n

CQRS can open many doors.

\n
\n\n

Note: This blog does not exist anymore but it has been archived by archived.org. The post is available here

\n\n

Depending on the number of use cases the service classes can become really huge. CQRS helps to decrease their size but I am a big fan of them. I like to separate each use case into a dedicated class.

\n\n

I’ve written a blog post to explain what is a commands and we can apply it to query too:

\n\n
\n \n \n \"Command\n \n \n Command and command handler design pattern\n \n \n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/what-is-the-difference-between-cqs-and-cqrs-patterns.html","relative_path":"_posts/2023-02-06-what-is-the-difference-between-cqs-and-cqrs-patterns.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"How to reduce coupling in your React app","description":"The dependency inversion principle is a great design pattern, it makes applications more modular and easier to test. A React Context can help to implement this pattern in a React application. Learn how in this new blog article.","date":"2023-03-06 00:00:00 -0600","image":"how-to-reduce-coupling-in-your-react-app.webp","alt":"How to reduce coupling in your React app","image_credit":"diana_pole","keywords":"react,dependency injection,dependency inversion,typescript,coupling,software,design pattern","tags":["react","design-patterns"],"slug":"how-to-reduce-coupling-in-your-react-app","ext":".md","excerpt":"

Today, I would like to cover dependency injection in React. I worked with several frameworks using tools to build and inject dependencies. It is pretty convenient if you apply the dependency inversion principle because you can easily change a dependency with another one.

\n","content":"

Today, I would like to cover dependency injection in React. I worked with several frameworks using tools to build and inject dependencies. It is pretty convenient if you apply the dependency inversion principle because you can easily change a dependency with another one.

\n\n

I will start by briefly introducing what is a React Context and I will then show you how to solve coupling problems in a React application.

\n\n

What is a React Context?

\n\n
\n

Context provides a way to pass data through the component tree without having to pass props down manually at every level.

\n\n

React documentation

\n
\n\n

Let’s take an example: several components display the username of the user who is connected. We have to pass the username as props to every application component that needs this information. It is annoying, but React context can help for this specific use case.

\n\n

First, we need to create a context:

\n\n

```ts self-taught\nconst UserContext = React.createContext();

\n
\nThen, we need to wrap our components using a context provider and give it a value. The value is the data we want to share with the provider’s children components.\n\n```tsx\nfunction App() {\n    return (\n        <UserContext.Provider value={'arn0'}>\n            <Toolbar />\n            <OtherComponent />\n        </UserContext.Provider>\n    );\n}\n
\n\n

Finally, we can get this value (the username) from the context thanks to the useContext hooks.

\n\n
function Toolbar() {\n    const username = useContext(UserContext);\n\n    return (\n        <div>\n            Welcome {username}\n        </div>\n    );\n}\n\n
\n

Which problems coupling brings?

\n\n
\n

Coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.

\n\n

Wikipedia

\n
\n\n

The developer’s worst enemy is coupling because it makes your code less testable. To illustrate what I am saying we will take an example: a to-do list application. The TodoList component is responsible for retrieving data from the server and building the list of tasks to do.

\n\n
const findTasks = async () => {\n    return await axios.get('/tasks');\n}\n\nfunction TodoList() {\n    const [tasks, setTasks] = useState<Task[]>([]);\n\n    useEffect(() => {\n        (async () => {\n            const response = await findTasks();\n            setTasks(response.data);\n        })();\n    }, []);\n    \n    return (\n        <ul>\n            {tasks.map((task: Task) => <li key={task.id}>{task.label}</li>)}\n        </ul>\n    );\n}\n
\n\n

The problem with the TodoList component is that it depends on the axios library to get data from the server. It does not ease testing because we need to set up the server to make this component work. Unit testing requires a short feedback loop! We need to find a way to get rid of this HTTP call. It would be great to be able to do HTTP calls in production but using stub for testing.

\n\n

How React Context reduces coupling?

\n\n

The problem with the TodoList component is that we should be able to use several implementations of the findTasks, but we can’t with its design. We need an implementation for the production that will make an HTTP call and another one for testing that will return stub.

\n\n

The findTasks function should not be hardcoded but it should be injected as a component dependency. A React Context will help us to solve that issue.

\n\n
type ServiceContainer = {findTasks: () => Promise<Task>};\n\nconst ContainerContext = React.createContext<ServiceContainer>({} as ServiceContainer);\n\nexport const useServiceContainer = () => useContext(ContainerContext);\n\nconst findTasks = async () => {\n    return await axios.get('/tasks');\n}\n\nfunction App() {\n    return (\n        <ContainerContext.Provider value={findTasks}>\n            <TodoList/>\n        </ContainerContext.Provider>\n    );\n}\n
\n\n

The ServiceContainer type represents all services we want to register in our application. The ContainerContext will share those services with ContainerContext.Provider children.

\n\n

Then, we only need to get the findTasks function from the React Context.

\n\n
function TodoList() {\n    const {findTasks} = useServiceContainer();\n    const [tasks, setTasks] = useState<Task[]>([]);\n\n    useEffect(() => {\n        (async () => {\n           const response = await findTasks();\n           setTasks(response.data);\n        })();\n    }, []);\n\n    return (\n        <ul>\n            {tasks.map((task: Task) => <li key={task.id}>{task.label}</li>)}\n        </ul>\n    );\n}\n
\n\n

Now, the code is testable because we can easily replace the findTasks by stub in the test suite. We can easily set up a test because this new function does not use HTTP calls.

\n\n
it('render the todo list', () => {\n    render(\n        <ContainerContext.Provider value={\n            { findTasks: () => ({id: 1, label: 'label'}) }\n        }>\n            <TodoList/>\n        </ContainerContext.Provider>\n    )\n\n    // …\n});\n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/how-to-reduce-coupling-in-your-react-app.html","relative_path":"_posts/2023-03-06-how-to-reduce-coupling-in-your-react-app.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"How to use custom React hook to increase application testability","description":"Sometimes, we depend on libraries that provide components which cannot be well rendered in the test environment. That means we cannot test some parts of an application. Learn how to use a React hook to prevent that problem and increase the application testability in this new blog article.","date":"2023-04-04 00:00:00 -0500","image":"how-to-use-custom-react-hook-to-increase-application-testability.webp","alt":"How to use custom React hook to increase application testability","image_credit":"joetography","keywords":"react,reactjs,hook,javascript,typescript,coupling,software,testing","tags":["react","testing"],"slug":"how-to-use-custom-react-hook-to-increase-application-testability","ext":".md","excerpt":"

In my previous blog, I spoke about reducing coupling in a React app to improve testing. Now I will show you how a custom React hook can increase testability.

\n","content":"

In my previous blog, I spoke about reducing coupling in a React app to improve testing. Now I will show you how a custom React hook can increase testability.

\n\n

Note: I assume that you are comfortable with React hooks. If you aren’t, please have a look at the React documentation

\n\n

First of all, I will show you some code that is not testable. In my side project, I use react-map-gl to create maps with Mapbox. Unfortunately, I can’t render the map with the testing library because this library only works in a web browser. I might have done something wrong but I haven’t found any solution to solve this problem.

\n\n
export function MapPage() {\n   const {mapId} = useParams<{ mapId: string }>();\n   const [markers, setMarkers] = useState([]);\n   const [isMarkerOpened, setIsMarkerOpened] = useState(false);\n\n\n   useEffect(() => {\n       setMarkers(getMarkers(mapId));\n   }, [mapId]);\n\n\n   const openMarkerPopup = () => setIsMarkerOpened(true);\n   const closeMarkerPopup = () => setIsMarkerOpened(false);\n\n\n   return (\n       <>\n           <ReactMapGL>\n               {markers.map(\n                   (marker) => <Marker\n                       longitude={marker.longitude}\n                       latitude={marker.latitude}\n                   >\n                       <MarkerIcon onClick={openMarkerPopup} />\n                   </Marker>\n               )}\n           </ReactMapGL>\n           <MarkerPopup isOpened={isMarkerOpened} onClose={closeMarkerPopup} />\n       </>\n   )\n}\n
\n\n

MapPage is in charge of loading map data depending on the mapId and rendering a map with its markers. I can’t test the MapBoard component because the ReactMapGL component can’t be rendered through the test tooling. That’s sad because I still want to check if I can open the marker popup when a user clicks on a marker.

\n\n

React will help us to fix this issue! We need to refactor this component to extract the business logic into a hook. This way, the component will only be responsible for rendering things. Let’s begin by creating the hooks.

\n\n
export function useMapPage(mapId, {defaultIsMarkerOpened} = {defaultIsMarkerOpened: false}) {\n   const [markers, setMarkers] = useState([]);\n   const [isMarkerOpened, setIsMarkerOpened] = useState(defaultIsMarkerOpened);\n\n\n   useEffect(() => {\n       setMarkers(getMarkers(mapId));\n   }, [mapId]);\n\n\n   const openMarkerPopup = () => setIsMarkerOpened(true);\n   const closeMarkerPopup = () => setIsMarkerOpened(false);\n\n\n   return {\n       markers,\n       isMarkerOpened,\n       closeMarkerPopup,\n       openMarkerPopup,\n   }\n}\n
\n

The hook exposes two variables: markers which is an array of map’s markers and isMarkerOpened which is a boolean that indicates if the popup is opened or closed. It exposes two functions, openMarkerPopup and closeMarkerPopup that let us mutate the isMarkerOpened boolean.

\n\n

Note: We could only expose setIsMarkerOpened but I think openMarkerPopup and closeMarkerPopup function names are clearer and match the component logic.

\n\n

Now, we need to call the hook from the MapPage component and it will still work as before.

\n\n
export function MapPage() {\n   const {\n       markers,\n       isMarkerOpened,\n       closeMarkerPopup,\n       openMarkerPopup\n   } = useMapPage(mapId);\n\n\n   return (\n       <>\n           <ReactMapGL>\n               {markers.map(\n                   (marker) => <Marker\n                       longitude={marker.longitude}\n                       latitude={marker.latitude}\n                   >\n                       <MarkerIcon onClick={openMarkerPopup} />\n                   </Marker>\n               )}\n           </ReactMapGL>\n           <MarkerPopup isOpened={isMarkerOpened} onClose={closeMarkerPopup} />\n       </>\n   )\n}\n
\n\n

The MapPage is still untestable but we can start testing the hook to ensure hook logic matches business expectations. We can test if we can open a marker’s popup. That’s great because the testing library provides the renderHook helper that eases the hook testing.

\n\n

Note: If you want to know how renderHook works you should have a look at this blog post written by Kent C. Dodds.

\n\n
describe('Map Page', () => {\n   test('should open the marker popup', async () => {\n       const { result } = renderHook(() => useMapPage(\n           'mapId', {defaultIsMarkerOpened: false}\n       ));\n       \n       act(() => result.current.openMarkerPopup());\n       \n       expect(result.current.isMarkerOpened).toEqual(true);\n   });\n\n\n   test('should close the marker popup', async () => {\n       const { result } = renderHook(() => useMapPage(\n           'mapId', {defaultIsMarkerOpened: true}\n       ));\n       \n       act(() => result.current.closeMarkerPopup());\n\n       expect(result.current.isMarkerOpened).toEqual(false);\n   });\n});\n
\n\n

As I said at the beginning of this blog post I wrote a blog post to explain how to reduce coupling in a React application. Please, have a look at this blog post to understand how to make a dependency injection system.

\n\n

Now, we need to remove the getMarkers function call from the hooks if we want to test the map data loading. We don’t want to trigger side effects like HTTP calls in the unit test suite because we want to have the shortest feedback loop. We will get the getMarkers function to useServiceContainer which is a hook that provides any services.

\n\n
export function useMapPage(mapId, {defaultIsMarkerOpened} = {defaultIsMarkerOpened: false}) {\n   const {getMarkers} = useServiceContainer();\n   // ...\n  \n   useEffect(() => {\n       setMarkers(getMarkers(mapId));\n   }, [mapId]);\n   // ...\n}\n
\n\n

By default, the useServiceContainer hooks return the production services, we will need to replace the getMarkers service with a fake service for testing purposes. The useServiceContainer hooks can’t work without a React Provider. I like to create a factory that wraps components I test with all needed providers. It avoids a lot of noise in the test suites and makes tests more readable.

\n\n
export const createWrapper = (serviceContainer) => function Wrapper(\n   { children }: { children: ReactElement },\n) {\n   return (\n       <ContainerContext.Provider value={serviceContainer}>\n           {children}\n       </ContainerContext.Provider>\n   );\n};\n
\n\n

Note: the factory has a parameter which is the service container. It will let us define the services we want to override for testing.

\n\n

The renderHook has a wrapper option that lets you define the component that will wrap the hook you are testing. We will use the createWrapper factory to wrap the hook into the ContainerContext provider and we create a fake getMarkers service.

\n\n
describe('Map Page', () => {\n   test('should load the markers of the map', async () => {\n       const markers = [{id: 'makerId'}];\n       const { result } = renderHook(\n           () => useMapPage('mapId'),\n           {wrapper: createWrapper({getMarkers: () => markers})}\n       );\n       \n       expect(result.current.markers).toEqual(markers);\n   });\n});\n
\n\n

Now, the getMarkers is predictable. That means we can test the map loading because the getMarker function will return [{id: 'makerId'}] every time.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/how-to-use-custom-react-hook-to-increase-application-testability.html","relative_path":"_posts/2023-04-04-how-to-use-custom-react-hook-to-increase-application-testability.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Use composition instead of props drilling","description":"Adding too many props will make your components complex, hard to understand and maintain. Instead opt for several small components and apply composition. Learn how in this blog article.","date":"2023-05-22 00:00:00 -0500","image":"use-composition-instead-of-props-drilling.webp","alt":"Use composition instead of props drilling","image_credit":"xavi_cabrera","keywords":"react,reactjs,composition,javascript,typescript","tags":["react","testing"],"slug":"use-composition-instead-of-props-drilling","ext":".md","excerpt":"

In this blog post, I would like to speak about how composition can improve your React codebase. It’s easy to add a lot of props to your component to make them configurable but it’s not a good idea.

\n","content":"

In this blog post, I would like to speak about how composition can improve your React codebase. It’s easy to add a lot of props to your component to make them configurable but it’s not a good idea.

\n\n

Let’s take an example. You are working on an e-Commerce webshop. A ProductList is used in the shop and the shop administration displays a list of products. In the shop administration, the component displays the product information and some calls to action (like product deletion and categorization for example) to manage products. In the shop you only need to display the product information, so, you don’t want to display the calls to action.

\n\n

As we can see in the next example, most of the ProductList props are used to render and configure the checkbox or the button.

\n\n
export function ProductList({\n products,\n displayCheckbox,\n displayAction,\n actionLabel,\n onCheckboxClick,\n onActionClick,\n}) {\n return (\n   <ul>\n     {products.map(product => (\n       <li>\n         {displayCheckbox &&\n           <input type=\"checkbox\" onclick={onCheckboxClick} /> : null}\n         {product.label}\n         {displayAction &&\n           <button onclick={onActionClick}>{actionLabel}</button> : null}\n       </li>\n     )}\n   </ul>\n );\n}\n\n\n
\n\n

This component is used in the AdminShopand Shop pages to display the product list to the customer or the shop owner.

\n\n
// Display to shop owner\nexport function AdminShop() {\n const [products, setProducts] = useState([]);\n\n\n useEffect(() => {\n   setProducts(getAllProducts())\n }, []);\n\n\n return (\n   <ProductList\n     products={products}\n     displayCheckbox={true}\n     displayAction={true}\n     actionLabel=\"delete\"\n     onCheckboxClick={/* callback */}\n     onActionClick={/* callback */}\n   />\n );\n}\n\n\n// Display to customers\nexport function Shop() {\n const [products, setProducts] = useState([]);\n\n\n useEffect(() => {\n   setProducts(getProductsAvailableforSale())\n }, []);\n\n\n return (\n   <ProductList\n     products={products}\n     displayCheckbox={false}\n     displayAction={false}\n   />\n\n\n );\n}\n
\n\n

The ProductList has to display elements depending on the given props. This big component will help mutualize the code but it will introduce complexity. Adding too many props will make your components complex, and hard to understand and maintain. Composition will help us to get rid of those props.

\n\n

Note: The ProductList component only has 3 props because I wanted to keep the example simple but guess what happens when your components have tens of props to configure them?

\n\n

How can composition help us? It’s like playing Lego. You need several bricks from different sizes and colors to create something. The big ProductList component can be split into several small components used to build the product list depending on business cases.

\n\n
export function ProductList({children}) {\n return (\n   <ul>{children}</ul>\n );\n}\n\n\nexport function Product({label, checkbox, action}) {\n return (\n   <li>\n     {checkbox}\n     {label}\n     {action}\n   </li>\n );\n}\n\n\nexport function ProductCheckbox({onClick}) {\n return <input type=\"checkbox\" onClick={onClick}/>;\n}\n\n\nexport function ProductAction({onClick, actionLabel}) {\n return <button onClick={onClick}>{actionLabel}</button>;\n}\n
\n\n

In the previous code example, we created 4 new components: ProductList, Product, ProductCheckbox and ProductAction. They are like Lego bricks and we can assemble them to create the product list with or without the call to action.

\n\n

Note: It’s not mandatory to create a dedicated component for the checkbox and the button. It can be useful to wrap generic components into more business-oriented ones. It helps to make things clearer. It’s another way to apply composition.

\n\n
// Display to shop owner\nexport function AdminShop() {\n const [products, setProducts] = useState([]);\n\n\n useEffect(() => {\n   setProducts(getAllProducts())\n }, []);\n\n\n return (\n   <ProductList>\n     {products.map(product => \n       <Product\n         label={product.label}\n         checkbox={<ProductCheckbox onClick={/* callback */} />}\n         action={<ProductAction onClick={/* callback */} actionLabel={\"delete\"} />}\n       />\n     )}\n   </ProductList>\n );\n}\n\n\n// Display to customers\nexport function Shop() {\n const [products, setProducts] = useState([]);\n\n\n useEffect(() => {\n   setProducts(getProductAvailableforSale())\n }, []);\n\n\n return (\n   <ProductList>\n     {products.map(product => <Product label={product.label} />)}\n   </ProductList>\n );\n}\n
\n\n

Small components are easier to test. They help build more stable applications and are easier to maintain. Your codebase will be less complex to understand. It will decrease your and your teammates’ mental load because you won’t have any components with complex API and logic.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/use-composition-instead-of-props-drilling.html","relative_path":"_posts/2023-05-22-use-composition-instead-of-props-drilling.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Ease testing thanks to the dependency inversion design pattern","description":"The inversion design pattern is quite simple and super powerful. It makes your code more modular. It lets you change a class's dependency to another one depending on the context. It is a good way to decouple your code from IO to make it testable.","date":"2023-06-19 00:00:00 -0500","image":"inversion-dependency/ease-testing-thanks-to-the-dependency-inversion-design-pattern.webp","alt":"Ease testing thanks to the dependency inversion design pattern","image_credit":"mmayyer","keywords":"unit test,design pattern,pattern,software,dependency inversion,dependency injection,test,typescript","tags":["testing","design-pattern","OOP"],"slug":"ease-testing-thanks-to-the-dependency-inversion-design-pattern","ext":".md","excerpt":"

In this new blog post, I would like to speak about the dependency inversion design pattern. This pattern makes your code more modular and helps to improve codebase testability. It’s quite simple and super powerful.

\n

What does this design pattern say?

\n

A class should not depend on another one to avoid coupling them together. If a class is coupled with another one, it means you won’t be able to use the first one without the second one.

\n","content":"

In this new blog post, I would like to speak about the dependency inversion design pattern. This pattern makes your code more modular and helps to improve codebase testability. It’s quite simple and super powerful.

\n

What does this design pattern say?

\n

A class should not depend on another one to avoid coupling them together. If a class is coupled with another one, it means you won’t be able to use the first one without the second one.

\n\n

\"Concrete

\n\n

The classes should only depend on abstractions (e.g. interfaces). An interface can be implemented in several ways. It will make your code more modular because you can use a specific implementation depending on the context.

\n\n

\"Concrete

\n\n

The interfaces should not depend on concrete implementations to avoid coupling them to another class.

\n\n

\"Abstraction

\n\n

How does this pattern improve testability?

\n\n

Let’s see with a simple example how dependency inversion helps to make your code easily testable. The following class lets a cartographer add a marker on a map.

\n\n

Note: I wrote an article about unit testing to help you to understand the main mistakes that make your codebase less testable. Here is the link https://arnolanglade.github.io/why-unit-testing-can-be-hard.html.

\n\n
class AddMarkerToMap {\n  execute(marker) {\n    const repository = PosgresqlMaps.getInstance()\n    \n    const map = repository.get(marker.mapId)\n    \n    map.addMarker(\n      marker.name,\n      marker.longitude,\n      marker.latitude,\n    )\n\n    repository.save(map)\n  }\n}\n
\n\n

This class uses a singleton PosgresqlMaps.getInstance() to retrieve an instance of the PosgresqlMaps repository. This repository is in charge of saving map data into a PostgreSQL database. The problem is that we cannot run this code without a working database. This class is coupled to the PosgresqlMaps repository.

\n\n

We don’t want to use IO (your tools like a database) when we unit-test a piece of code because we want to avoid setting up any tools to a short feedback loop. We only want to check if a section of the application behaves as expected. We don’t want to test if the map data is well stored.

\n\n

Using the dependency inversion pattern will help us to remove the coupling between AddMarkerToMap and PosgresqlMaps and make it easy to unit test.

\n\n

First, we need to remove the coupling between both classes. We will create an abstraction to define how to retrieve and save maps in the application.

\n\n
interface Maps {\n  get(mapId: MapId): Promise<Map>;\n  save(map: Map);\n}\n
\n\n

Note: When I cannot use a business term to name a repository I pluralize the name of my aggregate to name it. That’s why I name it Maps because I want to handle map aggregate persistence.

\n\n

Now, we can create as many implementations as we need. We will create a dedicated implementation for testing purposes. It will only keep it in memory which will avoid using a database.

\n\n
class InMemoryMaps implements Maps {\n  private maps: Record<MapId, Map>;\n  \n  async get(mapId: MapId): Promise<Map> {\n    return this.maps[mapId];\n  }\n\n  async save(map: Map): Promise<void> {\n    this.maps[map.id()] = map;\n  }\n}\n
\n\n

Note: I name all implementations with a prefix depending on what they are. If a repository uses a database, I will prefix the class with the name of the database. When I create an implementation for testing purposes, I use the InMemory prefix.

\n\n

As we want to create a working application, we will create an implementation which uses a database for the production environment.

\n\n
class PosgresqlMaps implements Maps {\n  // …\n  async get(mapId: MapId): Promise<Map> {\n    const map = await this.client.query(\n      `SELECT * FROM maps WHERE id = ${mapId}`,\n    );\n\n\n    return new Map(map);\n  }\n  \n  async save(map: Map): Promise<void> {\n    await this.client.query(\n      `INSERT INTO maps VALUES (${map.toState()})`\n    );\n  }\n}\n
\n\n

We need to refactor a bit the AddMarkerToMap class to be able to inject an implementation of the Maps interface.

\n\n
class AddMarkerToMap {\n  constructor(private maps: Maps) {}\n  \n  execute(marker) {\n    const map = this.maps.get(marker.mapId)\n\n\n    map.addMarker(\n      marker.name, marker.latitude, marker.longitude\n    )\n    \n    this.maps.save(map)\n  }\n}\n
\n\n

Finally, we can test this class because we can instantiate the AddMarkerToMap class with the InMemoryMaps class. This implementation helps us to test this class because it does not use any IO. Here, we don’t want to test if the data are well persisted but we want to test the business logic of marker addition on a map.

\n\n
it('adds a new marker to the map', () => {\n  const maps = InMemoryMaps()\n  \n  new AddMarkerToMap(maps).execute({\n    mapId: 'mapId', name: 'Le Sunset',\n    latitude: 23.252353245, longitude: 43.5432563457\n  })\n  \n  expect(maps.get('mapId')).toEqual(\n    new Map(\n      new Marker('Le Sunset', 23.252353245, 43.5432563457)\n    )\n  )\n})\n
\n\n

Note: We don’t use a unit test to ensure the application uses its tools well. We use integration tests for this. For instance, if we want to ensure that a repository works as expected.

\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html","relative_path":"_posts/2023-06-19-ease-testing-thanks-to-the-dependency-inversion-design-pattern.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Don’t test private methods","description":"One of the first mistakes I made when I started to test my code was to test private methods. Spoiler alert: it was a bad idea! If you need to test a private method, it probably means that your code is not well designed. Private methods are implementation details of objects and we should not care about them. When you test public methods you also test the private ones.","date":"2023-07-17 00:00:00 -0500","image":"do-not-test-private-method/do-not-test-private-methods.webp","alt":"Don’t test private methods","image_credit":"dtopkin1","keywords":"unit test,design pattern,pattern,software,private method,single responsibility principle,test","tags":["testing","OOP"],"slug":"do-not-test-private-methods","ext":".md","excerpt":"

It is pretty easy to make mistakes when you start testing your code. One of the first mistakes I made was to test private methods. Spoiler alert: it was a bad idea because I had to use reflection to make them public to access them. If you need to test a private method, it probably means that your code is not well designed

\n","content":"

It is pretty easy to make mistakes when you start testing your code. One of the first mistakes I made was to test private methods. Spoiler alert: it was a bad idea because I had to use reflection to make them public to access them. If you need to test a private method, it probably means that your code is not well designed

\n\n

We don’t test private methods. Private methods are implementation details of objects and we should not care about them. Don’t worry! They are tested in the end. When you test public methods you also test the private ones as described in the next schema.

\n\n

\"Test

\n\n

I needed to test the private methods because my object was a God object (huge object). It did a lot of things. It had a few public methods and a lot of private ones because too many things happened behind the scenes.

\n\n

\"Object

\n\n

The problem with this design is this object did not follow the Single Responsibility Principle, but what is this principle?

\n\n
\n

There should never be more than one reason for a class to change. In other words, every class should have only one responsibility

\n\n

wikipedia

\n
\n\n

My object was super huge because it did too many things. It had too many responsibilities. Because of that, I could not test it easily. How can we avoid that?

\n\n

\"complicated

\n\n

It’s better to work on small problems than a big one. The solution would have been to identify each responsibility to extract them into dedicated objects. We don’t need magic tricks to test small objects. It is simple to test them because they do a simple thing, and we only need to use their public API (public method) to test them. We don’t need reflection anymore.

\n\n

\"split

\n\n

Then, we need to apply the composition pattern to assemble those classes to make them work as the God object. Composition is like playing Lego: we have many small bricks, and we put them together to make a big piece. Software is the same. You should work with small classes/functions to easily test them and piece them together to make your feature.

\n\n

Let’s take an example. The following class is in charge of importing products into an application as a PIM or an ERP. This class does several things, it gets product data from a CSV file and it imports them into a database. We need to test the whole class to ensure the product import works as expected. That’s a bit annoying because I can’t test the CSV file reading or the production saving.

\n\n
type Product = {\n  name: string\n  description: string\n};\n\nclass ProductImport {\n  constructor(private connection: Connection) {}\n    \n  async import(filePath: string): Promise<void> {\n    await this.loadProductFromCsvFile(filePath);\n  }\n  \n  private async loadProductFromCsvFile(file: string): Promise<void> {\n    const csvData: Product[] = [];\n    createReadStream(file)\n      .pipe(csvParser())\n      .on('data', (product: Product) => csvData.push(product))\n      .on('end', async () => {\n        for (const data of csvData) {\n          await this.saveProducts(data);\n        }\n      });\n  }\n\n  private async saveProducts(product: Product): Promise<void> {\n    await this.connection.execute(\n      'INSERT INTO products (name, description) VALUES (?, ?)',\n      [product.name, product.description],\n    );\n  }\n}\n
\n\n

We need to split this class into smaller ones to ease testing. We will extract both private methods into dedicated classes.

\n\n
class CsvProductLoader {\n  async loadProduct(file: string): Promise<Product[]> {\n    const products: Product[] = [];\n    createReadStream(file)\n      .pipe(csvParser())\n      .on('data', (product: Product) => products.push(product));\n    \n    return products;\n  }\n}\n\nclass MysqlProducts {\n  constructor(private connection: Connection) {}\n    \n  async save(product: Product): Promise<void> {\n    await this.connection.execute(\n      'INSERT INTO products (name, description) VALUES (?, ?)',\n      [product.name, product.description],\n    );\n  }\n}\n
\n

Now, we can test them stand-alone because these classes expose public methods. We don’t need a magic trick such as reflection to change their visibility to test them.

\n\n

We still need the ProductImport class. It will depend on both previous classes and act as a controller. It asks CsvProductLoader to get the product information from the CSV file and asks CsvProductLoader to save them into a database.

\n\n
class ProductImport {\n  constructor(\n    private productLoader: CsvProductLoader,\n    private products: MysqlProducts,\n  ) {}\n    \n  async import(filePath: string): Promise<void> {\n    const products = await this.productLoader.loadProduct(filePath);\n    products.forEach((product: Product) => this.products.save(product));\n  }\n}\n
\n\n

That’s great because we extract IO usage into new classes. Both MysqlProducts and CsvProductLoader need to be tested with integration/contract tests since ProductImport can be unit tested.

\n\n

We need to make a last change. We cannot rely on concrete classes. We need to introduce interfaces to avoid coupling between ProductImport and its dependencies (MysqlProducts and CsvProductLoader).

\n\n
interface ProductLoader {\n  loadProduct(file: string): Promise<Product[]>\n}\n\ninterface Products {\n  save(product: Product): Promise<void>\n}\n\nclass ProductImport {\n  constructor(\n    private productLoader: ProductLoader,\n    private products: Products,\n  ) {}\n}\n
\n\n

Note: I’ve written an article about how the inversion dependency design pattern will ease testing. Here is the link:

\n\n
\n \n \n \"Ease\n \n \n Ease testing thanks to the dependency inversion design pattern\n \n \n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/do-not-test-private-methods.html","relative_path":"_posts/2023-07-17-do-not-test-private-methods.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Why breaking encapsulation is not a good idea","description":"This principle restricts direct access to the state of the object from outside. This means that the internal implementation details of a class are hidden. Accessing the state of the object is only allowed through its public API (public methods). This concept helps to protect the data from outside interference and ensures controlled and secure data manipulation.","date":"2023-09-19 00:00:00 -0500","image":"why-breaking-encapsulation-is-not-a-good-idea/why-breaking-encapsulation-is-not-a-good-idea.webp","alt":"Why breaking encapsulation is not a good idea","image_credit":"mattseymour","keywords":"oop,encapsulation,object,tell don’t ask,object","tags":["testing","OOP"],"slug":"why-breaking-encapsulation-is-not-a-good-idea","ext":".md","excerpt":"

In this blog post, I would like to speak about an important concept in Oriented Object Programming which is the encapsulation principle.

\n","content":"

In this blog post, I would like to speak about an important concept in Oriented Object Programming which is the encapsulation principle.

\n\n

Before speaking about encapsulation let’s talk a bit about OOP. What is the object’s life cycle? The first step of the object’s life cycle is to be instantiated. We give everything an object needs to initialise its internal state. Then we use its public API (public methods) to communicate with it. An object exposes a public API (behaviour) that manipulates its internal state (data).

\n\n

\"Object

\n\n

So, what is encapsulation? This principle restricts direct access to the state of the object from outside. This means that the internal implementation details of a class are hidden. Accessing the state of the object is only allowed through its public API (public methods). This concept helps to protect the data from outside interference and ensures controlled and secured data manipulation.

\n\n

Note: An object that only has getters and setters is not an object! This is a data structure because it has no behaviour.

\n\n

I worked on many applications that used getters and setters. They are good examples of what is breaking encapsulation. It is easy to break encapsulation but it is not a good idea. It will make your code less maintainable and your applications less evolutive. Let’s take a simple example to understand why breaking encapsulation is a bad idea. I want to find the closest point of interest on a map close to a given location.

\n\n
type Location = {\n  latitude: number\n  longitude: number\n}\n\n\ntype PointOfInterest = {\n  name: string\n  location: Location\n}\n\nclass Map {\n  constructor(private pointOfInterests: PointOfInterest[]) {}\n\n\n  getPointOfInterests(): PointOfInterest[] {\n    return this.pointOfInterests\n  }\n}\n\nclass AClassWhereWeNeedToFindClosestPOI {\n  doSomething(map: Map) {\n    const pointOfInterest = map.getPointOfInterests()\n      .filter((pointOfInterest: PointOfInterest) => {\n        // ...\n      })[0]\n    // ...\n  }\n}\n
\n\n

The Map class has a getPointOfInterest getter that gets the class property with the same name. Then we can use this getter to access the list of points of interest to iterate them and find the closest one.

\n\n

The drawback with this getter is that we will need to copy/paste this piece of code if we have to look for the closest point of interest in several places. It won’t help you to mutualize code. At best, you can extract this piece of code into a dedicated class like the following example:

\n\n
class POIFinder {\n  find(map: Map): PointOfInterest {\n    return map.getPointOfInterests()\n      .filter((pointOfInterest: PointOfInterest) => {\n        // ...\n      })[0]\n  }\n}\n
\n\n

The problem with this code is that we extract the Map object behaviour into another class. We will turn the Map object into a data structure if we remove all methods that add a behaviour to it.

\n\n

Note: A class that ends with -ER (like in the previous example) is a good insight into how this class does the job of another class.

\n\n

What happens if we need to change the internal of the POI list? Now, we don’t want to use an array anymore, we want to manage the POI list with a custom class named PointOfInterestList. It might be a simple refactoring for small applications but it is super painful for huge ones. If the getter method is used hundreds of times, we will have to refactor each getPointOfInterest usage to make them compatible with the new signature.

\n\n

To avoid this problem, we only need to apply the “Tell, don’t ask” principle. This principle says that we should tell an object to do something instead of asking for its internal state to do something in his stead.

\n\n

The solution would be to add a findClosestPointOfInterest method to the Map object. The only purpose of this method is to find the closest POI no matter how the POI list is designed. This allows you to refactor the internal state of the object as many times you want.

\n\n
class ListOfPointOfInterest {\n  findClosest(location: Location) {\n    // ...\n  }\n}\n\nclass Map {\n  constructor(private pointOfInterests: ListOfPointOfInterest) {}\n\n\n  findClosestPointOfInterest(location: Location): PointOfInterest {\n    return this.pointOfInterests.findClosest(location)\n  }\n}\n
\n\n

Note: Breaking encapsulation to test your code is a bad idea too. I’ve written an article to present you with an alternative to the getter to prevent exposing the state of the objects. Here is the link:

\n\n
\n \n \n \"Why\n \n \n Why you should not expose objects' state to test them\n \n \n
\n\n

Thanks to my proofreader @LaureBrosseau.

\n","url":"/why-breaking-encapsulation-is-not-a-good-idea.html","relative_path":"_posts/2023-09-19-why-breaking-encapsulation-is-not-a-good-idea.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"The pitfalls of OOP's inheritance: Why simple isn't always better","description":"Discover the complexities of excessive inheritance in object-oriented programming (OOP) and understand why careful consideration is crucial to avoid potential problems and pitfalls.","date":"2023-10-23 00:00:00 -0500","image":"pitfalls-of-oop-inheritance/pitfalls-of-oop-inheritance.webp","alt":"The pitfalls of OOP's inheritance: Why simple isn't always better","image_credit":"gabrielsanchez","keywords":"OOP,OOP inheritance,OOP principles,composition,Open-Closed principle,OOP best practices,coding tips","tags":["OOP"],"slug":"oop-inheritance-pitfalls","ext":".md","excerpt":"

In OOP, the simplest way to change the behavior of a class A is to create a class B that extends class A. Extensions allow you to override any public and protected methods of the parent class. That‘s quite simple, right?

\n","content":"

In OOP, the simplest way to change the behavior of a class A is to create a class B that extends class A. Extensions allow you to override any public and protected methods of the parent class. That‘s quite simple, right?

\n\n

\"Simple

\n\n

Furthermore, you can extend a class multiple times with several levels of inheritance. In the following example, we can see that class B has two children, and the class hierarchy has four levels of inheritance. Now let’s explore why it is not a good idea and which problem can occur?

\n\n

\"Object

\n\n

Designing code like this won’t facilitate refactoring. Let’s consider a scenario where Class A has a method that is overridden in both Class B and Class E. What happens if we decide to change the signature of this method in Class A? We will need to rewrite this method in Class B and Class E to match the new signature. Another frustrating aspect is that we will have to modify all portions of the code that use this method. In a small codebase, this may be manageable, but in a large one, it’s a different story!

\n\n

\"Refactoring

\n\n

This code won’t ease team collaboration. Let’s consider another scenario: where we are working on a huge monolith shared with several other teams. What happens if team A needs to change class A? That means teams B, C, and D must also update their codebases. We have introduced coupling between these three teams because of the coupling between classes A, B, C, and D. That’s a shame. This design will slow down your delivery because team A will need to coordinate with three other teams if it needs to change class A.

\n\n

\"Refactoring

\n\n

I have worked on several codebases that heavily relied on inheritance, but now I barely use it due to the drawbacks I’ve described. Instead, I prefer to use composition. It is better to work with several small classes and assemble them, it’s like playing with Lego blocks. Moreover, it greatly simplifies testing.

\n\n

I try to apply the open-closed principle as much as possible to enhance code modularity and facilitate evolution. In a related blog post, I explain the principle and provide an example to illustrate how to refactor code that doesn’t follow this principle. Here is the link:

\n\n
\n \n \n \"Open-Closed\n \n \n Open-Closed principle: Enhancing code modularity\n \n \n
\n\n","url":"/oop-inheritance-pitfalls.html","relative_path":"_posts/2023-10-23-oop-inheritance-pitfalls.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Open-Closed principle: Enhancing code modularity","description":"Unlock the potential of the Open-Closed Principle in programming. Discover how to enhance code modularity and simplify maintenance using this SOLID concept. Learn to reduce complexity and write more flexible code.","date":"2023-11-13 00:00:00 -0600","image":"open-close-principle.webp","alt":"Open-Closed principle: Enhancing code modularity","image_credit":"madze","keywords":"open-closed principle,SOLID principles,software engineering,design patterns,strategy pattern,object-oriented programming,programming principles,development best practices","tags":["OOP","SOLID"],"slug":"open-close-principle","ext":".md","excerpt":"

Have you missed my last blog post about the pitfalls of inheritance? I explain how it could be a bad idea to use it too much. Applying composition prevents this problem; it is better to work with small classes to easily assemble. In this blog post, I will talk about the open-closed principle. This principle facilitates composition and helps avoid relying too much on inheritance.

\n","content":"

Have you missed my last blog post about the pitfalls of inheritance? I explain how it could be a bad idea to use it too much. Applying composition prevents this problem; it is better to work with small classes to easily assemble. In this blog post, I will talk about the open-closed principle. This principle facilitates composition and helps avoid relying too much on inheritance.

\n\n

This principle is one of the SOLID principles, and I think it is super important because it allows you to write more flexible code. I wanted to explain it because its definition is quite simple, but it is not necessarily easy to grasp.

\n\n
\n

The open closed principle states “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”; that is, such an entity can allow its behaviour to be extended without modifying its source code.

\n\n

Wikipedia

\n
\n\n

The first time I read the definition of this principle, I understood that I should not have to modify my code to add additional behavior. This part of the definition “open for extension” was a bit confusing. What did it mean? Does it refer to OOP inheritance? No, it doesn’t refer to OOP inheritance. I have written a blog post about OOP inheritance. It explains why extending a class to change its behavior may seem simple, but is it a good idea? It introduces a lot of coupling in your codebase and between your team.

\n\n

Before digging into the principle, let’s consider a scenario to illustrate the following example: a class called ‘DiscountCalculator’ is in charge of calculating discounts based on the products in the basket. We apply a 20% discount to products with the category ‘sport,’ a 50% discount to products with the category ‘home,’ and a 10% discount to products with the category ‘food.

\n\n
class Product {\n   constructor(\n       public name: string,\n       public category: string,\n       public price: number\n   ) {}\n}\n\nclass Basket {\n   constructor(public products: Product[]) {}\n}\n\nclass DiscountCalculator {\n   calculate(basket: Basket): number {\n       let totalDiscount = 0;\n\n\n       for (const product of basket.products) {\n           switch (product.category) {\n               case 'sport':\n                   totalDiscount += product.price * 0.2; // 20% discount\n                   break;\n               case 'home':\n                   totalDiscount += product.price * 0.5; // 50% discount\n                   break;\n               case 'food':\n                   totalDiscount += product.price * 0.1; // 10% discount\n                   break;\n           }\n       }\n       \n       return totalDiscount;\n   }\n}\n\n// Example usage:\nit.each([\n   ['Football', 'sport', 100, 20],\n   ['Couch', 'home', 200, 100],\n   ['Banana', 'food', 10, 1],\n])('calculates discounts for %s category', (productName, category, price, expectedDiscount) => {\n   const product = new Product(productName, category, price);\n   const basket = new Basket([product]);\n   \n   expect(new DiscountCalculator().calculate(basket)).toBe(expectedDiscount);\n});\n
\n\n

This code does not follow the open-close principle because we need to modify this DiscountCalculator class every time we want to add or remove a discount rule. The problem is thatDiscountCalculator may become really large if the business asks us to add a lot of discount rules. Large objects are hard to understand, so it won’t facilitate its maintenance and testability.

\n\n

Let’s refactor this code to enhance its modularity and align it with the Open-Closed principle. We will use the strategy pattern to rewrite the calculator to remove the hard-coded rules. First, we will introduce a new interface that specifies how a discount works. This interface has two methods: the first one is isApplicable, which determines if a discount can be applied to a product, while the second one calculate calculates the amount of the discount.

\n\n
interface Discount {\n   isApplicable(product: Product): boolean\n   calculate(product: Product): number;\n}\n\nclass SportCategoryDiscount implements Discount {\n   isApplicable(product: Product): boolean {\n       return product.category === 'sport';\n   }\n   \n   calculate(product: Product): number {\n       return product.price * 0.2;\n   }\n}\n\nclass HomeCategoryDiscount implements Discount {\n   isApplicable(product: Product): boolean {\n       return product.category === 'home';\n   }\n   \n   calculate(product: Product): number {\n       return product.price * 0.5;\n   }\n}\n\nclass FoodCategoryDiscount implements Discount {\n   isApplicable(product: Product): boolean {\n       return product.category === 'food';\n   }\n   \n   calculate(product: Product): number {\n       return product.price * 0.1;\n   }\n}\n
\n\n

Then, we need to update the calculator. It will determine whether a discount is applicable to a product and calculate the discount amount. With this approach, you can easily add or remove discount rules as needed.

\n\n
class DiscountCalculator {\n   constructor(private discounts: Discount[]) {}\n    \n   calculateDiscount(basket: Basket): number {\n       let totalDiscount = 0;\n       \n       basket.products.forEach((product) => {\n           this.discounts.forEach((discount) => {\n               if(discount.isApplicable(product)) {\n                   totalDiscount += discount.calculate(product);\n               }\n           });\n       });\n       \n       return totalDiscount;\n   }\n}\n\n// Example usage:\nit.each([\n   ['Football', 'sport', 100, 20],\n   ['Couch', 'home', 200, 100],\n   ['Banana', 'food', 10, 1],\n])('calculates discounts for %s category', (productName, category, price, expectedDiscount) => {\n   const product = new Product(productName, category, price);\n   const basket = new Basket([product]);\n   \n   expect(new DiscountCalculator([\n       new SportCategoryDiscount(),\n       new HomeCategoryDiscount(),\n       new FoodCategoryDiscount(),\n   ]).calculate(basket)).toBe(expectedDiscount);\n});\n
\n\n

We don’t need to over-engineer to apply the open-close principle. With the right design pattern, it is quite simple. Now, the discount calculator is more flexible. We didn’t introduce a lot of new code but we divided the class into smaller ones. Small classes are easier to test and understand, and it will facilitate the maintenance and the evolution of your application.

\n\n","url":"/open-close-principle.html","relative_path":"_posts/2023-11-13-open-close-principle.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"The Mikado Method: Small Steps, Big Improvements","description":"Enhance your codebase with the Mikado Method – a focused approach for incremental improvements without breaking your codebase. Tailored for brownfield development, ensure code stability and effortless feature integration. Collaborate effectively with MikadoApp and achieve rapid code enhancements through Trunk Based Development.","date":"2023-11-27 00:00:00 -0600","image":"mikado-method/mikado-method.webp","alt":"The Mikado Method: Small Steps, Big Improvements","image_credit":"tateisimikito","keywords":"mikado method, refactoring, small steps development, brownfield development, trunk based development, mikado graph, continuous code improvement","tags":["methodology"],"slug":"mikado-method","ext":".md","excerpt":"

In this blog post, I will introduce the Mikado Method. This method helps solve complex problems without breaking your codebase, even if you need to introduce significant changes.

\n","content":"

In this blog post, I will introduce the Mikado Method. This method helps solve complex problems without breaking your codebase, even if you need to introduce significant changes.

\n\n

It is common to work using PR (Pull Request), you can work on your task without breaking your application and disturbing the rest of the team. However, when you start working on a task without maintaining something that works, you end up adding too many changes that are not production-ready. The drawback of this approach is that your PRs will be large and hard to merge.

\n\n

It often happens when you refactor your codebase. You start refactoring something but it breaks another part of this application, then you fix it but it introduces a new problem elsewhere. As a result, you accumulate many changes without being able to merge them.

\n\n

Merging big PR is more complicated than simple changes. First, we need to ask for code reviews, but it can be challenging for your teammate to understand what you did when your PR includes too many things. Then, another drawback is the need to rebase your PR several times due to other PRs being pushed to the main branch.

\n\n

Now, you understand why it’s difficult to introduce big changes in your codebase. It is better to work on small steps that can be mergeable at any time. The Mikado method takes its name from the Mikado game, where the goal is to remove one stick without disturbing the others. The Mikado method has the same philosophy. It aims to make small incremental improvements to a project without breaking the existing codebase. This way, you can push your changes at any time and they won’t break your application even if you did not finish your task.

\n\n

This method simplifies refactoring. You can continuously improve your codebase instead of stacking changes in a huge PR which can’t be merged because the test suites are broken. It’s better to regularly merge small changes that improve your codebase quality. This method is ideal for brownfield development. It enables you to add new features or alter existing ones without breaking the rest of the application. Moreover, it facilitates the improvement of the application’s architecture while allowing the delivery of new features concurrently.

\n\n

How does it work? Let’s take an example: MySQL doesn’t match the project’s needs; we need to use PostgreSQL. First, we need to define a goal that is clear and understandable for everyone. In our case, it is “Migrate the application from MySQL to PostgreSQL,” as you can see in the following example.

\n\n

\"define

\n\n

Note: A goal can be what you want to improve in your application such as refactoring a section of the application to enhance its clarity or improving an existing feature.

\n\n

There are less chances that you can achieve your goal in a single attempt and quickly but we will try to solve it. Based on what we learn in this initial experimentation, we will split a big task (our goal) into smaller ones, which we call prerequisites. As mentioned earlier, this approach prevents ending up with a large pull request that is difficult to merge.

\n\n

To migrate the application to PostgreSQL, we first need to install the database. Then, we need to update our repositories because they use SQL queries specific to MySQL.

\n\n

\"add

\n\n

Now, you will start exploring all the prerequisites. Select a prerequisite from the list and start an experimentation to solve it. If you can easily achieve it, that’s excellent! Commit your changes, mark the prerequisite as completed, and proceed to the next one on the list.

\n\n

\"prerequisite

\n\n

If you cannot easily solve it, you need to revert your changes and define a sublist of prerequisites to achieve the original prerequisite. The purpose is to avoid making big changes but to focus on working on small steps while keeping the codebase stable. Reverting changes may not be natural to a developer, but it’s an important step in the process. It allows you to continue working in smaller steps, while the exploration helps you learn what is necessary to solve a prerequisite.

\n\n

\"add

\n\n

Continue to resolve all prerequisites until the end. When all prerequisites are done, your goal is completed!

\n\n

\"goal

\n\n

As you can see in the previous sections of the blog post, we can represent your progress as a graph. This is a useful way to communicate the progress of your task with the rest of the team. For example, you can show the mikado graph at the daily meeting to easily explain what you did. If, for any reason, you cannot complete your task, you can share the mikado graph with a colleague to explain what you’ve done and what remains to be done. Organizing your work becomes easier, especially when you are working on complex tasks. The Mikado graph is more visual than a simple to-do list because it allows you to see dependencies between prerequisites.

\n\n

I wrote a small application called MikadoApp to easily create and share your Mikado graphs. All the images in the blog posts are screenshots from the application. You can start using it thanks to this link, and you can find the source code on GitHub. Don’t hesitate to contribute to the application to improve it.

\n\n

Since I started using this method, my way of working has changed. I try to break down my work into small steps, and each commit can be pushed into production. If I refactor something, it’s great because I regularly push improvements. If I work on a feature, I can refactor what I need to create my feature without breaking the rest of the application.

\n\n

Now,I like working directly on the main branch, but I ensure that I only push stable commits. That’s what we call Trunk Based Development. This approach allows delivering small improvements to production quickly and frequently. Even though it can be practiced with PRs, I no longer prefer working with them due to the many associated processes that slow down the delivery.

\n","url":"/mikado-method.html","relative_path":"_posts/2023-11-27-mikado-method.md","permalink":null},{"draft":false,"categories":[],"layout":"post","title":"Testing a React application: Secure your tests from internationalization impact","description":"Learn how to prevent test suite breaks caused by translation changes through an innovative solution, ensuring resilience and flexibility in your testing approach.","date":"2023-12-11 00:00:00 -0600","image":"test-strategy-i18n-react-application/test-strategy-i18n-react-application.webp","alt":"Testing a React application: Secure your tests from internationalization impact","image_credit":"claybanks","keywords":"I18n,localization,React-Intl,internationalization,Lokalise,testing,React testing,Jest,React Context,React,Typescript,Javascript","tags":["react","testing"],"slug":"test-strategy-i18n-react-application","ext":".md","excerpt":"

In my previous company, we automated the translation process. We used Lokalise, a cloud-based localization and translation management system. The developers imported all translation keys into the system, while the OPS team was responsible for translating all the keys.

\n","content":"

In my previous company, we automated the translation process. We used Lokalise, a cloud-based localization and translation management system. The developers imported all translation keys into the system, while the OPS team was responsible for translating all the keys.

\n\n

\"translation

\n\n

This process is excellent because you don’t have to wait for translations. As a developer, you add the new translation key and provide the default language. The OPS team is notified when a new key is imported into the tool. They don’t need a developer to provide translations; they are highly autonomous. Afterward, the developers need to pull the translations into the codebase and deploy the application.

\n\n

Let’s consider an example: a React Application that uses the React-Intl as its internationalization system. This library provides a component called FormattedMessage that finds the translation for a given key and locale. This component must be used within a React Context called IntlProvider.

\n\n
const translations = { key: 'translation' };\n\n\n<IntlProvider locale=\"en\" messages={translations}>\n  <FormattedMessage id=\"key\" />\n</IntlProvider>;\n
\n\n

I like wrapping the IntlProvider in a custom provider that allows configuring React Intl for the entire application and provides additional features like locale switching. To keep this example simple, I hardcoded the locale.

\n\n
function AppIntlProvider({ children }: { children: ReactElement }) {\n  const translations = { key: 'translation' };\n \n  return (\n    <IntlProvider\n      messages={translations}\n      locale=\"en\"\n      defaultLocale=\"en\"\n    >\n      {children}\n    </IntlProvider>\n );\n}\n
\n\n

Now let’s go back to the testing problem. The following example is a test that checks if the onClick callback is called when the button with the label “OK” is clicked.`

\n\n
function MyComponent({ onClick }: { onClick: () => void }) {\n  return (\n    <div>\n      // ...\n      <Button onClick={onClick}>\n        <FormattedMessage id=\"validate\" />\n      </Button>\n    </div>\n  );\n}\n\n//const translations = { validate: 'OK' };\n\nit('validate something', () => {\n  const onClick = jest.fn();\n  render(\n    <MyComponent onClick={onClick} />,\n    {\n      wrapper: AppIntlProvider,\n    },\n  );\n \n  userEvent.click(screen.getByText('OK'));\n \n  expect(onClick).toHaveBeenCalled();\n});\n
\n\n

What happens if an OPS changes the translation of the ‘validate’ key from ‘OK’ to ‘GO’ for any reason? Your test will break even if the code and the test have not changed. That is a shame. Should translations break your test suites? I would like to answer this question with a no.\nThe solution that I use to prevent this problem is to override each translation that the test needs. I added an extra prop to the custom React Intl provider called overriddenTranslations that lets me override the translations my test needs.

\n\n
function AppIntlProvider(\n  { children, overriddenTranslations }:\n  { children: ReactElement, overriddenTranslations?: Partial<Translations> },\n) {\n  const translations: Translations = { key: 'translation' };\n \n  return (\n    <IntlProvider\n      messages={ { ...translations, ...overriddenTranslations } }\n      locale=\"en\"\n      defaultLocale=\"en\"\n    >\n      {children}\n    </IntlProvider>\n  );\n}\n
\n\n

Now, we only need to override the translation for the key ‘validate.’ Its value will remain ‘OK’ in the test context.

\n\n
// const translations = { validate: 'GO' };\n\nit('validate something', () => {\n  const onClick = jest.fn();\n  render(\n    <MyComponent onClick={onClick} />,\n    {\n      wrapper: (children) => (\n        <AppIntlProvider overriddenTranslations={ { validate: 'OK' } }>\n          {children}\n        </AppIntlProvider>\n      ),\n    },\n  );\n  \n  userEvent.click(screen.getByText('OK'));\n  \n  expect(onClick).toHaveBeenCalled();\n});\n
\n\n

Overriding a translation makes the test more resilient; even if you change the translation, the test will still pass (be green). In this specific context, it allows the OPS team to change any translation without breaking the test suite.

\n","url":"/test-strategy-i18n-react-application.html","relative_path":"_posts/2023-12-11-test-strategy-i18n-react-application.md","permalink":null}],"pages":[{"draft":false,"categories":[],"layout":"default","title":"About arnaud Langlade","content_blocks":[{"_bookshop_name":"page-heading","title":"About","description":null},{"_bookshop_name":"page-image","image":"/images/me-about.webp","image_alt":"Arnaud Langlade's picture"},{"_bookshop_name":"content","content":"I am a software architect, and technical coach with 15 years of experience. I am, what we call, a self-taught. I studied telecommunications and networks at school but my first job was in a small web agency as a developer. I learned on the job and improved my skills by myself for many years during my free time. I did not take the easiest path but I don’t have any regrets. I love my job!\n\nI worked with many service companies that allowed me to work on big projects for huge companies like [Prisma media](https://www.prismamedia.com), [Royal Canin](https://www.royalcanin.com) and [Groupe Sud Ouest](https://www.groupesudouest.com). Then, I worked for several startups like [Akeneo](https://www.akeneo.com), [Convelio](https://www.convelio.com) or [Sunday](https://sundayapp.com). Finally, I started my own enterprise in August 2022 after leaving Sunday.\n\n> It's not stakeholder knowledge but developers' ignorance that gets deployed into production.\n>\n> [Alberto Brandolini](https://www.linkedin.com/in/brando/)\n\nSoftware is valuable only if it is used and solves business's needs. That’s why I focus on understanding the business first. I organize and animate event storming and example mapping workshops. Both workshops aim to gather tech and non-tech in the same room and let them speak. Event storming helps to grasp the global picture and start thinking about the software design while example mapping helps to clarify user stories.\n\nI focus my technical watch on topics that let me build robust and maintainable software. I develop using TDD and the mikado method. Those methodologies help me to design features baby step by baby step while covering code with tests. I am not interested in the latest super cool technologies. I prefer learning architecture patterns such as hexagonal architecture, it lets me build software no matter the frameworks.\n\n> Do The Simplest Thing That Could Possibly Work\n>\n> [Kent Beck](https://www.linkedin.com/in/kentbeck/)\n\nI try to find the simplest solution that solves a business problem to ship it to production as quickly as possible. Any feedback is key in software development, it ensures we take the right decision. Agile, «This is the way».\n"},{"_bookshop_name":"blog-section","link_url":"/blog"},{"_bookshop_name":"newsletter"}],"slug":"about","ext":".html","tags":[],"excerpt":"","date":"2024-01-08 08:11:03 -0600","content":"","url":"/about/","relative_path":"_pages/about.html","permalink":null},{"draft":false,"categories":[],"layout":"default","title":"Arnaud Langlade's blog","description":"Welcome to my blog. I love sharing my knowledge about software engineering such as architectural design patterns, software testing, methodologies and so on.","keywords":"arnaud langlade,langlade,software engineer,architect,technical coach,software,oop,blog,tdd,bdd,ddd,event storming,example mapping,arnolanglade,hexagonal architecture,event sourcing,unit test","content_blocks":[{"_bookshop_name":"blog-header","title":"Welcome to my blog","description":"Hi, my name is Arnaud. I am a software architect, and technical coach. I love sharing my knowledge about software engineering such as architectural design patterns, software testing, methodologies and so on.","image":"/images/me-home.webp","image_alt":"Arnaud Langlade's picture"},{"_bookshop_name":"posts-list","show_posts":true},{"_bookshop_name":"newsletter"}],"slug":"blog","ext":".html","tags":[],"excerpt":"","date":"2024-01-08 08:11:03 -0600","content":"","url":"/blog/","relative_path":"_pages/blog.html","permalink":null},{"draft":false,"categories":[],"layout":"default","title":"Contact Arnaud Langlade","content_blocks":[{"_bookshop_name":"page-heading","title":"Contact me"},{"_bookshop_name":"mailchimp-contact-form"},{"_bookshop_name":"blog-section","link_url":"/blog"}],"slug":"contact","ext":".html","tags":[],"excerpt":"","date":"2024-01-08 08:11:03 -0600","content":"","url":"/contact/","relative_path":"_pages/contact.html","permalink":null},{"draft":false,"categories":[],"layout":"default","title":"Arnaud Langlade's experiences","content_blocks":[{"_bookshop_name":"page-heading","title":"Experiences"},{"_bookshop_name":"testimonials-list"},{"_bookshop_name":"experiences-list"},{"_bookshop_name":"blog-section","link_url":"/blog"},{"_bookshop_name":"newsletter"}],"slug":"experiences","ext":".html","tags":[],"excerpt":"","date":"2024-01-08 08:11:03 -0600","content":"","url":"/experiences/","relative_path":"_pages/experiences.html","permalink":null},{"draft":false,"categories":[],"layout":"xml-files","permalink":"/:title:output_ext","title":"Feed","slug":"feed","ext":".xml","tags":[],"excerpt":"\n\n \n Arnaud Langlade\n \n https://arnolanglade.github.io/\n \n Mon, 08 Jan 2024 08:11:03 -0600\n Mon, 08 Jan 2024 08:11:03 -0600\n Jekyll v4.2.1\n \n \n Testing a React application: Secure your tests from internationalization impact\n <p>In my previous company, we automated the translation process. We used Lokalise, a cloud-based localization and translation management system. The developers imported all translation keys into the system, while the OPS team was responsible for translating all the keys.</p>\n\n<p><img src="images/posts/test-strategy-i18n-react-application/translation-management-workflow.svg" alt="translation management workflow with lokalized" /></p>\n\n<p>This process is excellent because you don’t have to wait for translations. As a developer, you add the new translation key and provide the default language. The OPS team is notified when a new key is imported into the tool. They don’t need a developer to provide translations; they are highly autonomous. Afterward, the developers need to pull the translations into the codebase and deploy the application.</p>\n\n<p>Let’s consider an example: a React Application that uses the <a href="https://github.com/formatjs/formatjs">React-Intl</a> as its internationalization system. This library provides a component called <code class="language-plaintext highlighter-rouge">FormattedMessage</code> that finds the translation for a given key and locale. This component must be used within a React Context called <code class="language-plaintext highlighter-rouge">IntlProvider</code>.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">translations</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">translation</span><span class="dl">'</span> <span class="p">};</span>\n\n\n<span class="p">&lt;</span><span class="nc">IntlProvider</span> <span class="na">locale</span><span class="p">=</span><span class="s">"en"</span> <span class="na">messages</span><span class="p">=</span><span class="si">{</span><span class="nx">translations</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">FormattedMessage</span> <span class="na">id</span><span class="p">=</span><span class="s">"key"</span> <span class="p">/&gt;</span>\n<span class="p">&lt;/</span><span class="nc">IntlProvider</span><span class="p">&gt;;</span>\n</code></pre></div></div>\n\n<p>I like wrapping the <code class="language-plaintext highlighter-rouge">IntlProvider</code> in a custom provider that allows configuring React Intl for the entire application and provides additional features like locale switching. To keep this example simple, I hardcoded the locale.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">AppIntlProvider</span><span class="p">({</span> <span class="nx">children</span> <span class="p">}:</span> <span class="p">{</span> <span class="nl">children</span><span class="p">:</span> <span class="nx">ReactElement</span> <span class="p">})</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">translations</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">translation</span><span class="dl">'</span> <span class="p">};</span>\n \n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">IntlProvider</span>\n <span class="na">messages</span><span class="p">=</span><span class="si">{</span><span class="nx">translations</span><span class="si">}</span>\n <span class="na">locale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="na">defaultLocale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">IntlProvider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now let’s go back to the testing problem. The following example is a test that checks if the <code class="language-plaintext highlighter-rouge">onClick</code> callback is called when the button with the label “OK” is clicked.`</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">MyComponent</span><span class="p">({</span> <span class="nx">onClick</span> <span class="p">}:</span> <span class="p">{</span> <span class="nl">onClick</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="k">void</span> <span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>\n // ...\n <span class="p">&lt;</span><span class="nc">Button</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">FormattedMessage</span> <span class="na">id</span><span class="p">=</span><span class="s">"validate"</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">Button</span><span class="p">&gt;</span>\n <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n<span class="c1">//const translations = { validate: 'OK' };</span>\n\n<span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">validate something</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">onClick</span> <span class="o">=</span> <span class="nx">jest</span><span class="p">.</span><span class="nx">fn</span><span class="p">();</span>\n <span class="nx">render</span><span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">MyComponent</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span> <span class="p">/&gt;,</span>\n <span class="p">{</span>\n <span class="na">wrapper</span><span class="p">:</span> <span class="nx">AppIntlProvider</span><span class="p">,</span>\n <span class="p">},</span>\n <span class="p">);</span>\n \n <span class="nx">userEvent</span><span class="p">.</span><span class="nx">click</span><span class="p">(</span><span class="nx">screen</span><span class="p">.</span><span class="nx">getByText</span><span class="p">(</span><span class="dl">'</span><span class="s1">OK</span><span class="dl">'</span><span class="p">));</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">onClick</span><span class="p">).</span><span class="nx">toHaveBeenCalled</span><span class="p">();</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>What happens if an OPS changes the translation of the ‘validate’ key from ‘OK’ to ‘GO’ for any reason? Your test will break even if the code and the test have not changed. That is a shame. Should translations break your test suites? I would like to answer this question with a no.\nThe solution that I use to prevent this problem is to override each translation that the test needs. I added an extra prop to the custom React Intl provider called overriddenTranslations that lets me override the translations my test needs.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">AppIntlProvider</span><span class="p">(</span>\n <span class="p">{</span> <span class="nx">children</span><span class="p">,</span> <span class="nx">overriddenTranslations</span> <span class="p">}:</span>\n <span class="p">{</span> <span class="nl">children</span><span class="p">:</span> <span class="nx">ReactElement</span><span class="p">,</span> <span class="nx">overriddenTranslations</span><span class="p">?:</span> <span class="nb">Partial</span><span class="o">&lt;</span><span class="nx">Translations</span><span class="o">&gt;</span> <span class="p">},</span>\n<span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">translations</span><span class="p">:</span> <span class="nx">Translations</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">translation</span><span class="dl">'</span> <span class="p">};</span>\n \n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">IntlProvider</span>\n <span class="na">messages</span><span class="p">=</span><span class="si">{</span> <span class="p">{</span> <span class="p">...</span><span class="nx">translations</span><span class="p">,</span> <span class="p">...</span><span class="nx">overriddenTranslations</span> <span class="p">}</span> <span class="si">}</span>\n <span class="na">locale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="na">defaultLocale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">IntlProvider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, we only need to override the translation for the key ‘validate.’ Its value will remain ‘OK’ in the test context.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// const translations = { validate: 'GO' };</span>\n\n<span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">validate something</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">onClick</span> <span class="o">=</span> <span class="nx">jest</span><span class="p">.</span><span class="nx">fn</span><span class="p">();</span>\n <span class="nx">render</span><span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">MyComponent</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span> <span class="p">/&gt;,</span>\n <span class="p">{</span>\n <span class="na">wrapper</span><span class="p">:</span> <span class="p">(</span><span class="nx">children</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">AppIntlProvider</span> <span class="na">overriddenTranslations</span><span class="p">=</span><span class="si">{</span> <span class="p">{</span> <span class="na">validate</span><span class="p">:</span> <span class="dl">'</span><span class="s1">OK</span><span class="dl">'</span> <span class="p">}</span> <span class="si">}</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">AppIntlProvider</span><span class="p">&gt;</span>\n <span class="p">),</span>\n <span class="p">},</span>\n <span class="p">);</span>\n \n <span class="nx">userEvent</span><span class="p">.</span><span class="nx">click</span><span class="p">(</span><span class="nx">screen</span><span class="p">.</span><span class="nx">getByText</span><span class="p">(</span><span class="dl">'</span><span class="s1">OK</span><span class="dl">'</span><span class="p">));</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">onClick</span><span class="p">).</span><span class="nx">toHaveBeenCalled</span><span class="p">();</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>Overriding a translation makes the test more resilient; even if you change the translation, the test will still pass (be green). In this specific context, it allows the OPS team to change any translation without breaking the test suite.</p>\n\n Mon, 11 Dec 2023 00:00:00 -0600\n https://arnolanglade.github.io/test-strategy-i18n-react-application.html?s=feed\n https://arnolanglade.github.io/test-strategy-i18n-react-application.html\n \n react\n \n testing\n \n \n \n \n \n The Mikado Method: Small Steps, Big Improvements\n <p>In this blog post, I will introduce the Mikado Method. This method helps solve complex problems without breaking your codebase, even if you need to introduce significant changes.</p>\n\n<p>It is common to work using PR (Pull Request), you can work on your task without breaking your application and disturbing the rest of the team. However, when you start working on a task without maintaining something that works, you end up adding too many changes that are not production-ready. The drawback of this approach is that your PRs will be large and hard to merge.</p>\n\n<p>It often happens when you refactor your codebase. You start refactoring something but it breaks another part of this application, then you fix it but it introduces a new problem elsewhere. As a result, you accumulate many changes without being able to merge them.</p>\n\n<p>Merging big PR is more complicated than simple changes. First, we need to ask for code reviews, but it can be challenging for your teammate to understand what you did when your PR includes too many things. Then, another drawback is the need to rebase your PR several times due to other PRs being pushed to the main branch.</p>\n\n<p>Now, you understand why it’s difficult to introduce big changes in your codebase. It is better to work on small steps that can be mergeable at any time. The Mikado method takes its name from the Mikado game, where the goal is to remove one stick without disturbing the others. The Mikado method has the same philosophy. It aims to make small incremental improvements to a project without breaking the existing codebase. This way, you can push your changes at any time and they won’t break your application even if you did not finish your task.</p>\n\n<p>This method simplifies refactoring. You can continuously improve your codebase instead of stacking changes in a huge PR which can’t be merged because the test suites are broken. It’s better to regularly merge small changes that improve your codebase quality. This method is ideal for brownfield development. It enables you to add new features or alter existing ones without breaking the rest of the application. Moreover, it facilitates the improvement of the application’s architecture while allowing the delivery of new features concurrently.</p>\n\n<p>How does it work? Let’s take an example: MySQL doesn’t match the project’s needs; we need to use PostgreSQL. First, we need to define a goal that is clear and understandable for everyone. In our case, it is “Migrate the application from MySQL to PostgreSQL,” as you can see in the following example.</p>\n\n<p><img src="images/posts/mikado-method/define-goal.webp" alt="define a goal" /></p>\n\n<p><strong>Note:</strong> A goal can be what you want to improve in your application such as refactoring a section of the application to enhance its clarity or improving an existing feature.</p>\n\n<p>There are less chances that you can achieve your goal in a single attempt and quickly but we will try to solve it. Based on what we learn in this initial experimentation, we will split a big task (our goal) into smaller ones, which we call prerequisites. As mentioned earlier, this approach prevents ending up with a large pull request that is difficult to merge.</p>\n\n<p>To migrate the application to PostgreSQL, we first need to install the database. Then, we need to update our repositories because they use SQL queries specific to MySQL.</p>\n\n<p><img src="images/posts/mikado-method/add-prerequisites.webp" alt="add prerequisites to the mikado graph" /></p>\n\n<p>Now, you will start exploring all the prerequisites. Select a prerequisite from the list and start an experimentation to solve it. If you can easily achieve it, that’s excellent! Commit your changes, mark the prerequisite as completed, and proceed to the next one on the list.</p>\n\n<p><img src="images/posts/mikado-method/prerequisite-completed.webp" alt="prerequisite completed" /></p>\n\n<p>If you cannot easily solve it, you need to revert your changes and define a sublist of prerequisites to achieve the original prerequisite. The purpose is to avoid making big changes but to focus on working on small steps while keeping the codebase stable. Reverting changes may not be natural to a developer, but it’s an important step in the process. It allows you to continue working in smaller steps, while the exploration helps you learn what is necessary to solve a prerequisite.</p>\n\n<p><img src="images/posts/mikado-method/add-prerequisite-to-prerequisite.webp" alt="add prerequisite to prerequisite" /></p>\n\n<p>Continue to resolve all prerequisites until the end. When all prerequisites are done, your goal is completed!</p>\n\n<p><img src="images/posts/mikado-method/goal-completed.webp" alt="goal completed" /></p>\n\n<p>As you can see in the previous sections of the blog post, we can represent your progress as a graph. This is a useful way to communicate the progress of your task with the rest of the team. For example, you can show the mikado graph at the daily meeting to easily explain what you did. If, for any reason, you cannot complete your task, you can share the mikado graph with a colleague to explain what you’ve done and what remains to be done. Organizing your work becomes easier, especially when you are working on complex tasks. The Mikado graph is more visual than a simple to-do list because it allows you to see dependencies between prerequisites.</p>\n\n<p>I wrote a small application called MikadoApp to easily create and share your Mikado graphs. All the images in the blog posts are screenshots from the application. You can start using it thanks to this <a href="https://mikado-method-teal.vercel.app">link</a>, and you can find the source code on <a href="https://github.com/arnolanglade/mikado-app">GitHub</a>. Don’t hesitate to contribute to the application to improve it.</p>\n\n<p>Since I started using this method, my way of working has changed. I try to break down my work into small steps, and each commit can be pushed into production. If I refactor something, it’s great because I regularly push improvements. If I work on a feature, I can refactor what I need to create my feature without breaking the rest of the application.</p>\n\n<p>Now,I like working directly on the main branch, but I ensure that I only push stable commits. That’s what we call Trunk Based Development. This approach allows delivering small improvements to production quickly and frequently. Even though it can be practiced with PRs, I no longer prefer working with them due to the many associated processes that slow down the delivery.</p>\n\n Mon, 27 Nov 2023 00:00:00 -0600\n https://arnolanglade.github.io/mikado-method.html?s=feed\n https://arnolanglade.github.io/mikado-method.html\n \n methodology\n \n \n \n \n \n Open-Closed principle: Enhancing code modularity\n <p>Have you missed my last blog post about the <a href="/oop-inheritance-pitfalls.html">pitfalls of inheritance</a>? I explain how it could be a bad idea to use it too much. Applying composition prevents this problem; it is better to work with small classes to easily assemble. In this blog post, I will talk about the open-closed principle. This principle facilitates composition and helps avoid relying too much on inheritance.</p>\n\n<p>This principle is one of the SOLID principles, and I think it is super important because it allows you to write more flexible code. I wanted to explain it because its definition is quite simple, but it is not necessarily easy to grasp.</p>\n\n<blockquote>\n <p>The open closed principle states “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”; that is, such an entity can allow its behaviour to be extended without modifying its source code.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle">Wikipedia</a></p>\n</blockquote>\n\n<p>The first time I read the definition of this principle, I understood that I should not have to modify my code to add additional behavior. This part of the definition “open for extension” was a bit confusing. What did it mean? Does it refer to OOP inheritance? No, it doesn’t refer to OOP inheritance. I have written a blog post about OOP inheritance. It explains why extending a class to change its behavior may seem simple, but is it a good idea? It introduces a lot of coupling in your codebase and between your team.</p>\n\n<p>Before digging into the principle, let’s consider a scenario to illustrate the following example: a class called ‘DiscountCalculator’ is in charge of calculating discounts based on the products in the basket. We apply a 20% discount to products with the category ‘sport,’ a 50% discount to products with the category ‘home,’ and a 10% discount to products with the category ‘food.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">Product</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">public</span> <span class="nx">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span>\n <span class="k">public</span> <span class="nx">category</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span>\n <span class="k">public</span> <span class="nx">price</span><span class="p">:</span> <span class="kr">number</span>\n <span class="p">)</span> <span class="p">{}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">Basket</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">public</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[])</span> <span class="p">{}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">DiscountCalculator</span> <span class="p">{</span>\n <span class="nx">calculate</span><span class="p">(</span><span class="nx">basket</span><span class="p">:</span> <span class="nx">Basket</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="kd">let</span> <span class="nx">totalDiscount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>\n\n\n <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">product</span> <span class="k">of</span> <span class="nx">basket</span><span class="p">.</span><span class="nx">products</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">switch</span> <span class="p">(</span><span class="nx">product</span><span class="p">.</span><span class="nx">category</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">case</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">:</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.2</span><span class="p">;</span> <span class="c1">// 20% discount</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="k">case</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">:</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.5</span><span class="p">;</span> <span class="c1">// 50% discount</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="k">case</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">:</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.1</span><span class="p">;</span> <span class="c1">// 10% discount</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="p">}</span>\n <span class="p">}</span>\n \n <span class="k">return</span> <span class="nx">totalDiscount</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="c1">// Example usage:</span>\n<span class="nx">it</span><span class="p">.</span><span class="nx">each</span><span class="p">([</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Football</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">20</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Couch</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">100</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Banana</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>\n<span class="p">])(</span><span class="dl">'</span><span class="s1">calculates discounts for %s category</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">,</span> <span class="nx">expectedDiscount</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">product</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Product</span><span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">basket</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Basket</span><span class="p">([</span><span class="nx">product</span><span class="p">]);</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="k">new</span> <span class="nx">DiscountCalculator</span><span class="p">().</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">basket</span><span class="p">)).</span><span class="nx">toBe</span><span class="p">(</span><span class="nx">expectedDiscount</span><span class="p">);</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>This code does not follow the open-close principle because we need to modify this <code class="language-plaintext highlighter-rouge">DiscountCalculator</code> class every time we want to add or remove a discount rule. The problem is that<code class="language-plaintext highlighter-rouge">DiscountCalculator</code> may become really large if the business asks us to add a lot of discount rules. Large objects are hard to understand, so it won’t facilitate its maintenance and testability.</p>\n\n<p>Let’s refactor this code to enhance its modularity and align it with the Open-Closed principle. We will use the strategy pattern to rewrite the calculator to remove the hard-coded rules. First, we will introduce a new interface that specifies how a discount works. This interface has two methods: the first one is <code class="language-plaintext highlighter-rouge">isApplicable</code>, which determines if a discount can be applied to a product, while the second one <code class="language-plaintext highlighter-rouge">calculate</code> calculates the amount of the discount.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span>\n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span><span class="p">;</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">SportCategoryDiscount</span> <span class="k">implements</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">category</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">;</span>\n <span class="p">}</span>\n \n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.2</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">HomeCategoryDiscount</span> <span class="k">implements</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">category</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">;</span>\n <span class="p">}</span>\n \n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.5</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">FoodCategoryDiscount</span> <span class="k">implements</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">category</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">;</span>\n <span class="p">}</span>\n \n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.1</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then, we need to update the calculator. It will determine whether a discount is applicable to a product and calculate the discount amount. With this approach, you can easily add or remove discount rules as needed.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">DiscountCalculator</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">discounts</span><span class="p">:</span> <span class="nx">Discount</span><span class="p">[])</span> <span class="p">{}</span>\n \n <span class="nx">calculateDiscount</span><span class="p">(</span><span class="nx">basket</span><span class="p">:</span> <span class="nx">Basket</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="kd">let</span> <span class="nx">totalDiscount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>\n \n <span class="nx">basket</span><span class="p">.</span><span class="nx">products</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">discounts</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">discount</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">if</span><span class="p">(</span><span class="nx">discount</span><span class="p">.</span><span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">))</span> <span class="p">{</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">discount</span><span class="p">.</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="p">});</span>\n <span class="p">});</span>\n \n <span class="k">return</span> <span class="nx">totalDiscount</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="c1">// Example usage:</span>\n<span class="nx">it</span><span class="p">.</span><span class="nx">each</span><span class="p">([</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Football</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">20</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Couch</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">100</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Banana</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>\n<span class="p">])(</span><span class="dl">'</span><span class="s1">calculates discounts for %s category</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">,</span> <span class="nx">expectedDiscount</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">product</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Product</span><span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">basket</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Basket</span><span class="p">([</span><span class="nx">product</span><span class="p">]);</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="k">new</span> <span class="nx">DiscountCalculator</span><span class="p">([</span>\n <span class="k">new</span> <span class="nx">SportCategoryDiscount</span><span class="p">(),</span>\n <span class="k">new</span> <span class="nx">HomeCategoryDiscount</span><span class="p">(),</span>\n <span class="k">new</span> <span class="nx">FoodCategoryDiscount</span><span class="p">(),</span>\n <span class="p">]).</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">basket</span><span class="p">)).</span><span class="nx">toBe</span><span class="p">(</span><span class="nx">expectedDiscount</span><span class="p">);</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>We don’t need to over-engineer to apply the open-close principle. With the right design pattern, it is quite simple. Now, the discount calculator is more flexible. We didn’t introduce a lot of new code but we divided the class into smaller ones. Small classes are easier to test and understand, and it will facilitate the maintenance and the evolution of your application.</p>\n\n\n Mon, 13 Nov 2023 00:00:00 -0600\n https://arnolanglade.github.io/open-close-principle.html?s=feed\n https://arnolanglade.github.io/open-close-principle.html\n \n OOP\n \n SOLID\n \n \n \n \n \n The pitfalls of OOP's inheritance: Why simple isn't always better\n <p>In OOP, the simplest way to change the behavior of a class A is to create a class B that extends class A. Extensions allow you to override any public and protected methods of the parent class. That‘s quite simple, right?</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/simple-inheritance.svg" alt="Simple object inheritance" /></p>\n\n<p>Furthermore, you can extend a class multiple times with several levels of inheritance. In the following example, we can see that class B has two children, and the class hierarchy has four levels of inheritance. Now let’s explore why it is not a good idea and which problem can occur?</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/inheritance-with-several-levels.svg" alt="Object inheritance with several levels" /></p>\n\n<p>Designing code like this won’t facilitate refactoring. Let’s consider a scenario where Class A has a method that is overridden in both Class B and Class E. What happens if we decide to change the signature of this method in Class A? We will need to rewrite this method in Class B and Class E to match the new signature. Another frustrating aspect is that we will have to modify all portions of the code that use this method. In a small codebase, this may be manageable, but in a large one, it’s a different story!</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/refactoring-inheritance-with-several-levels.svg" alt="Refactoring with object inheritance with several levels" /></p>\n\n<p>This code won’t ease team collaboration. Let’s consider another scenario: where we are working on a huge monolith shared with several other teams. What happens if team A needs to change class A? That means teams B, C, and D must also update their codebases. We have introduced coupling between these three teams because of the coupling between classes A, B, C, and D. That’s a shame. This design will slow down your delivery because team A will need to coordinate with three other teams if it needs to change class A.</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/refactoring-inheritance-with-several-teams.svg" alt="Refactoring with object inheritance with several teams" /></p>\n\n<p>I have worked on several codebases that heavily relied on inheritance, but now I barely use it due to the drawbacks I’ve described. Instead, I prefer to use composition. It is better to work with several small classes and assemble them, it’s like playing with Lego blocks. Moreover, it greatly simplifies testing.</p>\n\n<p>I try to apply the open-closed principle as much as possible to enhance code modularity and facilitate evolution. In a related blog post, I explain the principle and provide an example to illustrate how to refactor code that doesn’t follow this principle. Here is the link:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/open-close-principle.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/open-close-principle.webp" alt="Open-Closed principle: Enhancing code modularity" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Open-Closed principle: Enhancing code modularity</span>\n </span>\n </a>\n</div>\n\n\n Mon, 23 Oct 2023 00:00:00 -0500\n https://arnolanglade.github.io/oop-inheritance-pitfalls.html?s=feed\n https://arnolanglade.github.io/oop-inheritance-pitfalls.html\n \n OOP\n \n \n \n \n \n Why breaking encapsulation is not a good idea\n <p>In this blog post, I would like to speak about an important concept in Oriented Object Programming which is the encapsulation principle.</p>\n\n<p>Before speaking about encapsulation let’s talk a bit about OOP. What is the object’s life cycle? The first step of the object’s life cycle is to be instantiated. We give everything an object needs to initialise its internal state. Then we use its public API (public methods) to communicate with it. An object exposes a public API (behaviour) that manipulates its internal state (data).</p>\n\n<p><img src="images/posts/why-breaking-encapsulation-is-not-a-good-idea/object-life-cycle.svg" alt="Object life cycle" /></p>\n\n<p>So, what is encapsulation? This principle restricts direct access to the state of the object from outside. This means that the internal implementation details of a class are hidden. Accessing the state of the object is only allowed through its public API (public methods). This concept helps to protect the data from outside interference and ensures controlled and secured data manipulation.</p>\n\n<p><strong>Note:</strong> An object that only has getters and setters is not an object! This is a data structure because it has no behaviour.</p>\n\n<p>I worked on many applications that used getters and setters. They are good examples of what is breaking encapsulation. It is easy to break encapsulation but it is not a good idea. It will make your code less maintainable and your applications less evolutive. Let’s take a simple example to understand why breaking encapsulation is a bad idea. I want to find the closest point of interest on a map close to a given location.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Location</span> <span class="o">=</span> <span class="p">{</span>\n <span class="na">latitude</span><span class="p">:</span> <span class="kr">number</span>\n <span class="na">longitude</span><span class="p">:</span> <span class="kr">number</span>\n<span class="p">}</span>\n\n\n<span class="kd">type</span> <span class="nx">PointOfInterest</span> <span class="o">=</span> <span class="p">{</span>\n <span class="na">name</span><span class="p">:</span> <span class="kr">string</span>\n <span class="na">location</span><span class="p">:</span> <span class="nx">Location</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nb">Map</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">pointOfInterests</span><span class="p">:</span> <span class="nx">PointOfInterest</span><span class="p">[])</span> <span class="p">{}</span>\n\n\n <span class="nx">getPointOfInterests</span><span class="p">():</span> <span class="nx">PointOfInterest</span><span class="p">[]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">pointOfInterests</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">AClassWhereWeNeedToFindClosestPOI</span> <span class="p">{</span>\n <span class="nx">doSomething</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">pointOfInterest</span> <span class="o">=</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getPointOfInterests</span><span class="p">()</span>\n <span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">pointOfInterest</span><span class="p">:</span> <span class="nx">PointOfInterest</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">})[</span><span class="mi">0</span><span class="p">]</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">Map</code> class has a <code class="language-plaintext highlighter-rouge">getPointOfInterest</code> getter that gets the class property with the same name. Then we can use this getter to access the list of points of interest to iterate them and find the closest one.</p>\n\n<p>The drawback with this getter is that we will need to copy/paste this piece of code if we have to look for the closest point of interest in several places. It won’t help you to mutualize code. At best, you can extract this piece of code into a dedicated class like the following example:</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">POIFinder</span> <span class="p">{</span>\n <span class="nx">find</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">):</span> <span class="nx">PointOfInterest</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getPointOfInterests</span><span class="p">()</span>\n <span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">pointOfInterest</span><span class="p">:</span> <span class="nx">PointOfInterest</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">})[</span><span class="mi">0</span><span class="p">]</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The problem with this code is that we extract the <code class="language-plaintext highlighter-rouge">Map</code> object behaviour into another class. We will turn the <code class="language-plaintext highlighter-rouge">Map</code> object into a data structure if we remove all methods that add a behaviour to it.</p>\n\n<p><strong>Note:</strong> A class that ends with -ER (like in the previous example) is a good insight into how this class does the job of another class.</p>\n\n<p>What happens if we need to change the internal of the POI list? Now, we don’t want to use an array anymore, we want to manage the POI list with a custom class named <code class="language-plaintext highlighter-rouge">PointOfInterestList</code>. It might be a simple refactoring for small applications but it is super painful for huge ones. If the getter method is used hundreds of times, we will have to refactor each <code class="language-plaintext highlighter-rouge">getPointOfInterest</code> usage to make them compatible with the new signature.</p>\n\n<p>To avoid this problem, we only need to apply the “Tell, don’t ask” principle. This principle says that we should tell an object to do something instead of asking for its internal state to do something in his stead.</p>\n\n<p>The solution would be to add a <code class="language-plaintext highlighter-rouge">findClosestPointOfInterest</code> method to the <code class="language-plaintext highlighter-rouge">Map</code> object. The only purpose of this method is to find the closest POI no matter how the POI list is designed. This allows you to refactor the internal state of the object as many times you want.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">ListOfPointOfInterest</span> <span class="p">{</span>\n <span class="nx">findClosest</span><span class="p">(</span><span class="nx">location</span><span class="p">:</span> <span class="nx">Location</span><span class="p">)</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nb">Map</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">pointOfInterests</span><span class="p">:</span> <span class="nx">ListOfPointOfInterest</span><span class="p">)</span> <span class="p">{}</span>\n\n\n <span class="nx">findClosestPointOfInterest</span><span class="p">(</span><span class="nx">location</span><span class="p">:</span> <span class="nx">Location</span><span class="p">):</span> <span class="nx">PointOfInterest</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">pointOfInterests</span><span class="p">.</span><span class="nx">findClosest</span><span class="p">(</span><span class="nx">location</span><span class="p">)</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> Breaking encapsulation to test your code is a bad idea too. I’ve written an article to present you with an alternative to the getter to prevent exposing the state of the objects. Here is the link:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/you-should-not-expose-objects-state-to-test-them.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/test-comparison.webp" alt="Why you should not expose objects' state to test them" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Why you should not expose objects' state to test them</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 19 Sep 2023 00:00:00 -0500\n https://arnolanglade.github.io/why-breaking-encapsulation-is-not-a-good-idea.html?s=feed\n https://arnolanglade.github.io/why-breaking-encapsulation-is-not-a-good-idea.html\n \n testing\n \n OOP\n \n \n \n \n \n Don’t test private methods\n <p>It is pretty easy to make mistakes when you start testing your code. One of the first mistakes I made was to test private methods. Spoiler alert: it was a bad idea because I had to use reflection to make them public to access them. If you need to test a private method, it probably means that your code is not well designed</p>\n\n<p>We don’t test private methods. Private methods are implementation details of objects and we should not care about them. Don’t worry! They are tested in the end. When you test public methods you also test the private ones as described in the next schema.</p>\n\n<p><img src="images/posts/do-not-test-private-method/test-private-methods-through-public-ones.svg" alt="Test private methods through public ones" /></p>\n\n<p>I needed to test the private methods because my object was a God object (huge object). It did a lot of things. It had a few public methods and a lot of private ones because too many things happened behind the scenes.</p>\n\n<p><img src="images/posts/do-not-test-private-method/object-with-too-many-private-methods.svg" alt="Object with too many private methods" /></p>\n\n<p>The problem with this design is this object did not follow the <strong>S</strong>ingle <strong>R</strong>esponsibility <strong>P</strong>rinciple, but what is this principle?</p>\n\n<blockquote>\n <p>There should never be more than one reason for a class to change. In other words, every class should have only one responsibility</p>\n\n <p><a href="https://en.wikipedia.org/wiki/SOLID">wikipedia</a></p>\n</blockquote>\n\n<p>My object was super huge because it did too many things. It had too many responsibilities. Because of that, I could not test it easily. How can we avoid that?</p>\n\n<p><img src="images/posts/do-not-test-private-method/complicated-to-test-objects-with-many-responsibilities.svg" alt="complicated to test objects with many responsibilities" /></p>\n\n<p>It’s better to work on small problems than a big one. The solution would have been to identify each responsibility to extract them into dedicated objects. We don’t need magic tricks to test small objects. It is simple to test them because they do a simple thing, and we only need to use their public API (public method) to test them. We don’t need reflection anymore.</p>\n\n<p><img src="images/posts/do-not-test-private-method/split-good-objects-into-small-classes.svg" alt="split good objects into small classes" /></p>\n\n<p>Then, we need to apply the composition pattern to assemble those classes to make them work as the God object. Composition is like playing Lego: we have many small bricks, and we put them together to make a big piece. Software is the same. You should work with small classes/functions to easily test them and piece them together to make your feature.</p>\n\n<p>Let’s take an example. The following class is in charge of importing products into an application as a PIM or an ERP. This class does several things, it gets product data from a CSV file and it imports them into a database. We need to test the whole class to ensure the product import works as expected. That’s a bit annoying because I can’t test the CSV file reading or the production saving.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Product</span> <span class="o">=</span> <span class="p">{</span>\n <span class="na">name</span><span class="p">:</span> <span class="kr">string</span>\n <span class="na">description</span><span class="p">:</span> <span class="kr">string</span>\n<span class="p">};</span>\n\n<span class="kd">class</span> <span class="nx">ProductImport</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">connection</span><span class="p">:</span> <span class="nx">Connection</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">async</span> <span class="k">import</span><span class="p">(</span><span class="nx">filePath</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">loadProductFromCsvFile</span><span class="p">(</span><span class="nx">filePath</span><span class="p">);</span>\n <span class="p">}</span>\n \n <span class="k">private</span> <span class="k">async</span> <span class="nx">loadProductFromCsvFile</span><span class="p">(</span><span class="nx">file</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="na">csvData</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>\n <span class="nx">createReadStream</span><span class="p">(</span><span class="nx">file</span><span class="p">)</span>\n <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">csvParser</span><span class="p">())</span>\n <span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">data</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="na">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">csvData</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">product</span><span class="p">))</span>\n <span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">end</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">data</span> <span class="k">of</span> <span class="nx">csvData</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">saveProducts</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="p">});</span>\n <span class="p">}</span>\n\n <span class="k">private</span> <span class="k">async</span> <span class="nx">saveProducts</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">execute</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">INSERT INTO products (name, description) VALUES (?, ?)</span><span class="dl">'</span><span class="p">,</span>\n <span class="p">[</span><span class="nx">product</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">product</span><span class="p">.</span><span class="nx">description</span><span class="p">],</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>We need to split this class into smaller ones to ease testing. We will extract both private methods into dedicated classes.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">CsvProductLoader</span> <span class="p">{</span>\n <span class="k">async</span> <span class="nx">loadProduct</span><span class="p">(</span><span class="nx">file</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nx">Product</span><span class="p">[]</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="na">products</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>\n <span class="nx">createReadStream</span><span class="p">(</span><span class="nx">file</span><span class="p">)</span>\n <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">csvParser</span><span class="p">())</span>\n <span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">data</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="na">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">products</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">product</span><span class="p">));</span>\n \n <span class="k">return</span> <span class="nx">products</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">MysqlProducts</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">connection</span><span class="p">:</span> <span class="nx">Connection</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">async</span> <span class="nx">save</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">execute</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">INSERT INTO products (name, description) VALUES (?, ?)</span><span class="dl">'</span><span class="p">,</span>\n <span class="p">[</span><span class="nx">product</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">product</span><span class="p">.</span><span class="nx">description</span><span class="p">],</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n<p>Now, we can test them stand-alone because these classes expose public methods. We don’t need a magic trick such as reflection to change their visibility to test them.</p>\n\n<p>We still need the <code class="language-plaintext highlighter-rouge">ProductImport</code> class. It will depend on both previous classes and act as a controller. It asks <code class="language-plaintext highlighter-rouge">CsvProductLoader</code> to get the product information from the CSV file and asks <code class="language-plaintext highlighter-rouge">CsvProductLoader</code> to save them into a database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">ProductImport</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">productLoader</span><span class="p">:</span> <span class="nx">CsvProductLoader</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">MysqlProducts</span><span class="p">,</span>\n <span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">async</span> <span class="k">import</span><span class="p">(</span><span class="nx">filePath</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">products</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">productLoader</span><span class="p">.</span><span class="nx">loadProduct</span><span class="p">(</span><span class="nx">filePath</span><span class="p">);</span>\n <span class="nx">products</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="na">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">products</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span><span class="nx">product</span><span class="p">));</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>That’s great because we extract IO usage into new classes. Both <code class="language-plaintext highlighter-rouge">MysqlProducts</code> and <code class="language-plaintext highlighter-rouge">CsvProductLoader</code> need to be tested with integration/contract tests since <code class="language-plaintext highlighter-rouge">ProductImport</code> can be unit tested.</p>\n\n<p>We need to make a last change. We cannot rely on concrete classes. We need to introduce interfaces to avoid coupling between <code class="language-plaintext highlighter-rouge">ProductImport</code> and its dependencies (<code class="language-plaintext highlighter-rouge">MysqlProducts</code> and <code class="language-plaintext highlighter-rouge">CsvProductLoader</code>).</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">ProductLoader</span> <span class="p">{</span>\n <span class="nx">loadProduct</span><span class="p">(</span><span class="nx">file</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nx">Product</span><span class="p">[]</span><span class="o">&gt;</span>\n<span class="p">}</span>\n\n<span class="kr">interface</span> <span class="nx">Products</span> <span class="p">{</span>\n <span class="nx">save</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">ProductImport</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">productLoader</span><span class="p">:</span> <span class="nx">ProductLoader</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">Products</span><span class="p">,</span>\n <span class="p">)</span> <span class="p">{}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note</strong>: I’ve written an article about how the inversion dependency design pattern will ease testing. Here is the link:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/inversion-dependency/ease-testing-thanks-to-the-dependency-inversion-design-pattern.webp" alt="Ease testing thanks to the dependency inversion design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Ease testing thanks to the dependency inversion design pattern</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 17 Jul 2023 00:00:00 -0500\n https://arnolanglade.github.io/do-not-test-private-methods.html?s=feed\n https://arnolanglade.github.io/do-not-test-private-methods.html\n \n testing\n \n OOP\n \n \n \n \n \n Ease testing thanks to the dependency inversion design pattern\n <p>In this new blog post, I would like to speak about the dependency inversion design pattern. This pattern makes your code more modular and helps to improve codebase testability. It’s quite simple and super powerful.</p>\n<h2 id="what-does-this-design-pattern-say">What does this design pattern say?</h2>\n<p>A class should not depend on another one to avoid coupling them together. If a class is coupled with another one, it means you won’t be able to use the first one without the second one.</p>\n\n<p><img src="images/posts/inversion-dependency/concrete-class-should-not-use-concrete-class.svg" alt="Concrete class should not use concrete class" /></p>\n\n<p>The classes should only depend on abstractions (e.g. interfaces). An interface can be implemented in several ways. It will make your code more modular because you can use a specific implementation depending on the context.</p>\n\n<p><img src="images/posts/inversion-dependency/depend-on-abstraction.svg" alt="Concrete class should depend on abstraction" /></p>\n\n<p>The interfaces should not depend on concrete implementations to avoid coupling them to another class.</p>\n\n<p><img src="images/posts/inversion-dependency/abstraction-should-not-use-concrete-class.svg" alt="Abstraction should not use concrete class" /></p>\n\n<h2 id="how-does-this-pattern-improve-testability">How does this pattern improve testability?</h2>\n\n<p>Let’s see with a simple example how dependency inversion helps to make your code easily testable. The following class lets a cartographer add a marker on a map.</p>\n\n<p><strong>Note:</strong> I wrote an article about unit testing to help you to understand the main mistakes that make your codebase less testable. Here is the link https://arnolanglade.github.io/why-unit-testing-can-be-hard.html.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">AddMarkerToMap</span> <span class="p">{</span>\n <span class="nx">execute</span><span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">repository</span> <span class="o">=</span> <span class="nx">PosgresqlMaps</span><span class="p">.</span><span class="nx">getInstance</span><span class="p">()</span>\n \n <span class="kd">const</span> <span class="nx">map</span> <span class="o">=</span> <span class="nx">repository</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="nx">marker</span><span class="p">.</span><span class="nx">mapId</span><span class="p">)</span>\n \n <span class="nx">map</span><span class="p">.</span><span class="nx">addMarker</span><span class="p">(</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span><span class="p">,</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="p">,</span>\n <span class="p">)</span>\n\n <span class="nx">repository</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">)</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>This class uses a singleton <code class="language-plaintext highlighter-rouge">PosgresqlMaps.getInstance()</code> to retrieve an instance of the <code class="language-plaintext highlighter-rouge">PosgresqlMaps</code> repository. This repository is in charge of saving map data into a PostgreSQL database. The problem is that we cannot run this code without a working database. This class is coupled to the <code class="language-plaintext highlighter-rouge">PosgresqlMaps</code> repository.</p>\n\n<p>We don’t want to use IO (your tools like a database) when we unit-test a piece of code because we want to avoid setting up any tools to a short feedback loop. We only want to check if a section of the application behaves as expected. We don’t want to test if the map data is well stored.</p>\n\n<p>Using the dependency inversion pattern will help us to remove the coupling between <code class="language-plaintext highlighter-rouge">AddMarkerToMap</code> and <code class="language-plaintext highlighter-rouge">PosgresqlMaps</code> and make it easy to unit test.</p>\n\n<p>First, we need to remove the coupling between both classes. We will create an abstraction to define how to retrieve and save maps in the application.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">Maps</span> <span class="p">{</span>\n <span class="kd">get</span><span class="p">(</span><span class="nx">mapId</span><span class="p">:</span> <span class="nx">MapId</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nb">Map</span><span class="o">&gt;</span><span class="p">;</span>\n <span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> When I cannot use a business term to name a repository I pluralize the name of my aggregate to name it. That’s why I name it <code class="language-plaintext highlighter-rouge">Maps</code> because I want to handle map aggregate persistence.</p>\n\n<p>Now, we can create as many implementations as we need. We will create a dedicated implementation for testing purposes. It will only keep it in memory which will avoid using a database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">InMemoryMaps</span> <span class="k">implements</span> <span class="nx">Maps</span> <span class="p">{</span>\n <span class="k">private</span> <span class="nx">maps</span><span class="p">:</span> <span class="nb">Record</span><span class="o">&lt;</span><span class="nx">MapId</span><span class="p">,</span> <span class="nb">Map</span><span class="o">&gt;</span><span class="p">;</span>\n \n <span class="k">async</span> <span class="kd">get</span><span class="p">(</span><span class="nx">mapId</span><span class="p">:</span> <span class="nx">MapId</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nb">Map</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">[</span><span class="nx">mapId</span><span class="p">];</span>\n <span class="p">}</span>\n\n <span class="k">async</span> <span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">[</span><span class="nx">map</span><span class="p">.</span><span class="nx">id</span><span class="p">()]</span> <span class="o">=</span> <span class="nx">map</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> I name all implementations with a prefix depending on what they are. If a repository uses a database, I will prefix the class with the name of the database. When I create an implementation for testing purposes, I use the <code class="language-plaintext highlighter-rouge">InMemory</code> prefix.</p>\n\n<p>As we want to create a working application, we will create an implementation which uses a database for the production environment.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">PosgresqlMaps</span> <span class="k">implements</span> <span class="nx">Maps</span> <span class="p">{</span>\n <span class="c1">// …</span>\n <span class="k">async</span> <span class="kd">get</span><span class="p">(</span><span class="nx">mapId</span><span class="p">:</span> <span class="nx">MapId</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nb">Map</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">map</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span>\n <span class="s2">`SELECT * FROM maps WHERE id = </span><span class="p">${</span><span class="nx">mapId</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span>\n <span class="p">);</span>\n\n\n <span class="k">return</span> <span class="k">new</span> <span class="nb">Map</span><span class="p">(</span><span class="nx">map</span><span class="p">);</span>\n <span class="p">}</span>\n \n <span class="k">async</span> <span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span>\n <span class="s2">`INSERT INTO maps VALUES (</span><span class="p">${</span><span class="nx">map</span><span class="p">.</span><span class="nx">toState</span><span class="p">()}</span><span class="s2">)`</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>We need to refactor a bit the <code class="language-plaintext highlighter-rouge">AddMarkerToMap</code> class to be able to inject an implementation of the <code class="language-plaintext highlighter-rouge">Maps</code> interface.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">AddMarkerToMap</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">maps</span><span class="p">:</span> <span class="nx">Maps</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="nx">execute</span><span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">map</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="nx">marker</span><span class="p">.</span><span class="nx">mapId</span><span class="p">)</span>\n\n\n <span class="nx">map</span><span class="p">.</span><span class="nx">addMarker</span><span class="p">(</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="p">,</span> <span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span>\n <span class="p">)</span>\n \n <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">)</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Finally, we can test this class because we can instantiate the <code class="language-plaintext highlighter-rouge">AddMarkerToMap</code> class with the <code class="language-plaintext highlighter-rouge">InMemoryMaps</code> class. This implementation helps us to test this class because it does not use any IO. Here, we don’t want to test if the data are well persisted but we want to test the business logic of marker addition on a map.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">adds a new marker to the map</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">maps</span> <span class="o">=</span> <span class="nx">InMemoryMaps</span><span class="p">()</span>\n \n <span class="k">new</span> <span class="nx">AddMarkerToMap</span><span class="p">(</span><span class="nx">maps</span><span class="p">).</span><span class="nx">execute</span><span class="p">({</span>\n <span class="na">mapId</span><span class="p">:</span> <span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">,</span> <span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Le Sunset</span><span class="dl">'</span><span class="p">,</span>\n <span class="na">latitude</span><span class="p">:</span> <span class="mf">23.252353245</span><span class="p">,</span> <span class="na">longitude</span><span class="p">:</span> <span class="mf">43.5432563457</span>\n <span class="p">})</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">maps</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span>\n <span class="k">new</span> <span class="nb">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nx">Marker</span><span class="p">(</span><span class="dl">'</span><span class="s1">Le Sunset</span><span class="dl">'</span><span class="p">,</span> <span class="mf">23.252353245</span><span class="p">,</span> <span class="mf">43.5432563457</span><span class="p">)</span>\n <span class="p">)</span>\n <span class="p">)</span>\n<span class="p">})</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> We don’t use a unit test to ensure the application uses its tools well. We use integration tests for this. For instance, if we want to ensure that a repository works as expected.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 19 Jun 2023 00:00:00 -0500\n https://arnolanglade.github.io/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html?s=feed\n https://arnolanglade.github.io/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html\n \n testing\n \n design-pattern\n \n OOP\n \n \n \n \n \n Use composition instead of props drilling\n <p>In this blog post, I would like to speak about how composition can improve your React codebase. It’s easy to add a lot of props to your component to make them configurable but it’s not a good idea.</p>\n\n<p>Let’s take an example. You are working on an e-Commerce webshop. A <code class="language-plaintext highlighter-rouge">ProductList</code> is used in the shop and the shop administration displays a list of products. In the shop administration, the component displays the product information and some calls to action (like product deletion and categorization for example) to manage products. In the shop you only need to display the product information, so, you don’t want to display the calls to action.</p>\n\n<p>As we can see in the next example, most of the <code class="language-plaintext highlighter-rouge">ProductList</code> props are used to render and configure the checkbox or the button.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductList</span><span class="p">({</span>\n <span class="nx">products</span><span class="p">,</span>\n <span class="nx">displayCheckbox</span><span class="p">,</span>\n <span class="nx">displayAction</span><span class="p">,</span>\n <span class="nx">actionLabel</span><span class="p">,</span>\n <span class="nx">onCheckboxClick</span><span class="p">,</span>\n <span class="nx">onActionClick</span><span class="p">,</span>\n<span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">products</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">product</span> <span class="o">=&gt;</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">displayCheckbox</span> <span class="o">&amp;&amp;</span>\n <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="p">=</span><span class="s">"checkbox"</span> <span class="na">onclick</span><span class="p">=</span><span class="si">{</span><span class="nx">onCheckboxClick</span><span class="si">}</span> <span class="p">/&gt;</span> <span class="p">:</span> <span class="kc">null</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">product</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">displayAction</span> <span class="o">&amp;&amp;</span>\n <span class="p">&lt;</span><span class="nt">button</span> <span class="na">onclick</span><span class="p">=</span><span class="si">{</span><span class="nx">onActionClick</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">actionLabel</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> <span class="p">:</span> <span class="kc">null</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n</code></pre></div></div>\n\n<p>This component is used in the <code class="language-plaintext highlighter-rouge">AdminShop</code>and <code class="language-plaintext highlighter-rouge">Shop</code> pages to display the product list to the customer or the shop owner.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Display to shop owner</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">AdminShop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getAllProducts</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span>\n <span class="na">products</span><span class="p">=</span><span class="si">{</span><span class="nx">products</span><span class="si">}</span>\n <span class="na">displayCheckbox</span><span class="p">=</span><span class="si">{</span><span class="kc">true</span><span class="si">}</span>\n <span class="na">displayAction</span><span class="p">=</span><span class="si">{</span><span class="kc">true</span><span class="si">}</span>\n <span class="na">actionLabel</span><span class="p">=</span><span class="s">"delete"</span>\n <span class="na">onCheckboxClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span>\n <span class="na">onActionClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span>\n <span class="p">/&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="c1">// Display to customers</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">Shop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getProductsAvailableforSale</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span>\n <span class="na">products</span><span class="p">=</span><span class="si">{</span><span class="nx">products</span><span class="si">}</span>\n <span class="na">displayCheckbox</span><span class="p">=</span><span class="si">{</span><span class="kc">false</span><span class="si">}</span>\n <span class="na">displayAction</span><span class="p">=</span><span class="si">{</span><span class="kc">false</span><span class="si">}</span>\n <span class="p">/&gt;</span>\n\n\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">ProductList</code> has to display elements depending on the given props. This big component will help mutualize the code but it will introduce complexity. Adding too many props will make your components complex, and hard to understand and maintain. Composition will help us to get rid of those props.</p>\n\n<p><strong>Note:</strong> The <code class="language-plaintext highlighter-rouge">ProductList</code> component only has 3 props because I wanted to keep the example simple but guess what happens when your components have tens of props to configure them?</p>\n\n<p>How can composition help us? It’s like playing Lego. You need several bricks from different sizes and colors to create something. The big <code class="language-plaintext highlighter-rouge">ProductList</code> component can be split into several small components used to build the product list depending on business cases.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductList</span><span class="p">({</span><span class="nx">children</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">children</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">Product</span><span class="p">({</span><span class="nx">label</span><span class="p">,</span> <span class="nx">checkbox</span><span class="p">,</span> <span class="nx">action</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">checkbox</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">label</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">action</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductCheckbox</span><span class="p">({</span><span class="nx">onClick</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="p">=</span><span class="s">"checkbox"</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span><span class="p">/&gt;;</span>\n<span class="p">}</span>\n\n\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductAction</span><span class="p">({</span><span class="nx">onClick</span><span class="p">,</span> <span class="nx">actionLabel</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">&lt;</span><span class="nt">button</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">actionLabel</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>In the previous code example, we created 4 new components: <code class="language-plaintext highlighter-rouge">ProductList</code>, <code class="language-plaintext highlighter-rouge">Product</code>, <code class="language-plaintext highlighter-rouge">ProductCheckbox</code> and <code class="language-plaintext highlighter-rouge">ProductAction</code>. They are like Lego bricks and we can assemble them to create the product list with or without the call to action.</p>\n\n<p><strong>Note:</strong> It’s not mandatory to create a dedicated component for the checkbox and the button. It can be useful to wrap generic components into more business-oriented ones. It helps to make things clearer. It’s another way to apply composition.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Display to shop owner</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">AdminShop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getAllProducts</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">products</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">product</span> <span class="o">=&gt;</span> \n <span class="p">&lt;</span><span class="nc">Product</span>\n <span class="na">label</span><span class="p">=</span><span class="si">{</span><span class="nx">product</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span>\n <span class="na">checkbox</span><span class="p">=</span><span class="si">{</span><span class="p">&lt;</span><span class="nc">ProductCheckbox</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span> <span class="p">/&gt;</span><span class="si">}</span>\n <span class="na">action</span><span class="p">=</span><span class="si">{</span><span class="p">&lt;</span><span class="nc">ProductAction</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span> <span class="na">actionLabel</span><span class="p">=</span><span class="si">{</span><span class="dl">"</span><span class="s2">delete</span><span class="dl">"</span><span class="si">}</span> <span class="p">/&gt;</span><span class="si">}</span>\n <span class="p">/&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="c1">// Display to customers</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">Shop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getProductAvailableforSale</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">products</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">product</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nc">Product</span> <span class="na">label</span><span class="p">=</span><span class="si">{</span><span class="nx">product</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span> <span class="p">/&gt;)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Small components are easier to test. They help build more stable applications and are easier to maintain. Your codebase will be less complex to understand. It will decrease your and your teammates’ mental load because you won’t have any components with complex API and logic.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 22 May 2023 00:00:00 -0500\n https://arnolanglade.github.io/use-composition-instead-of-props-drilling.html?s=feed\n https://arnolanglade.github.io/use-composition-instead-of-props-drilling.html\n \n react\n \n testing\n \n \n \n \n \n How to use custom React hook to increase application testability\n <p>In my previous blog, I spoke about reducing coupling in a React app to improve testing. Now I will show you how a custom React hook can increase testability.</p>\n\n<p><strong>Note:</strong> I assume that you are comfortable with React hooks. If you aren’t, please have a look at the <a href="https://reactjs.org/docs/hooks-intro.html">React documentation</a></p>\n\n<p>First of all, I will show you some code that is not testable. In my <a href="https://mymaps.world">side project</a>, I use <code class="language-plaintext highlighter-rouge">react-map-gl</code> to create maps with <a href="https://www.mapbox.com/">Mapbox</a>. Unfortunately, I can’t render the map with the testing library because this library only works in a web browser. I might have done something wrong but I haven’t found any solution to solve this problem.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">MapPage</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span><span class="nx">mapId</span><span class="p">}</span> <span class="o">=</span> <span class="nx">useParams</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">mapId</span><span class="p">:</span> <span class="kr">string</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">();</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">markers</span><span class="p">,</span> <span class="nx">setMarkers</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">isMarkerOpened</span><span class="p">,</span> <span class="nx">setIsMarkerOpened</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setMarkers</span><span class="p">(</span><span class="nx">getMarkers</span><span class="p">(</span><span class="nx">mapId</span><span class="p">));</span>\n <span class="p">},</span> <span class="p">[</span><span class="nx">mapId</span><span class="p">]);</span>\n\n\n <span class="kd">const</span> <span class="nx">openMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">closeMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;&gt;</span>\n <span class="p">&lt;</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">markers</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span>\n <span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nc">Marker</span>\n <span class="na">longitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span><span class="si">}</span>\n <span class="na">latitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="si">}</span>\n <span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerIcon</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">openMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">Marker</span><span class="p">&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerPopup</span> <span class="na">isOpened</span><span class="p">=</span><span class="si">{</span><span class="nx">isMarkerOpened</span><span class="si">}</span> <span class="na">onClose</span><span class="p">=</span><span class="si">{</span><span class="nx">closeMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/&gt;</span>\n <span class="p">)</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><code class="language-plaintext highlighter-rouge">MapPage</code> is in charge of loading map data depending on the <code class="language-plaintext highlighter-rouge">mapId</code> and rendering a map with its markers. I can’t test the <code class="language-plaintext highlighter-rouge">MapBoard</code> component because the <code class="language-plaintext highlighter-rouge">ReactMapGL</code> component can’t be rendered through the test tooling. That’s sad because I still want to check if I can open the marker popup when a user clicks on a marker.</p>\n\n<p>React will help us to fix this issue! We need to refactor this component to extract the business logic into a hook. This way, the component will only be responsible for rendering things. Let’s begin by creating the hooks.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="nx">mapId</span><span class="p">,</span> <span class="p">{</span><span class="nx">defaultIsMarkerOpened</span><span class="p">}</span> <span class="o">=</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">false</span><span class="p">})</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">markers</span><span class="p">,</span> <span class="nx">setMarkers</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">isMarkerOpened</span><span class="p">,</span> <span class="nx">setIsMarkerOpened</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="nx">defaultIsMarkerOpened</span><span class="p">);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setMarkers</span><span class="p">(</span><span class="nx">getMarkers</span><span class="p">(</span><span class="nx">mapId</span><span class="p">));</span>\n <span class="p">},</span> <span class="p">[</span><span class="nx">mapId</span><span class="p">]);</span>\n\n\n <span class="kd">const</span> <span class="nx">openMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">closeMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n\n\n <span class="k">return</span> <span class="p">{</span>\n <span class="nx">markers</span><span class="p">,</span>\n <span class="nx">isMarkerOpened</span><span class="p">,</span>\n <span class="nx">closeMarkerPopup</span><span class="p">,</span>\n <span class="nx">openMarkerPopup</span><span class="p">,</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n<p>The hook exposes two variables: <code class="language-plaintext highlighter-rouge">markers</code> which is an array of map’s markers and <code class="language-plaintext highlighter-rouge">isMarkerOpened</code> which is a boolean that indicates if the popup is opened or closed. It exposes two functions, <code class="language-plaintext highlighter-rouge">openMarkerPopup</code> and <code class="language-plaintext highlighter-rouge">closeMarkerPopup</code> that let us mutate the <code class="language-plaintext highlighter-rouge">isMarkerOpened</code> boolean.</p>\n\n<p><strong>Note:</strong> We could only expose <code class="language-plaintext highlighter-rouge">setIsMarkerOpened</code> but I think <code class="language-plaintext highlighter-rouge">openMarkerPopup</code> and <code class="language-plaintext highlighter-rouge">closeMarkerPopup</code> function names are clearer and match the component logic.</p>\n\n<p>Now, we need to call the hook from the <code class="language-plaintext highlighter-rouge">MapPage</code> component and it will still work as before.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">MapPage</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span>\n <span class="nx">markers</span><span class="p">,</span>\n <span class="nx">isMarkerOpened</span><span class="p">,</span>\n <span class="nx">closeMarkerPopup</span><span class="p">,</span>\n <span class="nx">openMarkerPopup</span>\n <span class="p">}</span> <span class="o">=</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="nx">mapId</span><span class="p">);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;&gt;</span>\n <span class="p">&lt;</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">markers</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span>\n <span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nc">Marker</span>\n <span class="na">longitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span><span class="si">}</span>\n <span class="na">latitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="si">}</span>\n <span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerIcon</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">openMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">Marker</span><span class="p">&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerPopup</span> <span class="na">isOpened</span><span class="p">=</span><span class="si">{</span><span class="nx">isMarkerOpened</span><span class="si">}</span> <span class="na">onClose</span><span class="p">=</span><span class="si">{</span><span class="nx">closeMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/&gt;</span>\n <span class="p">)</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">MapPage</code> is still untestable but we can start testing the hook to ensure hook logic matches business expectations. We can test if we can open a marker’s popup. That’s great because the testing library provides the <code class="language-plaintext highlighter-rouge">renderHook</code> helper that eases the hook testing.</p>\n\n<p><strong>Note:</strong> If you want to know how <code class="language-plaintext highlighter-rouge">renderHook</code> works you should have a look at this <a href="https://kentcdodds.com/blog/how-to-test-custom-react-hooks">blog post</a> written by <a href="https://twitter.com/kentcdodds">Kent C. Dodds</a>.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">describe</span><span class="p">(</span><span class="dl">'</span><span class="s1">Map Page</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">should open the marker popup</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span> <span class="nx">result</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">renderHook</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">useMapPage</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">false</span><span class="p">}</span>\n <span class="p">));</span>\n \n <span class="nx">act</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">openMarkerPopup</span><span class="p">());</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">isMarkerOpened</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n <span class="p">});</span>\n\n\n <span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">should close the marker popup</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span> <span class="nx">result</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">renderHook</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">useMapPage</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">true</span><span class="p">}</span>\n <span class="p">));</span>\n \n <span class="nx">act</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">closeMarkerPopup</span><span class="p">());</span>\n\n <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">isMarkerOpened</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n <span class="p">});</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>As I said at the beginning of this blog post I wrote a blog post to explain how to reduce coupling in a React application. Please, have a look at this <a href="/how-to-reduce-coupling-in-your-react-app.html">blog post</a> to understand how to make a dependency injection system.</p>\n\n<p>Now, we need to remove the <code class="language-plaintext highlighter-rouge">getMarkers</code> function call from the hooks if we want to test the map data loading. We don’t want to trigger side effects like HTTP calls in the unit test suite because we want to have the shortest feedback loop. We will get the <code class="language-plaintext highlighter-rouge">getMarkers</code> function to <code class="language-plaintext highlighter-rouge">useServiceContainer</code> which is a hook that provides any services.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="nx">mapId</span><span class="p">,</span> <span class="p">{</span><span class="nx">defaultIsMarkerOpened</span><span class="p">}</span> <span class="o">=</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">false</span><span class="p">})</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span><span class="nx">getMarkers</span><span class="p">}</span> <span class="o">=</span> <span class="nx">useServiceContainer</span><span class="p">();</span>\n <span class="c1">// ...</span>\n \n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setMarkers</span><span class="p">(</span><span class="nx">getMarkers</span><span class="p">(</span><span class="nx">mapId</span><span class="p">));</span>\n <span class="p">},</span> <span class="p">[</span><span class="nx">mapId</span><span class="p">]);</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>By default, the <code class="language-plaintext highlighter-rouge">useServiceContainer</code> hooks return the production services, we will need to replace the <code class="language-plaintext highlighter-rouge">getMarkers</code> service with a fake service for testing purposes. The <code class="language-plaintext highlighter-rouge">useServiceContainer</code> hooks can’t work without a React Provider. I like to create a factory that wraps components I test with all needed providers. It avoids a lot of noise in the test suites and makes tests more readable.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">const</span> <span class="nx">createWrapper</span> <span class="o">=</span> <span class="p">(</span><span class="nx">serviceContainer</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="kd">function</span> <span class="nx">Wrapper</span><span class="p">(</span>\n <span class="p">{</span> <span class="nx">children</span> <span class="p">}:</span> <span class="p">{</span> <span class="nl">children</span><span class="p">:</span> <span class="nx">ReactElement</span> <span class="p">},</span>\n<span class="p">)</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span> <span class="na">value</span><span class="p">=</span><span class="si">{</span><span class="nx">serviceContainer</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">};</span>\n</code></pre></div></div>\n\n<p>Note: the factory has a parameter which is the service container. It will let us define the services we want to override for testing.</p>\n\n<p>The <code class="language-plaintext highlighter-rouge">renderHook</code> has a <code class="language-plaintext highlighter-rouge">wrapper</code> option that lets you define the component that will wrap the hook you are testing. We will use the <code class="language-plaintext highlighter-rouge">createWrapper</code> factory to wrap the hook into the <code class="language-plaintext highlighter-rouge">ContainerContext</code> provider and we create a fake <code class="language-plaintext highlighter-rouge">getMarkers</code> service.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">describe</span><span class="p">(</span><span class="dl">'</span><span class="s1">Map Page</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">should load the markers of the map</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">markers</span> <span class="o">=</span> <span class="p">[{</span><span class="na">id</span><span class="p">:</span> <span class="dl">'</span><span class="s1">makerId</span><span class="dl">'</span><span class="p">}];</span>\n <span class="kd">const</span> <span class="p">{</span> <span class="nx">result</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">renderHook</span><span class="p">(</span>\n <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">),</span>\n <span class="p">{</span><span class="na">wrapper</span><span class="p">:</span> <span class="nx">createWrapper</span><span class="p">({</span><span class="na">getMarkers</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">markers</span><span class="p">})}</span>\n <span class="p">);</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">markers</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="nx">markers</span><span class="p">);</span>\n <span class="p">});</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>Now, the <code class="language-plaintext highlighter-rouge">getMarkers</code> is predictable. That means we can test the map loading because the <code class="language-plaintext highlighter-rouge">getMarker</code> function will return <code class="language-plaintext highlighter-rouge">[{id: 'makerId'}]</code> every time.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 04 Apr 2023 00:00:00 -0500\n https://arnolanglade.github.io/how-to-use-custom-react-hook-to-increase-application-testability.html?s=feed\n https://arnolanglade.github.io/how-to-use-custom-react-hook-to-increase-application-testability.html\n \n react\n \n testing\n \n \n \n \n \n How to reduce coupling in your React app\n <p>Today, I would like to cover dependency injection in React. I worked with several frameworks using tools to build and inject dependencies. It is pretty convenient if you apply the dependency inversion principle because you can easily change a dependency with another one.</p>\n\n<p>I will start by briefly introducing what is a React Context and I will then show you how to solve coupling problems in a React application.</p>\n\n<h2 id="what-is-a-react-context">What is a React Context?</h2>\n\n<blockquote>\n <p>Context provides a way to pass data through the component tree without having to pass props down manually at every level.</p>\n\n <p><a href="https://reactjs.org/docs/context.html">React documentation</a></p>\n</blockquote>\n\n<p>Let’s take an example: several components display the username of the user who is connected. We have to pass the username as props to every application component that needs this information. It is annoying, but React context can help for this specific use case.</p>\n\n<p>First, we need to create a context:</p>\n\n<p>```ts self-taught\nconst UserContext = React.createContext<string>();</string></p>\n<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\nThen, we need to wrap our components using a context provider and give it a value. The value is the data we want to share with the provider’s children components.\n\n```tsx\nfunction App() {\n return (\n &lt;UserContext.Provider value={'arn0'}&gt;\n &lt;Toolbar /&gt;\n &lt;OtherComponent /&gt;\n &lt;/UserContext.Provider&gt;\n );\n}\n</code></pre></div></div>\n\n<p>Finally, we can get this value (the username) from the context thanks to the useContext hooks.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">Toolbar</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">username</span> <span class="o">=</span> <span class="nx">useContext</span><span class="p">(</span><span class="nx">UserContext</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>\n Welcome <span class="si">{</span><span class="nx">username</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n</code></pre></div></div>\n<h2 id="which-problems-coupling-brings">Which problems coupling brings?</h2>\n\n<blockquote>\n <p>Coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)">Wikipedia</a></p>\n</blockquote>\n\n<p>The developer’s worst enemy is <strong>coupling</strong> because it makes your code less testable. To illustrate what I am saying we will take an example: a to-do list application. The <code class="language-plaintext highlighter-rouge">TodoList</code> component is responsible for retrieving data from the server and building the list of tasks to do.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">findTasks</span> <span class="o">=</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/tasks</span><span class="dl">'</span><span class="p">);</span>\n<span class="p">}</span>\n\n<span class="kd">function</span> <span class="nx">TodoList</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">setTasks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="o">&lt;</span><span class="nx">Task</span><span class="p">[]</span><span class="o">&gt;</span><span class="p">([]);</span>\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="p">(</span><span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">findTasks</span><span class="p">();</span>\n <span class="nx">setTasks</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>\n <span class="p">})();</span>\n <span class="p">},</span> <span class="p">[]);</span>\n \n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">task</span><span class="p">:</span> <span class="nx">Task</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nt">li</span> <span class="na">key</span><span class="p">=</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The problem with the <code class="language-plaintext highlighter-rouge">TodoList</code> component is that it depends on the <code class="language-plaintext highlighter-rouge">axios</code> library to get data from the server. It does not ease testing because we need to set up the server to make this component work. Unit testing requires a short feedback loop! We need to find a way to get rid of this HTTP call. It would be great to be able to do HTTP calls in production but using stub for testing.</p>\n\n<h2 id="how-react-context-reduces-coupling">How React Context reduces coupling?</h2>\n\n<p>The problem with the <code class="language-plaintext highlighter-rouge">TodoList</code> component is that we should be able to use several implementations of the <code class="language-plaintext highlighter-rouge">findTasks</code>, but we can’t with its design. We need an implementation for the production that will make an HTTP call and another one for testing that will return stub.</p>\n\n<p>The <code class="language-plaintext highlighter-rouge">findTasks</code> function should not be hardcoded but it should be injected as a component dependency. A React Context will help us to solve that issue.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">ServiceContainer</span> <span class="o">=</span> <span class="p">{</span><span class="na">findTasks</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nx">Task</span><span class="o">&gt;</span><span class="p">};</span>\n\n<span class="kd">const</span> <span class="nx">ContainerContext</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createContext</span><span class="o">&lt;</span><span class="nx">ServiceContainer</span><span class="o">&gt;</span><span class="p">({}</span> <span class="k">as</span> <span class="nx">ServiceContainer</span><span class="p">);</span>\n\n<span class="k">export</span> <span class="kd">const</span> <span class="nx">useServiceContainer</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">useContext</span><span class="p">(</span><span class="nx">ContainerContext</span><span class="p">);</span>\n\n<span class="kd">const</span> <span class="nx">findTasks</span> <span class="o">=</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/tasks</span><span class="dl">'</span><span class="p">);</span>\n<span class="p">}</span>\n\n<span class="kd">function</span> <span class="nx">App</span><span class="p">()</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span> <span class="na">value</span><span class="p">=</span><span class="si">{</span><span class="nx">findTasks</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">TodoList</span><span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">ServiceContainer</code> type represents all services we want to register in our application. The <code class="language-plaintext highlighter-rouge">ContainerContext</code> will share those services with <code class="language-plaintext highlighter-rouge">ContainerContext.Provider</code> children.</p>\n\n<p>Then, we only need to get the <code class="language-plaintext highlighter-rouge">findTasks</code> function from the React Context.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">TodoList</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span><span class="nx">findTasks</span><span class="p">}</span> <span class="o">=</span> <span class="nx">useServiceContainer</span><span class="p">();</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">setTasks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="o">&lt;</span><span class="nx">Task</span><span class="p">[]</span><span class="o">&gt;</span><span class="p">([]);</span>\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="p">(</span><span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">findTasks</span><span class="p">();</span>\n <span class="nx">setTasks</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>\n <span class="p">})();</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">task</span><span class="p">:</span> <span class="nx">Task</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nt">li</span> <span class="na">key</span><span class="p">=</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, the code is testable because we can easily replace the <code class="language-plaintext highlighter-rouge">findTasks</code> by stub in the test suite. We can easily set up a test because this new function does not use HTTP calls.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">render the todo list</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">render</span><span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span> <span class="na">value</span><span class="p">=</span><span class="si">{</span>\n <span class="p">{</span> <span class="na">findTasks</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">({</span><span class="na">id</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="na">label</span><span class="p">:</span> <span class="dl">'</span><span class="s1">label</span><span class="dl">'</span><span class="p">})</span> <span class="p">}</span>\n <span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">TodoList</span><span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span><span class="p">&gt;</span>\n <span class="p">)</span>\n\n <span class="c1">// …</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 06 Mar 2023 00:00:00 -0600\n https://arnolanglade.github.io/how-to-reduce-coupling-in-your-react-app.html?s=feed\n https://arnolanglade.github.io/how-to-reduce-coupling-in-your-react-app.html\n \n react\n \n design-patterns\n \n \n \n \n \n What is the difference between CQS and CQRS patterns?\n <p>I recently found out that I did not grasp those design patterns. There are a lot of resources on the Internet about them but they are not always accurate. That’s a shame because they are pretty simple. I will share my understanding of them with you.</p>\n\n<h2 id="what-is-command-query-segregation-cqs">What is Command Query Segregation (CQS)?</h2>\n\n<blockquote>\n <p>The fundamental idea is that we should divide an object’s methods into two sharply separated categories:</p>\n <ul>\n <li>Queries: Return a result and do not change the observable state of the system (are free of side effects).</li>\n <li>Commands: Change the state of a system but do not return a value.</li>\n </ul>\n\n <p><a href="https://martinfowler.com/bliki/CommandQuerySeparation.html">Martin Fowler</a></p>\n</blockquote>\n\n<p>This concept is not specific to Object Oriented Programming but improves the object’s design. The object methods only have a single purpose: reading or changing the object state. We can see an object as a living entity. We can ask a question to someone because we need information. For example, we can ask someone what time it is. This is a query. We can ask someone to do something, we don’t expect an answer but we want to get the job done. For example, we can ask a child to finish his/her spinach. This is a command.</p>\n\n<p>We can apply this pattern to any object: like an aggregate. Let’s take an example! I would like to add markers on a map and then I would like to find which markers are the closest to a specific location (GPS Coordinates).\nk</p>\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nb">Map</span> <span class="p">{</span>\n <span class="nx">addMarker</span><span class="p">(</span><span class="nx">label</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">latitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="k">void</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n\n <span class="nx">findClosestMarkers</span><span class="p">(</span><span class="nx">location</span><span class="p">:</span> <span class="nx">Location</span><span class="p">):</span> <span class="nx">Marker</span><span class="p">[]</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">addMarker</code> method is in charge of mutating the object state without returning any result, while the ‘findClosestMarkers’ method finds the right markers without changing the object’s state. This object follows the CQS definition.</p>\n\n<p>Let’s go further. If we design our aggregates following the CQS pattern, we should apply it to the classes that handle use cases.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">MapService</span> <span class="p">{</span>\n <span class="nx">addMarkerToTheMap</span><span class="p">(</span><span class="nx">label</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">latitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">);</span> <span class="k">void</span>\n <span class="nx">findAllMarkersCloseToLocation</span><span class="p">():</span> <span class="nx">Marker</span><span class="p">[]</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>This ensures there is no inconsistency in the codebase. The business services use and manipulate the aggregates. For example, if the <code class="language-plaintext highlighter-rouge">MapService.addMarkerToTheMap</code> method returns a result, it might mean that the <code class="language-plaintext highlighter-rouge">Map.addMarker</code> method will need to return the expected result.</p>\n\n<h2 id="what-is-command-query-responsibility-segregation-cqrs">What is Command Query Responsibility Segregation (CQRS)?</h2>\n\n<blockquote>\n <p>Starting with CQRS, CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).</p>\n\n <p><a href="https://web.archive.org/web/20190211113420/http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-sourcing-agh/">Greg Young</a></p>\n</blockquote>\n\n<p><strong>Note:</strong> Greg Young’s blog does not exist anymore but his blog posts are still available thanks to archived.org.</p>\n\n<p>CQRS is the separation of command and query into two different objects instead of only one. MapService does not follow the CQRS pattern because it has a query and a command. We need to cut this object in half.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">MapReadService</span> <span class="p">{</span>\n <span class="nx">addMarkerToTheMap</span><span class="p">(</span><span class="nx">label</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">latitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">);</span> <span class="k">void</span>\n<span class="p">}</span>\n\n<span class="kr">interface</span> <span class="nx">MapWriteService</span> <span class="p">{</span>\n <span class="nx">findAllMarkersCloseToLocation</span><span class="p">():</span> <span class="nx">Marker</span><span class="p">[]</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>That’s pretty simple, right? Anyway, we don’t need to introduce complicated things in our application to use this tactical design pattern. We don’t need a write and a read model,\na command and query bus, an event sourcing architecture or multiple databases. Greg Young published this blog post in 2012 to explain what CQRS was not about.</p>\n\n<blockquote>\n <p>CQRS is not a silver bullet</p>\n\n <p>CQRS is not a top level architecture</p>\n\n <p>CQRS is not new</p>\n\n <p>CQRS is not shiny</p>\n\n <p>CQRS will not make your jump shot any better</p>\n\n <p>CQRS is not intrinsically linked to DDD</p>\n\n <p>CQRS is not Event Sourcing</p>\n\n <p>CQRS does not require a message bus</p>\n\n <p>CQRS is not a guiding principle / CQS is</p>\n\n <p>CQRS is not a good wife</p>\n\n <p>CQRS is learnable in 5 minutes</p>\n\n <p>CQRS is a small tactical pattern</p>\n\n <p>CQRS can open many doors.</p>\n</blockquote>\n\n<p><strong>Note:</strong> This blog does not exist anymore but it has been archived by archived.org. The post is available <a href="https://web.archive.org/web/20160729165044/https://goodenoughsoftware.net/2012/03/02/cqrs/">here</a></p>\n\n<p>Depending on the number of use cases the service classes can become really huge. CQRS helps to decrease their size but I am a big fan of them. I like to separate each use case into a dedicated class.</p>\n\n<p>I’ve written a blog post to explain what is a commands and we can apply it to query too:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-handler-patterns.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-handler/command-handler.webp" alt="Command and command handler design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Command and command handler design pattern</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 06 Feb 2023 00:00:00 -0600\n https://arnolanglade.github.io/what-is-the-difference-between-cqs-and-cqrs-patterns.html?s=feed\n https://arnolanglade.github.io/what-is-the-difference-between-cqs-and-cqrs-patterns.html\n \n software-architecture\n \n design-patterns\n \n \n \n \n \n Hexagonal architecture by example\n <p>In this blog post, I would like to explain the basics of hexagonal architecture thanks to a simple example: a product catalogue. The catalogue manager can add new products through a user interface and the nightly cron task imports new products from the ERP.</p>\n\n<p>Before going deeper into hexagonal architecture, let’s see what we need to create the product management application. We need two entry points: the first one will be consumed by the graphical client and the other one will be used by the cron task. Then, we will need another piece of code which will be in charge of persisting product data into storage.</p>\n\n<p><img src="images/posts/hexagonal-architecture/application-architecture.svg" alt="Application architecture" /></p>\n\n<h2 id="what-is-hexagonal-architecture">What is hexagonal architecture?</h2>\n\n<blockquote>\n <p>The hexagonal architecture, or ports and adapters architecture, is an architectural pattern used in software design. It aims at creating loosely coupled application components that can be easily connected to their software environment by means of ports and adapters. This makes components exchangeable at any level and facilitates test automation.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Hexagonal_architecture_(software)">Wikipedia</a></p>\n</blockquote>\n\n<p>There are three main areas in the hexagonal architecture:\nThe <strong>primary adapters (user interface)</strong> are the whole application entry points that can be consumed by clients like a UI or a CLI.\nThe <strong>secondary adapters (infrastructure)</strong> connect the application to tools like the database, file system, etc.\nThe <strong>domain</strong> is all pieces of code that represent the problem we are solving. This part must be side-effect free (it must not use any tools).</p>\n\n<h2 id="domain">Domain</h2>\n\n<p>The domain is the area where we solve our business problems no matter the technical constraints. We can start by designing the product aggregate.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Name</span> <span class="o">=</span> <span class="kr">string</span><span class="p">;</span>\n<span class="kd">type</span> <span class="nx">Description</span> <span class="o">=</span> <span class="kr">string</span><span class="p">;</span>\n\n<span class="k">export</span> <span class="kd">class</span> <span class="nx">Product</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">name</span><span class="p">:</span> <span class="nx">Name</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">description</span><span class="p">:</span> <span class="nx">Description</span>\n <span class="p">)</span> <span class="p">{}</span>\n\n <span class="nx">toState</span><span class="p">():</span> <span class="kr">string</span><span class="p">[]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">description</span><span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>As I said, we need to save products into the database but we don’t mind if the database is PostgreSQL, MySQL or whatever in the domain. We will define an <strong>abstraction (an interface)</strong> to avoid accessing any technical asset from the domain. This interface which is called a <strong>port</strong> will specify how to store a new product from a business point of view. This is nothing more than applying the dependency inversion design pattern.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kr">interface</span> <span class="nx">ProductCatalog</span> <span class="p">{</span>\n <span class="nx">add</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="k">void</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h3 id="what-about-testing">What about testing?</h3>\n\n<p>Moving IO as far as possible from your domain code is really convenient because it eases unit testing. We will mainly test this part of the application with unit testing. It offers a very short feedback loop, it will help you to design your domain step by step without setting up the whole application.</p>\n\n<p><strong>Tip:</strong> I’ve written a blog post about unit testing that explains why testing can be hard. It mainly gives you tips to move IO outside your code to make it testable.</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="why-unit-testing-can-be-hard.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/why-unit-testing-can-be-hard.webp" alt="Why unit testing can be hard?" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Why unit testing can be hard?</span>\n </span>\n </a>\n</div>\n\n<h3 id="coupling-rules">Coupling rules</h3>\n\n<p>The domain code must not use any IO: any tools like your database, randomness, or actual datetime, nor depend on the primary and the secondary adapters. We will explain what they are in the next sections.</p>\n\n<h2 id="secondary-adapters-infrastructure">Secondary adapters (Infrastructure)</h2>\n\n<p>The secondary or driven adapters implement the ports defined in the domain. In our example, the adapter will be a <code class="language-plaintext highlighter-rouge">PostgresProductCatalog</code> class that implements the <code class="language-plaintext highlighter-rouge">ProductCatalog</code> interface (port). Its purpose will be to store product data in a database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">PostgresProductCatalog</span> <span class="k">implements</span> <span class="nx">ProductCatalog</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">pg</span><span class="p">:</span> <span class="nx">Client</span><span class="p">)</span> <span class="p">{}</span>\n\n <span class="nx">add</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">pg</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">INSERT INTO product (name, properties) VALUES ($1, $2)</span><span class="dl">'</span><span class="p">,</span>\n <span class="nx">product</span><span class="p">.</span><span class="nx">toState</span><span class="p">()</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>An advantage of this architecture is that we can simply delay choices. At the beginning of a project, it may be hard to choose the right tools because you still need to learn and understand the business. In that case, you can implement an in-memory adapter, it will work the same way as the previous one but it will only keep product aggregate in memory.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">InMemoryProductCatalog</span> <span class="k">implements</span> <span class="nx">ProductCatalog</span> <span class="p">{</span>\n <span class="k">private</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[];</span>\n\n <span class="nx">add</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">products</span> <span class="o">=</span> <span class="p">[</span><span class="nx">product</span><span class="p">,</span> <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">products</span><span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> This adapter can be used in your test suites because it lets you bypass your tools constraints like foreign key constraints when we use a database, for instance.</p>\n\n<h3 id="what-about-testing-1">What about testing?</h3>\n\n<p>The part of the application is mainly covered by “integration” or “contract” tests. Those tests ensure that the tools used by the application work as expected. For example, you are able to save and query your database.</p>\n\n<p><strong>Tip:</strong> I encourage you to test all implementations of a given port with the same test because it will ensure they work the same way.</p>\n\n<h3 id="coupling-rules-1">Coupling rules</h3>\n\n<p>The infrastructure code only depends on the domain code.</p>\n\n<h2 id="primary-adapters-user-interface">Primary adapters (User interface)</h2>\n\n<p>The primary adapters or driving adapters are entry points that describe how the application is consumed by the clients. Their purpose is to tell the domain what to do. Actually, it can be a Web controller or CLI command for instance.</p>\n\n<p>In our example, we need two adapters: a web controller and a CLI command. Both of them will execute the same action, they will save product data but they have different input and output. The first one takes JSON and returns an HTTP response and the second one takes input and returns code status.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">try</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">productCatalog</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="k">new</span> <span class="nx">Product</span><span class="p">(</span>\n <span class="nx">request</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">),</span> <span class="c1">// get name argument for cli command</span>\n <span class="nx">request</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">description</span><span class="dl">'</span><span class="p">),</span> <span class="c1">// get description argument for cli command</span>\n <span class="p">))</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">HttpResponse</span><span class="p">(</span><span class="mi">201</span><span class="p">);</span> <span class="c1">// return 0 for cli command</span>\n<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nb">Error</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nx">HttpResponse</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span> <span class="c1">// return 1 for cli command</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>As you see, the only differences are the input and output of the adapter. We need to refactor this code to avoid duplication between both primary adapters. It should be extracted into a dedicated business service.</p>\n\n<p><strong>Tip:</strong> These business services can be written using the command and command handler patterns. I’ve written a blog post that explains these design patterns:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-handler-patterns.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-handler/command-handler.webp" alt="Command and command handler design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Command and command handler design pattern</span>\n </span>\n </a>\n</div>\n\n<p>I’ve written a bunch of articles about how to handle a command, validate its data, handle user permissions, and so on. Take a look at these articles:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/tag/command-bus">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/data-validation.webp" alt="See all blog posts about command handling." />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">See all blog posts about command handling.</span>\n </span>\n </a>\n</div>\n\n<h3 id="what-about-testing-2">What about testing?</h3>\n\n<p>There are several ways to test primary adapters.</p>\n\n<p>First option: the easiest one, your application only has one primary adapter. I advise you to write an acceptance test that boots the application and checks that the whole application works for each business use case.</p>\n\n<p>Second option: the complex one, your application has several primary adapters like our example (web and CLI). I advise you to check that your command handler works as expected thanks to an acceptance. That way you ensure your handler will work as expected for both adapters. Thus, you can write a test to ensure that the adapters return the right output (HTTP response or code status) depending on the case.</p>\n\n<h3 id="coupling-rules-2">Coupling rules</h3>\n\n<p>The user interface code only depends on the domain code.</p>\n\n<h2 id="flow-of-control">Flow of control</h2>\n\n<p><img src="images/posts/hexagonal-architecture/hexgonal-architecture-flow-control.svg" alt="Hexgonal architecture: flow control" /></p>\n\n<p>The application flow goes from the user interface <strong>(1)</strong> through the domain <strong>(2)</strong> to the infrastructure <strong>(3)</strong> then goes back through the domain <strong>(2)</strong> to the user interface <strong>(4)</strong>.</p>\n\n<p>Example: The UI sends data to an HTTP controller <strong>(1)</strong>, then a product aggregate is created <strong>(2)</strong>, then the repository saves data into the database <strong>(3)</strong>, and finally the web controller sends a 200 HTTP response <strong>(4)</strong>. We don’t need step <strong>(2)</strong> because nothing happens in the domain after the product creation.</p>\n\n<h2 id="code-organization">Code organization</h2>\n\n<p>The <strong>domain</strong> contains the aggregates, ports, business services and so on. Most importantly, they must not use IO and must be business oriented.</p>\n\n<p>The <strong>infrastructure</strong> contains all secondary adapters that use external tools (IO) like your database.</p>\n\n<p>The <strong>user interface</strong> contains all primary adapters that are the application entry points. Users and machines use them to interact with the application.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>src\n├── domain\n│ ├── ProductCatalog.ts\n│ └── Product.ts\n├── infra\n│ ├── InMemoryProductCatalog.ts\n│ └── PostgresProductCatalog.ts\n└── user-interface\n ├── CliCreateProduct.ts\n └── WebCreateProduct.ts\n</code></pre></div></div>\n\n<p><strong>Note:</strong> I decided to split each class/interface into a dedicated module because I wanted to show you where things are. Feel free to organize your module as you wish.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 09 Jan 2023 00:00:00 -0600\n https://arnolanglade.github.io/hexagonal-architect-by-example.html?s=feed\n https://arnolanglade.github.io/hexagonal-architect-by-example.html\n \n software-architecture\n \n \n \n \n \n What is the event sourcing pattern?\n <p>Event sourcing consists in storing all changes that happened to an application as a sequence of events instead of only storing the current state of the application. The sum of all events is the current application state. When I heard about this pattern a few years ago, I was really confused. I used to only persist the current application state in a database and that was fine! So I asked myself do I need that?</p>\n\n<p>I will show you an example to help you understand what this pattern stands for. People used to explain it with a bank account but I wanted to find something funnier: a table soccer game. A complete example is available on a Github repository:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="https://github.com/arnolanglade/table-soccer">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/github-logo.png" alt="Have a look at the GitHub repository" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Have a look at the GitHub repository</span>\n </span>\n </a>\n</div>\n\n<p>Let’s start! A group of developers who are fans of table soccer wants to create an application to see who’s the best player. They decided to save the results of matches and rank themselves.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">redTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">blueTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">gameScore</span><span class="p">:</span> <span class="nx">Score</span><span class="p">,</span>\n <span class="p">)</span> <span class="p">{}</span>\n\n <span class="k">public</span> <span class="nx">recordScore</span><span class="p">(</span><span class="nx">redPlayerScore</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">bluePlayerScore</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">,</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">,</span>\n <span class="k">new</span> <span class="nx">Score</span><span class="p">(</span><span class="nx">redPlayerScore</span><span class="p">,</span> <span class="nx">bluePlayerScore</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n\n <span class="c1">// example: ['arn0', 'momos', 'Popeye', 'coco', 10, 1]</span>\n <span class="k">public</span> <span class="nx">toState</span><span class="p">():</span> <span class="p">[</span><span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">,</span> <span class="kr">number</span><span class="p">,</span> <span class="kr">number</span><span class="p">]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">[</span>\n <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">.</span><span class="nx">toState</span><span class="p">(),</span>\n <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">.</span><span class="nx">toState</span><span class="p">(),</span>\n <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">gameScore</span><span class="p">.</span><span class="nx">toState</span><span class="p">()</span>\n <span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">Game</code> Aggregate has a <code class="language-plaintext highlighter-rouge">recordScore</code> method to record the score at the end of the game. Then we get the current state of <code class="language-plaintext highlighter-rouge">Game</code> with the <code class="language-plaintext highlighter-rouge">toState</code> method to save it in the database.</p>\n\n<p>That works perfectly for the one versus one games but what happens for two versus two games? Let’s focus on one of the players, we will call him Popeye. Actually, Popeye is not a really good player even if he is full of goodwill. He is smart, he always wants to play with the best player to have more chances to win. We cannot know who is the best player with only the result of the game. Who has really scored? Popeye or its teammate?</p>\n\n<p>Event sourcing is the solution. Instead of saving the score of the game, we will store what really happens. We will refactor the <code class="language-plaintext highlighter-rouge">Game</code> aggregate to make it compliant with the event sourcing pattern.</p>\n\n<p>First, we will rework the aggregate construction. We still want to encapsulate its current state but we want to record all events that happened too. In the following example, we added an <code class="language-plaintext highlighter-rouge">events</code> argument to the primary constructor and a named constructor (secondary construct) called <code class="language-plaintext highlighter-rouge">start</code> to the <code class="language-plaintext highlighter-rouge">Game</code> class. From a business point of view, its goal is to initialize the game and from a technical point of view, it lets us record the <code class="language-plaintext highlighter-rouge">GameStarted</code> event.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">redTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">blueTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">gameScore</span><span class="p">:</span> <span class="nx">Score</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">events</span><span class="p">:</span> <span class="nx">Event</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[]</span>\n <span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">public</span> <span class="k">static</span> <span class="nx">start</span><span class="p">(</span>\n <span class="nx">redAttacker</span><span class="p">:</span> <span class="nx">Player</span><span class="p">,</span>\n <span class="nx">redDefender</span><span class="p">:</span> <span class="nx">Player</span><span class="p">,</span>\n <span class="nx">blueAttacker</span><span class="p">:</span> <span class="nx">Player</span><span class="p">,</span>\n <span class="nx">blueDefender</span><span class="p">:</span> <span class="nx">Player</span>\n <span class="p">):</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">redTeam</span> <span class="o">=</span> <span class="nx">Team</span><span class="p">.</span><span class="nx">ofTwoPlayer</span><span class="p">(</span><span class="nx">redAttacker</span><span class="p">,</span> <span class="nx">redDefender</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">blueTeam</span> <span class="o">=</span> <span class="nx">Team</span><span class="p">.</span><span class="nx">ofTwoPlayer</span><span class="p">(</span><span class="nx">blueAttacker</span><span class="p">,</span> <span class="nx">blueDefender</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span>\n <span class="nx">redTeam</span><span class="p">,</span>\n <span class="nx">blueTeam</span><span class="p">,</span>\n <span class="nx">Score</span><span class="p">.</span><span class="nx">playersHaveNotScored</span><span class="p">(),</span>\n <span class="p">[</span><span class="k">new</span> <span class="nx">GameStarted</span><span class="p">(</span><span class="nx">redTeam</span><span class="p">,</span> <span class="nx">blueTeam</span><span class="p">)],</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then we will add a new method to <code class="language-plaintext highlighter-rouge">Game</code> to record all goals scored by any players. That will let us know who is the best striker in the game. In the following example, we record two events: <code class="language-plaintext highlighter-rouge">GoalScored</code> and <code class="language-plaintext highlighter-rouge">GameEnded</code>. The first one is recorded every time a player scores and the second one is recorded when the first team has 10 points meaning the game is over.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span> \n <span class="c1">// …</span>\n <span class="k">public</span> <span class="nx">goalScoredBy</span><span class="p">(</span><span class="nx">player</span><span class="p">:</span> <span class="nx">Player</span><span class="p">):</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">teamColor</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">.</span><span class="nx">isTeammate</span><span class="p">(</span><span class="nx">player</span><span class="p">)</span> <span class="p">?</span> <span class="nx">TeamColor</span><span class="p">.</span><span class="nx">Red</span> <span class="p">:</span> <span class="nx">TeamColor</span><span class="p">.</span><span class="nx">Blue</span><span class="p">;</span>\n <span class="kd">const</span> <span class="nx">gameScore</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">gameScore</span><span class="p">.</span><span class="nx">increase</span><span class="p">(</span><span class="nx">teamColor</span><span class="p">);</span>\n\n <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">GoalScored</span><span class="p">(</span><span class="nx">teamColor</span><span class="p">,</span> <span class="nx">player</span><span class="p">,</span> <span class="nx">gameScore</span><span class="p">))</span>\n\n <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">gameScore</span><span class="p">.</span><span class="nx">canIncrease</span><span class="p">(</span><span class="nx">teamColor</span><span class="p">))</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">GameEnded</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">,</span> <span class="nx">gameScore</span><span class="p">))</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">,</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">,</span>\n <span class="nx">gameScore</span><span class="p">,</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">,</span>\n <span class="p">);</span>\n <span class="p">}</span>\n <span class="c1">// …</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> We can drop the <code class="language-plaintext highlighter-rouge">recordScore</code> method because we won’t want to only record the score of the game at the end of the game.</p>\n\n<p>Finally, the last thing to refactor is the persistence mechanism. We need to rework the <code class="language-plaintext highlighter-rouge">toState</code> because we won’t store a snapshot of the <code class="language-plaintext highlighter-rouge">Game</code> state but we want to save all events raised during the game. This method will return all serialized events and metadata like the name of the aggregate. Normally, we should persist some extra metadata like the aggregate id or the date when the event has been raised. Then, those data will be used in the <code class="language-plaintext highlighter-rouge">Game</code> repository to persist changes in the database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span> \n <span class="c1">// …</span>\n <span class="k">public</span> <span class="nx">toState</span><span class="p">():</span> <span class="p">[[</span><span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">]]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">event</span><span class="p">:</span> <span class="nx">Event</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="dl">'</span><span class="s1">Game</span><span class="dl">'</span><span class="p">,</span> <span class="nx">event</span><span class="p">.</span><span class="nx">toState</span><span class="p">()]);</span>\n <span class="p">}</span>\n <span class="c1">// …</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Last thing, we will add a named constructor to be able to build the object from the persisted state (a list of events). The <code class="language-plaintext highlighter-rouge">fromEvents</code> will iterate on all events to compute and set the current state of a game.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span> \n <span class="c1">// …</span>\n <span class="k">public</span> <span class="k">static</span> <span class="nx">fromEvents</span><span class="p">(</span><span class="nx">events</span><span class="p">:</span> <span class="nx">Event</span><span class="p">[]):</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">let</span> <span class="nx">redTeam</span><span class="p">,</span> <span class="nx">blueTeam</span><span class="p">,</span> <span class="nx">score</span><span class="p">;</span>\n <span class="nx">events</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">event</span><span class="p">:</span> <span class="nx">Event</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">switch</span> <span class="p">(</span><span class="kc">true</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">case</span> <span class="nx">event</span> <span class="k">instanceof</span> <span class="na">GameStarted</span><span class="p">:</span>\n <span class="nx">redTeam</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">;</span>\n <span class="nx">blueTeam</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">;</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="k">case</span> <span class="nx">event</span> <span class="k">instanceof</span> <span class="na">GameEnded</span><span class="p">:</span>\n <span class="nx">score</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">score</span><span class="p">;</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="p">});</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span><span class="nx">redTeam</span><span class="p">,</span> <span class="nx">blueTeam</span><span class="p">,</span> <span class="nx">score</span><span class="p">,</span> <span class="nx">events</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="c1">// …</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, we have all the data we need to know if Popeye really helps his teammate. In the following code example, we can see that Momos and arn0 were not in a good shape. Coco and Popeye won easily but we can see that Popeye did not score. Perhaps, he is a good defender, who knows?</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">game</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">startTwoVersusTwo</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Popeye</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n</code></pre></div></div>\n\n<p>I explained to you how to save <code class="language-plaintext highlighter-rouge">Game</code> aggregate events and create the aggregate from events in the previous sections of the blog post. The last missing feature is the leaderboard! How to create it? It won’t be as simple as querying a SQL table in the database because we need to get all game events for each game and compute them to know who is the better striker. Even though it can be fast in the beginning, the more games you have, the longer it will be.</p>\n\n<p>To prevent this problem, we need to create data projections. That means we will compute a representation of the data we want to query from the event stream. We will compute the new projection of the leaderboard each time a game ends.</p>\n\n<p>Last but not least, We often associate CQRS with the event sourcing pattern even if there are two different patterns.</p>\n\n<p>Don’t forget that a complete example is available on a Github repository.</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="https://github.com/arnolanglade/table-soccer">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/github-logo.webp" alt="Have a look at the GitHub repository" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Have a look at the GitHub repository</span>\n </span>\n </a>\n</div>\n\n<p>Any resemblance to real and actual names is purely coincidental!</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 28 Nov 2022 00:00:00 -0600\n https://arnolanglade.github.io/what-is-the-event-sourcing-pattern.html?s=feed\n https://arnolanglade.github.io/what-is-the-event-sourcing-pattern.html\n \n software-architecture\n \n \n \n \n \n My feedback about example mapping\n <p>Example mapping is a workshop that gathers tech and non-tech people to ensure everyone has the same understanding of the domain problem. It also helps clarify the acceptance criteria for a given story. Because it’s always better to understand what is expected and raise all bottlenecks before developing a story.</p>\n\n<p>Disclaimer! I won’t explain how to run such a workshop, you can easily find a bunch of articles on the web. You can also have a look at <a href="/agile-tour-rennes-example-mapping.html">these slides</a>, they come from one of my talks about example mapping if you’re not familiar with it. In this blog article, I want to share with you my experience on Example Mapping and how it helps me to prepare and organize the team’s work.</p>\n\n<p><strong>Caution:</strong> A little while ago, I got feedback from <a href="https://twitter.com/brunoboucard">Bruno Boucard</a> about using sticky notes. He advised me to use index cards instead of sticky notes. The workshop attendees can put them on a table and easily move them, unlike stick notes. I speak about sticky notes in this blog post because I only practiced this workshop remotely using tools like <a href="https://www.miro.com">Miro</a>.</p>\n\n<h2 id="who-will-attend-the-workshop">Who will attend the workshop?</h2>\n\n<p>The methodology recommends to involve at least the product managers, developers and testers. The goal of example mapping is that the product manager shares the problem with the person(s) who will solve it. I will go further, you can invite anyone who wants to understand what you are doing. It is a good way to share knowledge.</p>\n\n<p>During my last year at Akeneo, I worked on a new product called Shared Catalogs. All my teammates including devs, product manager, and engineering managers were newcomers. Even if they were really well onboarded on Akeneo’s products, they had a micro vision of what Akeneo PIM did, and the software’s functional perimeter was pretty huge. At this time, I was working at Akeneo for 4 years, andI had a good understanding of the product. During the example mapping sessions I shared as much knowledge as possible with my teammates, it helped the team to quickly improve their functional skills.</p>\n\n<h2 id="when-do-we-plan-it">When do we plan it?</h2>\n\n<p>From my experience, a 30-minute slot is a good tradeoff. It’s not too long and you can easily illustrate the main business rules of the story and detect all bottlenecks. With a 30-minute meeting, you’re sure that your teammates will stay focused, especially when you work remotely. Having regular and short workshops is better than doing a big and long one.</p>\n\n<p>Depending on their roles, some team members can be really busy. For instance, I worked with several PMs who were often in meetings and it was really hard to catch them. To be sure that everyone can be available, each team member booked a 30 minutes slot after the daily meeting. Doing an example mapping was not mandatory, we only did the workshop if we needed to prepare stories.</p>\n\n<h2 id="how-organize-the-team">How organize the team</h2>\n\n<p>The attendees can have different roles: onek person writes sticky notes, another animates the workshop and the others ask questions and drive the person who writes sticky notes. I think it is important to switch his/her role each session to keep everyone involved during the workshop.</p>\n\n<p>I worked with some product managers and domain experts who wanted to contribute and write sticky notes. It is not a good idea because they should focus on sharing the knowledge and let the rest of the team grasp the business expectations. You won’t help someone if you do his/her job.</p>\n\n<h2 id="how-to-start">How to start</h2>\n\n<p>Writing the title of a story on a yellow sticky note is pretty simple but I sometimes had difficulties getting the business rules and the examples listed. Especially, when you are doing this workshop with a team for the first time. I found out that it was easier to sometimes start by writing the example first or sometimes by writing the business rules first.</p>\n\n<p>First option: start by writing the business rules and then write the examples if your team is comfortable with the exercise and your product manager has a clear vision of what is expected.</p>\n\n<p>Second option: start by writing examples and then extract business rules from examples if your team is not comfortable with the workshop or if your product manager needs to explore a topic and he/she waits for your feedback. It will let you and your teammates speak, and understand what is going on. When you have enough examples and your understanding of business is better you can extract the business rules.</p>\n\n<p>Don’t be afraid if it is a bit complicated to be efficient in the beginning. One day, my teammates and I prepared a story about exporting a CSV file, quite simple, right? We only needed to “take data from the DB and build a file” but it wasn’t that simple! We turned this “simple” story into at least 15 stories. We discovered a lot of “hidden” business rules. We thought it was a story but it was an epic…</p>\n\n<h2 id="how-to-write-example">How to write example</h2>\n\n<p>Don’t try to write gherkins scenarios at all costs because it can be time-consuming. The goal of this workshop is to ensure all teammates grasp what the business expects and it is the right time to raise all problems and incomprehension.</p>\n\n<p>The simplest format I used to define the example looked like the Given / When / Then but a really simplified version.</p>\n\n<p><img src="images/posts/example-mapping/write-simple-exmaple.webp" alt="Simplified gherkins" /></p>\n\n<p>Sometimes it can be more readable to draw something.</p>\n\n<p><img src="images/posts/example-mapping/draw-example.webp" alt="Draw examples" /></p>\n\n<p>Don’t limit yourself, if you prefer another format, use it. The most important thing is that everyone understands what is expected.</p>\n\n<h2 id="dont-forget-red-sticky-notes">Don’t forget red sticky notes</h2>\n\n<p>Avoid endless debates! Don’t hesitate to use red sticky notes if your teammates disagree on something. Keep in mind that your product manager can’t answer all questions during the workshops. It’s normal, the product manager is not a super(wo)man! Thus, add a red sticky note and take time to think about it, he/she’ll answer all questions in the next session.</p>\n\n<h2 id="have-small-stories">Have small stories</h2>\n\n<p>I like to talk with the PM when the story is ready to be developed (when there are no more red stickies and when all teammates are OK with it). I usually challenge him/her to know which business rules are really mandatory and which ones are nice-to-have. It ensures your stories are really small and it eases the prioritization. You can focus on what is really important and keep what is nice-to-have for later.</p>\n\n<p><strong>Tip:</strong> If your story has too many business rules, it’s a smell! That means you should split it into small ones. It will be easier to ship several small stories than a big one. If a business rule has too many examples, that’s a smell too. You might have missed some business rules.</p>\n\n<p><img src="images/posts/example-mapping/split-story.webp" alt="Split story into small ones" /></p>\n\n<p>I am not a big fan of estimates, it’s a waste of time. We should focus on understanding the problem we want to solve, instead of giving figures that will probably be wrong. Having a really small story will help you to be more predictive. You can count the stories done during a time frame and easily forecast what your team will be able to do during the next iteration.</p>\n\n<h2 id="final-thoughts">Final thoughts</h2>\n\n<p>The first example mapping workshop can be complex but don’t give up. The more you practice, the more comfortable your team will be with the workshop. Example mapping is a good way to align the team’s understanding with the stakeholders expectations. It will help your team to better collaborate and break all silos between all kinds of positions in your team. Last but not least, it will help you refine your stories and improve your backlog prioritization.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 31 Oct 2022 00:00:00 -0500\n https://arnolanglade.github.io/my-feedback-about-example-mapping.html?s=feed\n https://arnolanglade.github.io/my-feedback-about-example-mapping.html\n \n BDD\n \n methodology\n \n \n \n \n \n How I have learned programming by myself\n <p>I am, what we call, a self-taught. I studied telecommunications and networks at school, unfortunately, I only learned the basics of programming. I had to learn and improve my skills by myself for many years during my free time. I did not take the easiest path to learn! That’s why I wanted to share with you my own experience and what I did to learn software development. I hope this post will help some of you.</p>\n\n<h2 id="find-a-mentor">Find a mentor</h2>\n\n<p>In the beginning, even though I knew some basics of programming I was a bit lost. I wasn’t able to build an application end to end and I did not know which subject I had to study to solve that. That’s why I advise junior engineers to find at least one mentor. A mentor can teach you what is important like how to test, design patterns, software architecture, and so on. A mentor will help you focus on the right topics like how to build robust applications instead of focusing on hype technologies.</p>\n\n<p><strong>Tip:</strong> If you’re a junior, I would recommend you focus on testing: TDD will help you to design your code step by step. Architectural patterns like hexagonal architecture will help you to decouple your code from IO. Agile: eXtreme programming will help you to reduce the cost of changes by having multiple short development cycles rather than a long one.</p>\n\n<h2 id="play-and-have-fun-with-a-side-project">Play and have fun with a side project</h2>\n\n<p>You can have strong constraints at work, so it can be really hard to try new things because of bad processes, bad code quality, impossible deadlines etc. I have worked on several side projects for the last 10 years. I tried twice to release an application for a French NGO to manage their volunteer data. Then I tried to make an application to organize my trips. The last one is about making maps to remember places I have been. I learned a lot from those projects, they let me try what I read in blog posts, books or what I saw in conferences without any pressure of production. The funny thing is that I learned more from failures. Only my last side project <a href="https://mymaps.world">“mymaps”</a> is live, I did not release the other ones! This is because they were only playgrounds rather than real projects. They helped me understand why being pragmatic is important, focusing only on technical aspects does not help to build an application. Keep in mind that a good codebase is not the only thing you need to make a successful project.</p>\n\n<h2 id="contribute-to-an-open-source-project">Contribute to an open-source project</h2>\n\n<p>I worked on <a href="https://sylius.com">Sylius</a> which is an open-source e-commerce framework. The community of Sylius is great. I learned a lot of good practices like testing, code review and behaviour-driven development for instance. I mainly worked on the <code class="language-plaintext highlighter-rouge">SyliusResourceBundle</code> which is a library that eases CRUD management. During this period, I was working for a web agency, it helped me to be more efficient at work and ship projects faster.</p>\n\n<p><strong>Caution:</strong> Many companies use open-source projects but they don’t contribute to them. I was happy to contribute to this project during my free time, but you should negotiate allocated time with your company to help those projects if they help you deliver value to your customers.</p>\n\n<p>I would like to thank <a href="https://pjedrzejewski.com">Pawel</a> for making me a core team member. Contributing to Sylius has opened many doors to me.</p>\n\n<p>Thanks to what I have done in that library, I had the chance to do my first conference (<a href="https://live.symfony.com/2015-paris">Symfony live</a>) as a speaker. That was so great! I was so excited and terrified at the same time. Then I got hired by a french startup <a href="https://www.akeneo.com/">Akeneo</a> to work on an open-source PIM (Product Information Management). I only worked for service companies before Akeneo, this experience made me discover what was software edition.</p>\n\n<h2 id="attend-conferences-and-meetups">Attend conferences and meetups</h2>\n\n<p>Attending conferences is a great way to learn and open your mind to new things. You can have a chat with other attendees during breaks as well. It is a good way to meet new people and to have interesting talks. One of my favourite conferences is <a href="http://www.ncrafts.io">newcraft</a>, its local edition at <a href="https://bordeaux.ncrafts.io/">Bordeaux</a> was really great too.</p>\n\n<p>When you will be comfortable the next step will be to do a presentation. Preparing a talk is good to dive into the topic you will present and formalize your ideas. Even if you know this topic, it may not be that easy to clearly explain it to someone else. Don’t be shy, submit your talks! A lot of conference organizations help new speakers. I did not think too much when I submitted my first talk. I thought it wouldn’t be selected but I received an email that said my talk was accepted. I was so happy and excited! I realized what happened and I really started to panic (true story, a little panic attack) so I started to work on my talk to be ready for D-day. You can have a look at <a href="http://arnolanglade.github.io/talks.html">my talks</a>.</p>\n\n<h2 id="read-books">Read books</h2>\n\n<p>Another way to learn is through books. This is a good way to shut down your computer while still learning new things about software engineering.</p>\n\n<p><strong>Tip:</strong> Some books in my library: <a href="https://www.oreilly.com/library/view/accelerate/9781457191435/">Accelerate</a>, <a href="https://www.oreilly.com/library/view/extreme-programming-explained/0201616416/">Extreme Programming Explained</a>, <a href="https://www.oreilly.com/library/view/domain-driven-design-distilled/9780134434964/">Domain-Driven Design Distilled</a>, <a href="https://www.oreilly.com/library/view/patterns-principles-and/9781118714706/">Patterns, Principles, and Practices of Domain-Driven Design</a>, <a href="https://www.yegor256.com/elegant-objects.html">Elegant Objects</a> and so on.</p>\n\n<h2 id="final-thoughts">Final thoughts</h2>\n\n<p>A few weeks ago, I saw some software engineers saying on social media that we should self-train in our free time. Learning in your free time will help you progress faster but it can be time and energy consuming. Don’t forget that burnouts are real. One of my friends experienced burnout and couldn’t do anything for almost a year, he was completely out of energy.</p>\n\n<p>I also had to take several breaks in my learning process to avoid going to the dark side of the force. <strong>Only do things when you want in your free time! Don’t put pressure on yourself!</strong> And keep in mind that learning should be fun!</p>\n\n<p>Learning is a part of your job. Companies should let you learn during business hours. On a day-to-day basis, pair and mob programming is a good way to learn and challenge your ideas. Your company should train you as well. For instance, <a href="https://matthiasnoback.nl">Mathias Noback</a> gave us some training when I was at Akeneo. I learned a lot from him, and I definitely recommend him!</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 17 Oct 2022 00:00:00 -0500\n https://arnolanglade.github.io/how-I-have-learned-programming-by-myself.html?s=feed\n https://arnolanglade.github.io/how-I-have-learned-programming-by-myself.html\n \n learning\n \n \n \n \n \n Increase your test quality thanks to builders or factories\n <p>In a previous <a href="http://arnolanglade.github.io/you-should-not-expose-objects-state-to-test-them.html">blog post</a>, I explained why it’s better to compare object instances instead of exposing their state to test them. This avoids breaking encapsulation and it does not have any impact on their design.</p>\n\n<p>Let’s take an example! My side project allows me to create maps to remember places I have been. A map has a name and, as a cartographer, I am allowed to rename it. Real basic use case but more than enough! The following test ensures I can rename this map:</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="s1">'Pepito'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="s1">'Bordeaux city'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="s1">'Good places in Anglet'</span><span class="p">),</span>\n <span class="nc">Tag</span><span class="o">::</span><span class="nf">city</span><span class="p">(),</span>\n <span class="nc">MarkerList</span><span class="o">::</span><span class="nb">empty</span><span class="p">(),</span>\n<span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">);</span>\n\n<span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span>\n <span class="nv">$map</span><span class="p">,</span>\n <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="s1">'Pepito'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="s1">'Good places in Anglet'</span><span class="p">),</span>\n <span class="nc">Tag</span><span class="o">::</span><span class="nf">city</span><span class="p">(),</span>\n <span class="nc">MarkerList</span><span class="o">::</span><span class="nb">empty</span><span class="p">(),</span>\n <span class="p">)</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p>We can see that comparing object instances is great for encapsulation because we don’t expose the object’s state but this makes the test less readable. Here, the only thing we want to focus on is the value of <code class="language-plaintext highlighter-rouge">MapName</code>. The values of the other value object are only noise because they are not useful for this test. But, this is not the only drawback of this test. What happens if you want to add an extra property to the <code class="language-plaintext highlighter-rouge">Map</code> object? In this case, we will need to refactor all the tests that create a map object. It might be easily doable in small projects but it can become messy for big ones.</p>\n\n<p>Now, let’s show how we can improve this test. The title of my blogpost can give you a huge hint on the solution. We will add a named constructor called <code class="language-plaintext highlighter-rouge">whatever</code> to the <code class="language-plaintext highlighter-rouge">Map</code> object to centralize the object construction. Named constructors are static factories that build the object itself.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Map</span> \n<span class="p">{</span>\n <span class="cd">/** @internal */</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">whatever</span><span class="p">(</span>\n <span class="kt">string</span> <span class="nv">$mapId</span> <span class="o">=</span> <span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$addedBy</span> <span class="o">=</span> <span class="s1">'Pepito'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$name</span> <span class="o">=</span> <span class="s1">'Anglet city'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$description</span> <span class="o">=</span> <span class="s1">'Good places in Anglet'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$tag</span> <span class="o">=</span> <span class="s1">'city'</span><span class="p">,</span>\n <span class="kt">array</span> <span class="nv">$markers</span> <span class="o">=</span> <span class="p">[],</span>\n <span class="p">):</span> <span class="kt">self</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="nv">$mapId</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$addedBy</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$name</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="nv">$description</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Tag</span><span class="p">(</span><span class="nv">$tag</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MarkerList</span><span class="p">(</span><span class="nv">$markers</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> I like to add a <code class="language-plaintext highlighter-rouge">@internal</code> annotation to remind all teammates that the object constructor should only be used in tests.</p>\n\n<p>The value object instantiation is delegated to the <code class="language-plaintext highlighter-rouge">whatever</code> constructor. I try to use primitive data types like arguments as much as possible, it makes me write less code and it’s easier to read. All constructor arguments have a default value, then I can override a given value depending on the needs thanks to the named argument feature.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">whatever</span><span class="p">(</span><span class="n">name</span><span class="o">:</span> <span class="s1">'Bordeaux city'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">);</span>\n\n<span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span>\n <span class="nv">$map</span><span class="p">,</span>\n <span class="nc">Map</span><span class="o">::</span><span class="nf">whatever</span><span class="p">(</span><span class="n">name</span><span class="o">:</span> <span class="s1">'Anglet city'</span><span class="p">)</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p>Now, the test is clear and focuses on the right thing. Everyone can easily understand it, and it will help your teammates to grasp the code you wrote. Refactoring will be simplified as you only have to rewrite the <code class="language-plaintext highlighter-rouge">whatever</code> constructor if the signature of the primary constructor of <code class="language-plaintext highlighter-rouge">Map</code> changes.</p>\n\n<p>I know that some people won’t like the idea of adding a method to objects only for testing purposes. If you don’t like that, you can replace this static factory with a builder.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MapBuilder</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$mapId</span> <span class="o">=</span> <span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$addedBy</span> <span class="o">=</span> <span class="s1">'Pepito'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$name</span> <span class="o">=</span> <span class="s1">'Anglet city'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$description</span> <span class="o">=</span> <span class="s1">'Good places in Anglet'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$tag</span> <span class="o">=</span> <span class="s1">'city'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">array</span> <span class="nv">$markers</span> <span class="o">=</span> <span class="p">[];</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">identifiedBy</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span> <span class="o">=</span> <span class="nv">$mapId</span><span class="p">;</span>\n \n <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">named</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$name</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>\n\n <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="c1">// ... other setters ....</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">build</span><span class="p">():</span> <span class="kt">Map</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">addedBy</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">description</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Tag</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">tag</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MarkerList</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markers</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then your test will look like this:</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="p">(</span><span class="k">new</span> <span class="nc">MapBuilder</span><span class="p">())</span><span class="o">-&gt;</span><span class="nf">named</span><span class="p">(</span><span class="s1">'Bordeaux city'</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">();</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">);</span>\n\n<span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span>\n <span class="nv">$map</span><span class="p">,</span>\n <span class="p">(</span><span class="k">new</span> <span class="nc">MapBuilder</span><span class="p">())</span><span class="o">-&gt;</span><span class="nf">named</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">()</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> Read or anemic models don’t have logic to ensure they are built in a good way. If you use this method for them you can add some logic to your builder/factories to ensure they are created with consistent data. It will make your tests stronger.</p>\n\n<h2 id="final-thought">Final thought</h2>\n\n<p>Builders or factories ease test refactoring and make tests more readable. Don’t forget that bad test suites are a nightmare to maintain and can drastically slow down your delivery. Taking care of your test quality will help you to ship fast. Moreover, good tests are free documentation.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 10 Oct 2022 00:00:00 -0500\n https://arnolanglade.github.io/increase-your-test-quality-thanks-to-builders-or-factories.html?s=feed\n https://arnolanglade.github.io/increase-your-test-quality-thanks-to-builders-or-factories.html\n \n testing\n \n \n \n \n \n How to handle user permissions through command bus middleware\n <p>Applying user permissions might be very complex and can lead to introducing a lot of accidental complexity to your application. In this blog post, I want to share with you how to do it by simply adding a middleware to your command bus.</p>\n\n<p><strong>Note:</strong> If you’re not familiar with this pattern, please have a look at this <a href="http://arnolanglade.github.io/command-bus-design-pattern.html">blog post</a>, it explains what a command bus and a middleware are.</p>\n\n<p>Let’s imagine a basic use case: an application with two kinds of users: regular ones and admins. We want to allow certain actions only to admin users.</p>\n\n<p>First, I will introduce an interface <code class="language-plaintext highlighter-rouge">OnlyPerformedByAdministrator</code> that will be implemented by the command restricted to the admin users.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">interface</span> <span class="nc">OnlyPerformedByAdministrator</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">username</span><span class="p">():</span> <span class="kt">string</span><span class="p">;</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">CreateNewProduct</span> <span class="kd">implements</span> <span class="nc">OnlyPerformedByAdministrator</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">username</span><span class="p">():</span> <span class="kt">string</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then, we will add a <code class="language-plaintext highlighter-rouge">CheckAccessPermission</code> middleware to the command bus that will check if the user can execute an action. If he/she can’t, an <code class="language-plaintext highlighter-rouge">AccessDenied</code> exception will be thrown. It will be caught later in the execution flow to be turned into something that will be understandable to the user.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">AccessDenied</span> <span class="k">extends</span> <span class="err">\\</span><span class="nc">Exception</span>\n<span class="p">{</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">CheckAccessPermission</span> <span class="kd">implements</span> <span class="nc">Middleware</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">private</span> <span class="nc">Users</span> <span class="nv">$users</span><span class="p">)</span> <span class="p">{}</span>\n\n <span class="k">final</span> <span class="k">public</span> <span class="k">function</span> <span class="n">handle</span><span class="p">(</span><span class="kt">Command</span> <span class="nv">$command</span><span class="p">,</span> <span class="kt">Middleware</span> <span class="nv">$next</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$user</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">users</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">username</span><span class="p">()));</span>\n <span class="k">if</span> <span class="p">(</span><span class="nv">$command</span> <span class="k">instanceof</span> <span class="nc">OnlyPerformedByAdministrator</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="nf">isAdmin</span><span class="p">())</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">AccessDenied</span><span class="p">();</span>\n <span class="p">}</span>\n\n <span class="nv">$next</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nv">$command</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>This middleware will stop the command processing if an error is raised. We need to catch this exception to return a 403 HTTP response in the web controller, or to return a status code greater than 0 in the CLI command.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">WebToggleCartographerPremiumStatus</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">private</span> <span class="nc">CommandBus</span> <span class="nv">$commandBus</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">Request</span> <span class="nv">$request</span><span class="p">):</span> <span class="kt">Response</span>\n <span class="p">{</span>\n <span class="k">try</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">commandBus</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="k">new</span> <span class="nc">CreateNewProduct</span><span class="p">(</span><span class="cd">/** ... */</span><span class="p">));</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">AccessDenied</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">Response</span><span class="p">(</span><span class="mi">403</span><span class="p">,</span> <span class="s1">'Access denied'</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">Response</span><span class="p">(</span><span class="mi">200</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h2 id="why-do-i-handle-permissions-with-a-middleware">Why do I handle permissions with a middleware?</h2>\n\n<p>I decided to add a middleware to the command bus because it ensures that permissions are checked no matter where commands are dispatched. For example: from the web controller or a CLI command. Moreover, I don’t depend on a security library or any framework configuration. All permission business rules are coded in the domain.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 26 Sep 2022 00:00:00 -0500\n https://arnolanglade.github.io/how-to-handle-user-permissions-through-command-bus-middleware.html?s=feed\n https://arnolanglade.github.io/how-to-handle-user-permissions-through-command-bus-middleware.html\n \n command-bus\n \n \n \n \n \n The command bus design pattern\n <p><strong>Note:</strong> Before reading this blog post, if you don’t know what a command and a command handler are, I advise you to first read the blog post I’ve written about those design patterns. It will help you to understand this new article:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-handler-patterns.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-handler/command-handler.webp" alt="Command and command handler design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Command and command handler design pattern</span>\n </span>\n </a>\n</div>\n\n<h2 id="what-is-a-bus">What is a bus?</h2>\n\n<p>Let’s start with the basics, what is a bus? In computer science, a bus is a system that connects several components and transfers data between them. In software, those components are called middleware. A middleware processes an incoming request and returns a response. As you can see in the schema below, the main advantage of a bus is that it is highly customizable as you can add as many middleware as you want.</p>\n\n<p><img src="images/posts/command-bus/bus.svg" alt="A bus" /></p>\n\n<p>In the next sections, we will speak about the command bus which is often associated with an event bus. Using an event bus is not mandatory but we will see how it will make your application more modular and evolutive. Their goal is to deliver a command or an event to their handler(s). Events and commands are objects used to encapsulate information needed to achieve an action (a command) or to tell what happened in the system (an event).</p>\n\n<h2 id="the-command-bus">The command bus</h2>\n\n<p><strong>Quick reminder about command and command handler:</strong> A command represents a user’s intent. The data carried by the command has to be valid. It can be only handled by only one handler that is just a callable that will perform the user action.</p>\n\n<p>Now, we will build a command bus following the same architecture that I described in the previous section. The only difference is that the command bus will return void. As commands canmight be handled asynchronously, we don’t want to wait for the result of the command processing.</p>\n\n<p><img src="images/posts/command-bus/command-bus.svg" alt="A command bus" /></p>\n\n<p>Let’s see the most common middleware used to build a command bus. The first one is probably the “logging middleware”. It helps to make your application observable and it is really useful for bug hunting. Then the “validation middleware” ensures that the command is valid before giving it to the handler. Its purpose is to stop the command processing if data is invalid. It is pretty convenient because it avoids validating them manually. When your application uses a database, the “transaction middleware” wraps the handler execution into a SQL transaction. It makes sure all database changes are done, otherwise it rollbacks the transaction. Finally, the last middleware is responsible for finding and executing the handler that matches the command.</p>\n\n<h2 id="the-event-bus">The event bus</h2>\n\n<p>An event represents something that happened in the application. Unlike a command, an event can be handled by several handlers. Listening to events allows us to enhance existing features or add new ones very quickly. Several teams can listen to the same event to perform additional tasks depending on business needs. It makes applications more evolutive without adding accidental complexity and lets your team work isolated from each other.</p>\n\n<p><strong>Tip:</strong> I would like to encourage you to mainly use business-oriented events instead of technical ones. They clearly describe what happened from a business point of view. For example, <code class="language-plaintext highlighter-rouge">NewAccountHasBeenCreated</code> is more understandable than <code class="language-plaintext highlighter-rouge">ResourceCreated</code> with a resource property equal to ‘Account’</p>\n\n<p>Even if the event bus is built the same way as the command bus we don’t need all the different middleware. We don’t need the validation middleware because events are generated by the aggregates with value objects. Those objects ensure domain invariant which means they are always valid. We also don’t need the transactional middleware because the event will be processed into the transaction begun during the command processing. Moreover, depending on your business needs you may not want to process events into this transaction. Let’s take a simple example. After creating an account, an event <code class="language-plaintext highlighter-rouge">AccountCreated</code> is dispatched, then a welcome email is sent during <code class="language-plaintext highlighter-rouge">AccountCreated</code> processing. If the email sending fails, do we want to roll back the account creation? Not sure! In that case, you need to speak with your product manager to decide how to process this event.</p>\n\n<p>As I said previously, events are recorded by aggregates and they should be business oriented. I will share with you two ways to dispatch events into the event bus.</p>\n\n<p><img src="images/posts/command-bus/event-bus.svg" alt="A event bus" /></p>\n\n<p><strong>Solution 1:</strong> You can collect them from your repository if no errors have been raised during the aggregate persisting and then dispatch them.</p>\n\n<p><strong>Solution 2:</strong> The other solution is to collect events from the command handler. The handler can return them, and then the “handle command” middleware catches and dispatches them.</p>\n\n<p><strong>Note:</strong> My previous <a href="http://arnolanglade.github.io/command-handler-patterns.html">blog post</a> about the command and command handler pattern said that a command handler should return void. Here, the idea is that the command bus should return void only the “handle command” should be aware of the result of the handler execution.</p>\n\n<p>I’ve written a bunch of articles about how to handle a command, validate its data, handle user permissions, and so on. Take a look at these articles:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/tag/command-bus">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/data-validation.webp" alt="See all blog posts about command handling." />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">See all blog posts about command handling.</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 12 Sep 2022 00:00:00 -0500\n https://arnolanglade.github.io/command-bus-design-pattern.html?s=feed\n https://arnolanglade.github.io/command-bus-design-pattern.html\n \n command-bus\n \n design-patterns\n \n \n \n \n \n Objective: set up your projects more easily\n <p>For the last decade I worked on several more or less complex projects. I often had problems with their installation. Sometimes, the project was not documented or the existing documentation was not up to date. I had to run commands but I did not understand all of them. When I got errors it was hard to understand what happened. That was not always simple.</p>\n\n<p>During my last projects, I used makefile to provide an abstraction to simplify their installation and hide complexity. It let me install projects with a single command and provided a minimal set of targets which made my daily work easier.</p>\n\n<h2 id="how-does-makefile-work">How does makefile work?</h2>\n\n<p>A makefile is a set of “rules” that looks like:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>target: prerequisites prerequisites\n recipe\n recipe\n ...\n</code></pre></div></div>\n\n<p>A <strong>target</strong> is the name of a file (or a folder) that is generated by <code class="language-plaintext highlighter-rouge">make</code>. It could also be the name of an action to perform but you need to declare it as PHONY.</p>\n\n<p>A <strong>prerequisite</strong> are the files (or folders) needed to create the target, you can see them as target dependencies.</p>\n\n<p>A <strong>recipe</strong> are all actions executed when the target is run. <strong>Caution:</strong> you need to indent all recipes using a “real” tab character otherwise you will get errors.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.env:\n <span class="nb">cp</span> .env.dist .env\n</code></pre></div></div>\n\n<p>If the <code class="language-plaintext highlighter-rouge">.env</code> file does not exist, the recipe will be carried out, but if it does exist the recipe won’t be executed #magic.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: cache\ncache: .env\n bin/console c:c\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">cache</code> target does not target a file. Declaring this target as PHONY allows having a file named <code class="language-plaintext highlighter-rouge">cache</code> in the same directory as the Makefile.</p>\n\n<p><strong>Note:</strong> If the <code class="language-plaintext highlighter-rouge">.env</code> file does not exist the <code class="language-plaintext highlighter-rouge">.env</code> target will be performed before the <code class="language-plaintext highlighter-rouge">cache</code> target.</p>\n\n<h2 id="lets-take-an-example">Let’s take an example</h2>\n\n<p>For instance, a project orchestrated by docker-compose having:</p>\n<ul>\n <li>a front application written in JS using React framework,</li>\n <li>a back application written in PHP using Symfony framework,</li>\n <li>a PostgreSQL database managed by Doctrine DBAL and Doctrine migration</li>\n</ul>\n\n<p><strong>Caution:</strong> I will only speak about projects setup for dev purposes. I won’t talk about making docker images ready for production.</p>\n\n<p>Let’s start installing the project dependencies. The following targets install project dependencies if they have not been downloaded yet. They can guess if they are outdated to upgrade them thanks to target prerequisites. Another interesting thing is that nothing will be done if dependencies are already installed and up to date.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Front</span>\nweb/yarn.lock: web/package.json\n docker-compose run <span class="nt">--rm</span> node yarn <span class="nb">install\n\n</span>web/node_modules: web/yarn.lock\n docker-compose run <span class="nt">--rm</span> node yarn <span class="nb">install</span> <span class="nt">--frozen-lockfile</span>\n docker-compose run <span class="nt">--rm</span> node yarn check <span class="nt">--integrity</span>\n\n<span class="c"># back</span>\napi/composer.lock: api/composer.json\n docker-compose run <span class="nt">--rm</span> fpm composer update\n\napi/vendor: api/composer.lock\n docker-compose run <span class="nt">--rm</span> fpm composer <span class="nb">install</span>\n\n</code></pre></div></div>\n\n<p>Then, we need to “up” all docker-compose services: the web server, the PHP process manager, the datatable, and the node to run the front application in development mode.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: up\nup:\n docker-compose up <span class="nt">-d</span>\n</code></pre></div></div>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker-compose ps \n Name Command State Ports \n<span class="nt">---------------------------------------------------------------------------------------------------------------------------------------------</span> \nmy-maps-node docker-entrypoint.sh yarn ... Up \nmy-maps-web nginx <span class="nt">-g</span> daemon off<span class="p">;</span> Up 80/tcp \nmy-maps_database_1 docker-entrypoint.sh postgres Up 5432/tcp \nmy-maps_fpm_1 php-fpm <span class="nt">-F</span> Up \n</code></pre></div></div>\n\n<p>The last thing to do is to create the database schema using Doctrine migration.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: db-migration\ndb-migration: api/vendor\n docker-compose run <span class="nt">--rm</span> fpm bin/console doctrine:migrations:migrate <span class="nt">--no-interaction</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> To ease my daily work, I like introducing other targets like <code class="language-plaintext highlighter-rouge">db</code> target that resets database quickly or <code class="language-plaintext highlighter-rouge">fixture</code> to load some data fixtures.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: db\ndb: api/vendor\n docker-compose run <span class="nt">--rm</span> fpm bin/console doctrine:database:drop <span class="nt">--force</span> <span class="nt">--no-interaction</span>\n docker-compose run <span class="nt">--rm</span> fpm bin/console doctrine:database:create <span class="nt">--no-interaction</span>\n\n.PHONY: fixtures\nfixtures: api/vendor\n docker-compose run <span class="nt">--rm</span> fpm bin/console project:fixtures:load\n</code></pre></div></div>\n\n<p>Now, we have all atomic targets to set up all parts of the application. Another interesting thing with make, is that it can run several targets within a single command <code class="language-plaintext highlighter-rouge">make up api/vendor web/node_modules</code>.This is pretty useful to create scenarios. For instance, to set up and run the project I only need to run the following command:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>make up api/vendor web/node_modules db db-migration fixtures\n</code></pre></div></div>\n\n<p>But it works with everything:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>make db db-migration fixtures\nmake api/vendor web/node_modules\n</code></pre></div></div>\n\n<p>To make your day-to-day basis, you can introduce targets that run those scenarios.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># It builds and runs the application</span>\n.PHONY: app-dev\napp-dev: up api/vendor web/node_modules db db-migration fixtures\n\n<span class="c"># It resets the database</span>\n.PHONY: db-reset\ndb-reset: db db-migration fixtures\n\n<span class="c"># It resets the database</span>\n.PHONY: dependencies\ndependencies: api/vendor web/node_modules\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> I advise you to introduce the minimum set of targets into the makefile. Keep it simple! Don’t forget that everyone uses it! To let developers have their custom targets you may want to include custom makefiles using <a href="https://www.gnu.org/software/make/manual/html_node/Include.html">include</a>. Don’t forget to add an entry into <code class="language-plaintext highlighter-rouge">.ignore</code> to avoid committing those files. Now, developers can create their own makefile with their personal targets.</p>\n\n<h2 id="one-last-word">One last word</h2>\n\n<p>Makefile is only a solution, this is not THE solution. The important thing to keep in mind is that you should be able to easily run your project to reduce the developer’s mental load and let them focus on the right thing. It will improve the day-to-day basis and make newcomers’ onboarding easier.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Wed, 02 Jun 2021 00:00:00 -0500\n https://arnolanglade.github.io/objective-set-up-your-projects-more-easily.html?s=feed\n https://arnolanglade.github.io/objective-set-up-your-projects-more-easily.html\n \n makefile\n \n \n \n \n \n Why unit testing can be hard?\n <blockquote>\n <p>Unit tests are typically automated tests written and run by software developers to ensure that a section of an application (known as the “unit”) meets its design and behaves as intended</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Unit_testing">Wikipedia</a></p>\n</blockquote>\n\n<p>I remember when I started to test my code it was really hard! It was mainly because I misunderstood some basics like what testing was about and the need of well-designed code. Unit tests ensure your code works as expected, but we often forget that unit testing is also the simplest way to have quick feedback during development phase.</p>\n\n<p>In this blog post, I will share what I learned to easily unit test my codebases.</p>\n\n<h2 id="test-your-public-methods">Test your public methods</h2>\n\n<p>Objects should be seen as black boxes. Public methods are the only way to interact with objects, while private and protected methods are implementation details. We should not pay attention to how objects work internally. That’s why we don’t test private and protected methods. If you need to test them, that’s a design smell! Your objects might do too many things and they probably do not respect the <strong>S</strong>ingle <strong>R</strong>esponsibility <strong>P</strong>rinciple.</p>\n\n<blockquote>\n <p>The single-responsibility principle (SRP) is a computer-programming principle that states that every class in a computer program should have responsibility over a single part of that program’s functionality, which it should encapsulate.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Single-responsibility_principle">Wikipedia</a></p>\n</blockquote>\n\n<p>Actually, it is better to have several small objects solving simple problems instead of having god objects that are doing everything the wrong way. If your objects become too big, split them into smaller ones because they are easier to maintain and to test.</p>\n\n<h2 id="do-not-unit-test-code-that-uses-ios">Do not unit test code that uses IOs</h2>\n\n<blockquote>\n <p>Input/output (I/O, or informally io or IO) is the communication between an information processing system, such as a computer, and the outside world, possibly a human or another information processing system.</p>\n\n <p><a href="https://press.rebus.community/programmingfundamentals/chapter/input-and-output/">Wikipedia</a></p>\n</blockquote>\n\n<p>For example, IO are side effects like: network calls, database queries, filesystem operations, actual timestamps or randomness.</p>\n\n<h3 id="do-not-deal-with-the-outside">Do not deal with the outside</h3>\n\n<p>The code covered by unit tests should not depend on the outside world like databases, external services and so on. Unit tests should not require any application setup, they have to remain as simple as possible. Their goal is to give you quick feedback by checking that a small piece of code (a unit) matches a business expectation. If you want to be sure that all application parts are well integrated with the outside world, you have to use an integration test.</p>\n\n<p>The following example shows a piece of code that depends on the external service. Here, we can’t build the <code class="language-plaintext highlighter-rouge">Map</code> object without a working database.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HandleMarkerAddition</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nv">$connection</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">AddMarkerToMap</span> <span class="nv">$command</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$mapState</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="s1">'SELECT ... FROM ...'</span><span class="p">,</span> <span class="p">[</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">mapId</span><span class="p">()]);</span>\n\n <span class="nv">$map</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">fromState</span><span class="p">(</span><span class="nv">$mapState</span><span class="p">);</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">name</span><span class="p">(),</span> <span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">location</span><span class="p">());</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="s1">'INSERT INTO ...'</span><span class="p">,</span> <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">toState</span><span class="p">()]);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The goal of this piece of code is to add a marker to a <code class="language-plaintext highlighter-rouge">Map</code> object, no matter how the object is stored. Tests that cover this class should focus on business use cases instead of technical details. A solution would be to use a repository design pattern to hide the map storage logic. The class will better follow the <strong>S</strong>ingle <strong>R</strong>esponsable <strong>P</strong>rinciple because it will only handle the marker addition use case whereas the map repository will be in charge of storing data.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HandleMarkerAddition</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Maps</span> <span class="nv">$maps</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Maps</span> <span class="nv">$maps</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">maps</span> <span class="o">=</span> <span class="nv">$maps</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">AddMarkerToMap</span> <span class="nv">$command</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$map</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">maps</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">mapId</span><span class="p">());</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">name</span><span class="p">(),</span> <span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">location</span><span class="p">());</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">maps</span><span class="o">-&gt;</span><span class="nf">add</span><span class="p">(</span><span class="nv">$map</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>With this new design, it is easier to test this class. Thanks to the <code class="language-plaintext highlighter-rouge">Maps</code> interface , we are able to simply create test doubles for the map repository.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// `PostgreSQLMaps` is the implementation used by default on the production</span>\n<span class="nv">$maps</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PostgreSQLMaps</span><span class="p">();</span>\n<span class="p">(</span><span class="k">new</span> <span class="nc">HandleMarkerAddition</span><span class="p">(</span><span class="nv">$postgreSQLMaps</span><span class="p">)(</span><span class="nv">$command</span><span class="p">);</span>\n\n<span class="c1">// `InMemoryMaps` is an implementation that keeps map objects in memory for testing </span>\n<span class="nv">$maps</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">InMemoryMaps</span><span class="p">();</span>\n<span class="p">(</span><span class="k">new</span> <span class="nc">HandleMarkerAddition</span><span class="p">(</span><span class="nv">$inMemoryMaps</span><span class="p">)(</span><span class="nv">$command</span><span class="p">);</span>\n\n<span class="c1">// In both cases we can retrieve the Map object from the repository to check the map has the new marker.</span>\n<span class="nv">$map</span> <span class="o">=</span> <span class="nv">$maps</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">mapId</span><span class="p">());</span>\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">hasSameState</span><span class="p">(</span><span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best place'</span><span class="p">,</span> <span class="k">new</span> <span class="nc">Marker</span><span class="p">(</span><span class="cm">/* … */</span><span class="p">)))</span> <span class="c1">// should return true;</span>\n\n</code></pre></div></div>\n\n<h3 id="do-not-deal-with-randomness">Do not deal with randomness</h3>\n\n<p>Randomness makes your code unpredictable. To simply test a piece of code you should be able to predict its result. To ease unit testing your code should avoid using randomness as much as possible.</p>\n\n<p>The following example shows a piece of code that uses randomness.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HashedPassword</span>\n<span class="p">{</span>\n <span class="c1">// ... </span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$hash</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">hash</span> <span class="o">=</span> <span class="nv">$hash</span><span class="p">;</span>\n <span class="p">}</span>\n\n\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">fromString</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$hash</span> <span class="o">=</span> <span class="err">\\</span><span class="nb">password_hash</span><span class="p">(</span><span class="nv">$password</span><span class="p">,</span> <span class="no">PASSWORD_BCRYPT</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span><span class="nv">$hash</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="c1">// ...</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">HashedPasswordTest</span> <span class="kd">extends</span> <span class="nc">TestCase</span>\n<span class="p">{</span>\n <span class="cd">/** @test */</span>\n <span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">builds</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="n">password</span><span class="err"> </span><span class="n">from</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="nf">string</span><span class="p">()</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">assertEquals</span><span class="p">(</span>\n <span class="nv">$this</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="s1">'Password1'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">HashedPassword</span><span class="p">(</span><span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span><span class="p">)</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>When we run <code class="language-plaintext highlighter-rouge">HashedPasswordTest</code> we get an error because the <code class="language-plaintext highlighter-rouge">password_hash</code> generates a random salt to hash the password. The problem is that the <code class="language-plaintext highlighter-rouge">password_hash</code> function cannot return the same hash for a given password. Each time you call this function a different hash will be returned.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">-Password</span> Object &amp;000000006e7168e60000000023b11bb2 <span class="o">(</span>\n- <span class="s1">'hash'</span> <span class="o">=&gt;</span> <span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span>\n+Password Object &amp;000000006e7168210000000023b11bb2 <span class="o">(</span>\n+ <span class="s1">'hash'</span> <span class="o">=&gt;</span> <span class="s1">'$2y$10$b/9GX4grnt4gH5cm8FzzSuUNGGQUiA/w.5HdKNEsW3dHtSUeTMXgK'</span>\n</code></pre></div></div>\n\n<p>The simplest solution would be to hardcode the salt to make sure the <code class="language-plaintext highlighter-rouge">hash_password</code> returns the same hash every time but this is not a good design. This would weaken the password generation because we need to test it. Another way would be to extract the hash generation in another place.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HashedPassword</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">fromString</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">,</span> <span class="kt">PasswordEncryptor</span> <span class="nv">$passwordEncryptor</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$hash</span> <span class="o">=</span> <span class="nv">$passwordEncryptor</span><span class="o">-&gt;</span><span class="nb">hash</span><span class="p">(</span><span class="nv">$password</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span><span class="nv">$hash</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">PasswordEncryptor</code> interface makes test doubles creation possible. Now, we just need to create a fake object to test this method.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">FakePasswordEncryptor</span> <span class="kd">implements</span> <span class="nc">PasswordEncryptor</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">hash</span><span class="p">():</span> <span class="kt">string</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span><span class="p">;</span>\n <span class="p">}</span>\n\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">HashedPasswordTest</span> <span class="kd">extends</span> <span class="nc">TestCase</span>\n<span class="p">{</span>\n <span class="cd">/** @test */</span>\n <span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">builds</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="n">password</span><span class="err"> </span><span class="n">from</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="nf">string</span><span class="p">()</span>\n <span class="p">{</span>\n <span class="nv">$fakePasswordEncryptor</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FakePasswordEncryptor</span><span class="p">();</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">assertEquals</span><span class="p">(</span>\n <span class="n">this</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="s1">'Password1'</span><span class="p">,</span> <span class="nv">$fakePasswordEncryptor</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">HashedPassword</span><span class="p">(</span><span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span><span class="p">)</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h3 id="avoid-actual-datetimes">Avoid actual datetimes</h3>\n\n<p>With actual datetimes, we have the same problem as with randomness, neither can be predicted.</p>\n\n<p>The following example shows you that actual datetimes are not predictable like <code class="language-plaintext highlighter-rouge">hash_password</code> in the previous section.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="err">\\</span><span class="nc">DateTimeImmutable</span> <span class="nv">$markerAddedAt</span> <span class="o">=</span> <span class="kc">null</span><span class="p">,</span> <span class="nc">Marker</span> <span class="mf">...</span><span class="nv">$makers</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">addMarker</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$name</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$location</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markerAddedAt</span> <span class="o">=</span> <span class="k">new</span> <span class="err">\\</span><span class="nf">DateTimeImmutable</span><span class="p">(</span><span class="s1">'now'</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">MapTest</span> <span class="kd">extends</span> <span class="nc">TestCase</span>\n<span class="p">{</span>\n <span class="cd">/** @test */</span>\n <span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">adds</span><span class="err"> </span><span class="n">marker</span><span class="err"> </span><span class="n">to</span><span class="err"> </span><span class="n">the</span><span class="err"> </span><span class="nf">map</span><span class="p">()</span>\n <span class="p">{</span>\n <span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Map name'</span><span class="p">);</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">,</span> <span class="p">[</span><span class="mf">47.21725</span><span class="p">,</span> <span class="o">-</span><span class="mf">1.55336</span><span class="p">]);</span>\n \n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">assetTrue</span><span class="p">(</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">hasSameState</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">Marker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">,</span> <span class="p">[</span><span class="mf">47.21725</span><span class="p">,</span> <span class="o">-</span><span class="mf">1.55336</span><span class="p">]),</span> \n <span class="k">new</span> <span class="err">\\</span><span class="nf">DateTimeImmutable</span><span class="p">(</span><span class="s1">'now'</span><span class="p">)</span>\n <span class="p">)</span>\n <span class="p">)</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>When we run <code class="language-plaintext highlighter-rouge">MapTest</code> we get an error because we can predict to the millisecond when the marker was added to the map.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">-Map</span> Object &amp;000000003acad975000000006b83e943 <span class="o">()</span>\n+Map Object &amp;000000003acad936000000006b83e943 <span class="o">(</span>\n+ <span class="s1">'markerAddedAt'</span> <span class="o">=&gt;</span> DateTimeImmutable Object &amp;000000003acad946000000006b83e943 <span class="o">(</span>\n+ <span class="s1">'date'</span> <span class="o">=&gt;</span> <span class="s1">'2021-04-18 17:36:02.919004'</span>\n+ <span class="s1">'timezone_type'</span> <span class="o">=&gt;</span> 3\n+ <span class="s1">'timezone'</span> <span class="o">=&gt;</span> <span class="s1">'UTC'</span>\n+ <span class="o">)</span>\n+<span class="o">)</span>\n</code></pre></div></div>\n\n<p>To prevent this kind of problem, a good idea is to abstract time by introducing an interface that is responsible for time management.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">addMarker</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$name</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$location</span><span class="p">,</span> <span class="kt">Clock</span> <span class="nv">$clock</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markerAddedAt</span> <span class="o">=</span> <span class="nv">$clock</span><span class="o">-&gt;</span><span class="nf">now</span><span class="p">();</span>\n <span class="p">}</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, thanks to the <code class="language-plaintext highlighter-rouge">Clock</code> interface we will be able to create test doubles and easily test this method.</p>\n\n<h2 id="coupling-might-be-your-worst-enemy">Coupling might be your worst enemy</h2>\n\n<blockquote>\n <p>Coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)">Wikipedia</a></p>\n</blockquote>\n\n<p>As you have seen in the previous sections, objects should depend on abstractions instead of concrete implementations. Abstractions (e.g. interfaces) ease testing because your code is more modular. You can use test doubles to reduce the complexity and facilitate testing. Their goal is to mimic the behavior of real objects to replace a subpart of an algorithm.</p>\n\n<p>The following example shows that hardcoding object dependencies won’t help to create test doubles.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MyClass</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">ConcreteImplementation</span> <span class="nv">$concreteImplementation</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="c1">// Here we can only use these concrete implementations, if they use IO for instance you won't be able to test it.</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">concreteImplementation</span> <span class="o">=</span> <span class="nv">$concreteImplementation</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">anotherConcreteImplementation</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">AnotherConcreteImplementation</span><span class="p">();</span>\n \n <span class="c1">// Singleton pattern does not help because it hides object dependencies and makes them hard coded.</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nc">Connection</span><span class="o">::</span><span class="nf">getInstance</span><span class="p">();</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The solution is to use the dependency inversion pattern to remove hard coded dependencies introducing abstractions as much as possible.</p>\n\n<blockquote>\n <p>High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g., interfaces). Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Wikipedia</a></p>\n</blockquote>\n\n<p>In the following example, all class dependencies are interchangeable. So, you can easily create test doubles like fake, stub, or mocks to make sure your objects meet business expectations.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MyClass</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">ImplementationInterface</span> <span class="nv">$concreteImplementation</span><span class="p">,</span>\n <span class="kt">AnoherImplementationInterface</span> <span class="nv">$anotherConcreteImplementation</span><span class="p">,</span>\n <span class="kt">ConnectionInterface</span> <span class="nv">$connection</span>\n <span class="p">)</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">concreteImplementation</span> <span class="o">=</span> <span class="nv">$concreteImplementation</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">anotherConcreteImplementation</span> <span class="o">=</span> <span class="nv">$anotherConcreteImplementation</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nv">$connection</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Caution:</strong> That does not mean you should use interfaces everywhere! Knowing when to introduce new abstractions might be hard at the beginning, there is no magic recipe!</p>\n\n<p>Thanks to my proofreaders <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a> and <a href="https://twitter.com/jjanvier_">@jjanvier_</a>.</p>\n\n Mon, 03 May 2021 00:00:00 -0500\n https://arnolanglade.github.io/why-unit-testing-can-be-hard.html?s=feed\n https://arnolanglade.github.io/why-unit-testing-can-be-hard.html\n \n testing\n \n OOP\n \n \n \n \n \n Why you should not expose objects' state to test them\n <p>To introduce this topic, let’s have a look at the PHP documentation to understand how object comparison works using the comparison and identity operators.</p>\n\n<blockquote>\n <p>When using the comparison operator (==), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values (values are compared with ==), and are instances of the same class.</p>\n\n <p>When using the identity operator (===), object variables are identical if and only if they refer to the same instance of the same class.</p>\n\n <p><a href="https://www.php.net/manual/en/language.oop5.object-comparison.php">PHP documentation </a></p>\n</blockquote>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$object</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Object</span><span class="p">();</span>\n<span class="nv">$otherObject</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Object</span><span class="p">();</span>\n\n<span class="nv">$object</span> <span class="o">==</span> <span class="nv">$otherObject</span> <span class="c1">// true</span>\n<span class="nv">$object</span> <span class="o">===</span> <span class="nv">$otherObject</span> <span class="c1">// false </span>\n</code></pre></div></div>\n\n<p>I add an <code class="language-plaintext highlighter-rouge">equals</code> method to objects to handle object comparison. The purpose of this method is to compare an object state with another one. In the following example, I use the comparison operator (==) because I want to check if the objects have the same state no matter their references.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Email</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$email</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$email</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">email</span> <span class="o">=</span> <span class="nv">$email</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">equals</span><span class="p">(</span><span class="kt">Email</span> <span class="nv">$email</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span> <span class="o">==</span> <span class="nv">$email</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>There is another way to compare object state. Do you know that instances of the same class can access each other’s private members?</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Email</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">equals</span><span class="p">(</span><span class="kt">Email</span> <span class="nv">$email</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">email</span> <span class="o">===</span> <span class="nv">$email</span><span class="o">-&gt;</span><span class="n">email</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> This is really useful to compare Doctrine entities that have persistent collections. The error <code class="language-plaintext highlighter-rouge">Error: Nesting level too deep - recursive dependency?</code> is raised when we compare entities using the comparison operator (==). You should have a look at this <a href="https://www.richardlord.net/blog/php/php-nesting-level-too-deep-recursive-dependency.html">blog post</a> to understand why this error occured. Accessing private attributes let you use the identity operator (===) to prevent this error.</p>\n\n<p>By the way, entities are a bit special because an entity is an object that has an identity. It means that if we want to compare them we should compare their identities instead of their states.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">equals</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span><span class="o">-&gt;</span><span class="nf">equals</span><span class="p">(</span><span class="nv">$mapId</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>I add an extra method called <code class="language-plaintext highlighter-rouge">hasSameState</code> to entities to compare their states because entity state comparison remains really useful for testing.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">hasSameState</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span> <span class="o">==</span> <span class="nv">$map</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>For a long time, I used getters for testing purposes. I only knew this way to ensure objects had the right state.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Nantes'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">getName</span><span class="p">()</span><span class="o">-&gt;</span><span class="nf">shouldReturn</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">)</span> <span class="p">;</span>\n</code></pre></div></div>\n\n<p>It was a mistake because exposing objects’ state breaks data encapsulation. We should not know how objects work internally, we should only use their public API (public methods) to interact with them. But, if we need to build the <code class="language-plaintext highlighter-rouge">Map</code> object with something else than a string, this assertion will no longer be true. That will break all application tests and parts that use this getter! That’s not great! Object comparison I described previously helps to get rid of getters.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Nantes'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">hasSameState</span><span class="p">(</span><span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">))</span><span class="o">-&gt;</span><span class="nf">shouldReturn</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n</code></pre></div></div>\n\n<p>Now, the <code class="language-plaintext highlighter-rouge">Map</code> object is better designed. Its state is not exposed anymore which improves data encapsulation. It follows the “Tell don’t ask” principle because I don’t need to extract its internal state to test it. I only need to use its public API to check if it meets the business exceptions.</p>\n\n<p><strong>Tip:</strong> If you don’t want or if you can’t add a method to your objects that handles comparison you can still compare their instances to avoid adding getters.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span><span class="nv">$map</span><span class="p">,</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">));</span>\n</code></pre></div></div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 13 Apr 2021 00:00:00 -0500\n https://arnolanglade.github.io/you-should-not-expose-objects-state-to-test-them.html?s=feed\n https://arnolanglade.github.io/you-should-not-expose-objects-state-to-test-them.html\n \n testing\n \n OOP\n \n \n \n \n \n How did I organize my last Symfony projects?\n <p>In this blog post, I will explain how I organized my last Symfony projects. They are mainly inspired by Hexagonal and CQRS architecture. Keep in mind that I did not try to implement these architectures by the book, I only took some concepts that helped me to have a simple and clear codebase organization.</p>\n\n<p>If we have a look at the project’s root, nothing special happens, I kept all folders and files created during Symfony installation.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree <span class="nb">.</span> <span class="nt">-L</span> 1 \n├── bin\n├── composer.json\n├── composer.lock\n├── config\n├── features\n├── public\n├── src\n├── symfony.lock\n├── tests\n├── translations\n├── var\n└── vendor\n</code></pre></div></div>\n\n<p>In the next sections, we are going to see how I organized the src folder.</p>\n\n<h2 id="hexagonal-architecture">Hexagonal architecture</h2>\n\n<p>The foundation of the hexagonal architecture is the explicit separation between the domain (inside) and the infrastructure (outside). All dependencies are going from Infrastructure to the Domain.</p>\n\n<p>The domain is the part of the application that contains your business logic. It must reflect as much as possible the problem your application has to solve. This part of the application must not use IO, the infrastructure contains them all. For instance, IO are side effects like network calls, database queries, filesystem operations, actual timestamps or randomness..</p>\n\n<p>Based on that information my first decision was to split src into two areas: <code class="language-plaintext highlighter-rouge">Domain</code> and <code class="language-plaintext highlighter-rouge">Infrastructure</code>.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/ <span class="nt">-L</span> 1\napi/src/Domain/\n├── Domain\n└── Infrastructure\n</code></pre></div></div>\n\n<p><strong>Coupling rules:</strong></p>\n<ul>\n <li>Domain must not depend on the Infrastructure.</li>\n <li>Domain must not use IO</li>\n</ul>\n\n<p>I am not a big fan of the onion architecture because I want to keep my projects as simple as possible. Having a lot of layers can be really hard to maintain because you need to align the whole team on the coupling rules. Agreeing with yourself is not easy, so getting several people to agree may be really hard. Here, we only have a single rule.</p>\n\n<p>Sometimes, I needed to write libraries because I could not find any open source libraries that match my expectations. To avoid coding in the vendor directory, I introduced a third area called <code class="language-plaintext highlighter-rouge">Libraries</code> (this new area is optional). Those libraries may be used in the domain and the infrastructure but their usage should not break the coupling rules that are defined for those areas.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/ <span class="nt">-L</span> 1\napi/src/Domain/\n├── Domain\n├── Infrastructure\n└── Librairies\n</code></pre></div></div>\n\n<p><strong>Coupling rules:</strong></p>\n<ul>\n <li>Libraries must not depend on Domain and Infrastructure</li>\n</ul>\n\n<p>Finally, I created a “sub” area called <code class="language-plaintext highlighter-rouge">Application</code> in the infrastructure that contains all pieces of code needed to have an application up and running: framework code (Symfony kernel, framework customizations), data fixtures, and migration.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Infrastructure/Application <span class="nt">-L</span> 1 \napi/src/Infrastructure/Application\n├── Exception \n├── Fixture\n├── Kernel.php\n├── Migrations\n├── Security\n└── Kernel\n</code></pre></div></div>\n<p>In this example, <code class="language-plaintext highlighter-rouge">Exception</code> and <code class="language-plaintext highlighter-rouge">Security</code> folders contain framework customizations.</p>\n\n<h2 id="business-first">Business first</h2>\n\n<p>A really important thing for me is to drive codebase organization by business concepts. I don’t want to name folders and classes with technical patterns like factory or repository for instance. Non-tech people should be able to understand what a class does thanks to its name.</p>\n\n<h3 id="domain">Domain</h3>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain <span class="nt">-L</span> 1\napi/src/Domain\n├── Cartographer\n└── Map\n</code></pre></div></div>\n\n<p>Because I did not use any technical words to name folders we can easily imagine the project is about making maps. Now, let’s have a look inside the <code class="language-plaintext highlighter-rouge">Map</code> directory:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/Map <span class="nt">-L</span> 1\n├── CartographersAllowedToEditMap.php // Value object\n├── Description.php // Value object\n├── MapCreated.php // Event \n├── MapId.php // Value object\n├── MapName.php // Value object\n├── Map.php // Root aggregate\n├── Maps.php // Repository interface\n├── Marker // All classes to design Marker entity\n├── MarkerAddedToMap.php // Event\n├── MarkerDeletedFromMap.php // Event\n├── MarkerEditedOnMap.php // Event\n├── UnknownMap.php // Exception\n└── UseCase // Use cases orchestration\n</code></pre></div></div>\n\n<p>In this folder, we have all the pieces of code needed to design the <code class="language-plaintext highlighter-rouge">Map</code> aggregate. As you can see, I did not organize it by design patterns like <code class="language-plaintext highlighter-rouge">ValueObject</code>, <code class="language-plaintext highlighter-rouge">Event</code> or <code class="language-plaintext highlighter-rouge">Exception</code>.</p>\n\n<p>As you might have understood the <code class="language-plaintext highlighter-rouge">Map</code> entity has a one-to-many relationship with the Marker entity. All classes needed to modelize this entity are in the Marker folder and they are organized the same way as the <code class="language-plaintext highlighter-rouge">Map</code> directory.</p>\n\n<p>The <code class="language-plaintext highlighter-rouge">UseCase</code> folder gathers all pieces of code needed to orchestrate use cases like command, their handler and business validation.</p>\n\n<p><strong>Tip:</strong> I don’t suffix repositories by ‘Repository’ but I try to use a business concept to name them like <code class="language-plaintext highlighter-rouge">ProductCatalog</code> for a <code class="language-plaintext highlighter-rouge">Product</code> aggregate. If I can find a business concept to name it I use the plural of the aggregate because a repository is a collection of objects.</p>\n\n<h3 id="infrastructure">Infrastructure</h3>\n\n<p>I organize the root of the <code class="language-plaintext highlighter-rouge">Infrastructure</code> folder the same way as the <code class="language-plaintext highlighter-rouge">Domain</code> one.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Infrastructure <span class="nt">-L</span> 1 \napi/src/Infrastructure\n├── Application\n├── Cartographer\n└── Map\n</code></pre></div></div>\n\n<p>Now, let’s have a look at the <code class="language-plaintext highlighter-rouge">Map</code> directory:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Infrastructure/Map <span class="nt">-L</span> 1 \napi/src/Infrastructure/Map\n├── Storage\n└── UserInterface\n └── Web\n └── Cli\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">Storage</code> namespace gathers everything related to data storage like repositories, queries. The <code class="language-plaintext highlighter-rouge">UserInterface</code> namespace gathers everything related to ways to interact with the application like the WEB API (controllers) called by the front application or CLI (Symfony commands).</p>\n\n<h2 id="cqrs">CQRS</h2>\n\n<p>CQRS is the acronym for Command Query Responsibility Segregation. The main idea of CQRS is that you can use different models for writing (command) or reading (query) information. I like the idea of having two small and simple models dedicated to a precise purpose: reading or writing instead of having one big model. It can prevent your aggregate from becoming a god object because as things progress you can have many write and read use cases to handle.</p>\n\n<p>From this pattern, I decided to split the domain into two areas, the first one: <code class="language-plaintext highlighter-rouge">Command</code> and the second one: <code class="language-plaintext highlighter-rouge">Query</code>. It allows me to design a model with the same name for these reading or writing purposes.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/ <span class="nt">-L</span> 2\napi/src/Domain/\n├── Command\n│ ├── Cartographer\n│ └── Map\n└── Query\n ├── Cartographer\n └── Map\n</code></pre></div></div>\n\n<p><strong>Coupling rule:</strong></p>\n<ul>\n <li><code class="language-plaintext highlighter-rouge">Command</code> area must not depend on the <code class="language-plaintext highlighter-rouge">Query</code> area and the other way around.</li>\n</ul>\n\n<p><strong>Note:</strong> I did not make major changes in the infrastructure, the only change I made is to split the storage into two areas like the domain.</p>\n\n<p><strong>Caution:</strong> For those projects, I did not make any projections because my database schema remained simple so I did not need them. I only decided to split my models because my codebase was simple and clearer this way.</p>\n\n<h2 id="last-word">Last word</h2>\n<p>I tried for the last few years to find the perfect architecture but it does not exist. I just tried to use some architectural concepts that make me and my teammates comfortable to work on a daily basis. This project organization has been used for two projects that are in production. One of these projects is a side project I made for fun to create maps without Google Maps. The second was a professional project, real people use it on a daily basis.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 30 Mar 2021 00:00:00 -0500\n https://arnolanglade.github.io/how-did-I-organize-my-last-symfony-project.html?s=feed\n https://arnolanglade.github.io/how-did-I-organize-my-last-symfony-project.html\n \n software-architecture\n \n symfony\n \n \n \n \n \n Persisting entities without ORM\n <p>Today, I will talk about persisting entities without ORM. First, I will introduce the repository pattern because it provides a good abstraction to manage object persistence. Then, we will see what are the impacts on the entity design.</p>\n\n<h2 id="repository-pattern">Repository pattern</h2>\n\n<p>The repository design pattern can be used to manage entity persistence and retrieval. It behaves like a collection of objects and hides the complexity of their storage. It ensures a clean separation between the domain model (the entity) and the data model (SQL tables). The following example shows a basic repository interface. Thanks to the <code class="language-plaintext highlighter-rouge">Maps</code> interface we will be able to add and retrieve Map entities, no matter their storage.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">interface</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n <span class="cd">/**\n * @throws \\LogicException\n * @throws UnknownMap\n */</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">get</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">Map</span><span class="p">;</span>\n\n <span class="cd">/**\n * @throws \\LogicException\n */</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">add</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">void</span><span class="p">;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Caution:</strong> All <code class="language-plaintext highlighter-rouge">Maps</code> implementations should be tested with the same test because we need to be sure they behave the same way. It ensures the application works no matter the chosen implementation.</p>\n\n<p>Let’s see how we can implement this interface with PostgreSQL for instance. The <code class="language-plaintext highlighter-rouge">get</code> method is only responsible to get information from the database to build the map entity whereas the <code class="language-plaintext highlighter-rouge">add</code> method extracts the entity information to store them in the database.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PostgreSqlMaps</span> <span class="kd">implements</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nv">$connection</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">get</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">Map</span>\n <span class="p">{</span>\n <span class="nv">$sql</span> <span class="o">=</span> <span class="sh">&lt;&lt;&lt;SQL\n SELECT map."mapId", map.name\n FROM map\n WHERE map."mapId" = :mapId\n SQL;</span>\n\n <span class="nv">$statement</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="nv">$sql</span><span class="p">,</span> <span class="p">[</span><span class="s1">'mapId'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="nv">$mapId</span><span class="p">]);</span>\n\n <span class="k">if</span> <span class="p">(</span><span class="kc">false</span> <span class="o">===</span> <span class="nv">$map</span> <span class="o">=</span> <span class="nv">$statement</span><span class="o">-&gt;</span><span class="nf">fetchAssociative</span><span class="p">())</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="nc">UnknownMap</span><span class="o">::</span><span class="nf">withId</span><span class="p">(</span><span class="nv">$mapId</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="nv">$map</span><span class="p">[</span><span class="s1">'mapId'</span><span class="p">],</span> <span class="nv">$map</span><span class="p">[</span><span class="s1">'name'</span><span class="p">]);</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">add</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$sql</span> <span class="o">=</span> <span class="sh">&lt;&lt;&lt;SQL\n INSERT INTO map ("mapId", name)\n VALUES (:mapId, :name)\n ON CONFLICT ("mapId")\n DO UPDATE SET name = :name;\n SQL;</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="nv">$sql</span><span class="p">,</span> <span class="p">[</span><span class="s1">'mapId'</span> <span class="o">=&gt;</span> <span class="nv">$map</span><span class="p">,</span> <span class="s1">'name'</span> <span class="o">=&gt;</span> <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">name</span><span class="p">()]);</span>\n <span class="p">}</span>\n\n <span class="k">private</span> <span class="k">function</span> <span class="n">executeQuery</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$sql</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$data</span><span class="p">):</span> <span class="kt">Result</span>\n <span class="p">{</span>\n <span class="c1">// Execute query or throw logic exceptions if something goes wrong.</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> Thanks to the clause <a href="https://www.postgresql.org/docs/9.5/sql-insert.html">ON CONFLICT</a> we can easily insert or update data with a single query.</p>\n\n<h2 id="entity-design-impacts">Entity design impacts</h2>\n\n<p>Now we are able to persist and retrieve our map entity. Let’s study the impact on entity design.</p>\n\n<p>Let’s start with persistence. In the previous example, I used getters to get its properties but I am not a fan of the getter to be honest! Getters break data encapsulation because they expose object implementation details. They don’t follow the <a href="https://www.martinfowler.com/bliki/TellDontAsk.html">Tell don’t ask</a> principle because we should not ask about the object state to do something, we should tell the object to do something for us. I like adding a <code class="language-plaintext highlighter-rouge">toState</code> method that is responsible to turn the entity into an associative array.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">toState</span><span class="p">():</span> <span class="kt">array</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="p">[</span>\n <span class="s1">'mapId'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span><span class="p">,</span>\n <span class="s1">'name'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">,</span>\n <span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>So I just need to call the <code class="language-plaintext highlighter-rouge">toState</code> method instead of getters, this method returns data expected by the <code class="language-plaintext highlighter-rouge">executeQuery</code> method.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PostgreSqlMaps</span> <span class="kd">implements</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">add</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="nv">$sql</span><span class="p">,</span> <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">toState</span><span class="p">());</span>\n <span class="p">}</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Let’s continue with retrieval. If we have a look at the <code class="language-plaintext highlighter-rouge">Map</code>constructor method we can see that a <code class="language-plaintext highlighter-rouge">MapInitialized</code> event is recorded there. Houston, we have a problem! When we build an entity from its state (data stored somewhere) we don’t want to record any event because nothing happens. So, we need to find a solution to avoid recording those events.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">,</span>\n <span class="kt">MapName</span> <span class="nv">$name</span>\n<span class="p">)</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span> <span class="o">=</span> <span class="nv">$mapId</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">recordEvent</span><span class="p">(</span><span class="k">new</span> <span class="nc">MapInitialized</span><span class="p">(</span>\n <span class="nv">$mapId</span><span class="p">,</span>\n <span class="nv">$name</span>\n <span class="p">));</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>I like adding a named constructor called <code class="language-plaintext highlighter-rouge">fromState</code> to the entity. This constructor is responsible for building the aggregate from the state. Moreover, named constructors are explicit and give developers information about when to use them. In the following example, after calling the <a href="https://arnolanglade.github.io/build-object-using-php.html">primary constructor</a> we call the <code class="language-plaintext highlighter-rouge">eraseRecordedEvents</code> method to reset events before returning the object in the right state.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">fromState</span><span class="p">(</span><span class="kt">array</span> <span class="nv">$state</span><span class="p">):</span> <span class="kt">self</span>\n<span class="p">{</span>\n <span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="nv">$state</span><span class="p">[</span><span class="s1">'mapId'</span><span class="p">]),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$state</span><span class="p">[</span><span class="s1">'name'</span><span class="p">])</span>\n <span class="p">);</span>\n\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">eraseRecordedEvents</span><span class="p">();</span>\n\n <span class="k">return</span> <span class="nv">$map</span><span class="p">;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>So, the only change in the repository is to build the <code class="language-plaintext highlighter-rouge">Map</code> entity from the named constructor.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PostgreSqlMaps</span> <span class="kd">implements</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">get</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">Map</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n\n <span class="k">return</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">fromState</span><span class="p">(</span><span class="nv">$map</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h2 id="last-word">Last word</h2>\n\n<p>I did a presentation about the repository design pattern at the Forum PHP in 2018. A video is only available in French <a href="https://www.youtube.com/watch?v=cYFKkhtIr8w&amp;ab_channel=AFUPPHP">here</a> but the slides are in English <a href="https://arnolanglade.gitlab.io/bad-or-good-repository/">here</a> (press “s” to display English notes). Even if this presentation was made for Doctrine ORM it gives a lot of information about the pattern.</p>\n\n<p><strong>Note:</strong> In this talk I spoke about generating the entity identity by the repository. To be honest, I stopped doing that because generating it from controllers is easier and makes the repository design simpler.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 23 Mar 2021 00:00:00 -0500\n https://arnolanglade.github.io/persisting-entities-without-orm.html?s=feed\n https://arnolanglade.github.io/persisting-entities-without-orm.html\n \n OOP\n \n design-patterns\n \n \n \n \n \n OOP: how to build an object\n <p>In this new blog post, I want to talk about object building more specifically about primary and secondary constructors. The primary constructor is the default way to build an object with all its dependencies. The secondary constructors provide other ways to build objects depending on use cases.</p>\n\n<p><strong>Note:</strong> I did not work on a PHP8 project yet so that is why I won’t talk about named arguments feature.</p>\n\n<h2 id="primary-constructor">Primary constructor</h2>\n\n<p>The PHP language provides a single way to build an object thanks to the <code class="language-plaintext highlighter-rouge">__construct()</code> method. I use this method to define the primary constructor of my classes to encapsulate all their dependencies.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">MapName</span> <span class="nv">$name</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">CartographersAllowedToEditMap</span> <span class="nv">$cartographersAllowedToEditMap</span><span class="p">;</span>\n <span class="cd">/** @var Marker[] */</span>\n <span class="k">private</span> <span class="kt">array</span> <span class="nv">$markers</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">MapName</span> <span class="nv">$name</span><span class="p">,</span>\n <span class="kt">CartographersAllowedToEditMap</span> <span class="nv">$cartographersAllowedToEditMap</span><span class="p">,</span>\n <span class="kt">Marker</span> <span class="mf">...</span><span class="nv">$markers</span>\n <span class="p">)</span> <span class="p">{</span> \n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">cartographersAllowedToEditMap</span> <span class="o">=</span> <span class="nv">$cartographersAllowedToEditMap</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markers</span> <span class="o">=</span> <span class="nv">$markers</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> If your objects encapsulate a collection of a specific type (like the <code class="language-plaintext highlighter-rouge">Marker</code> in this example), you can use variadic arguments to automatically validate each item of this collection. Here, we don’t need to iterate the collection to check the type of its items, the language does it for us.</p>\n\n<h2 id="secondary-constructor">Secondary constructor</h2>\n\n<p>The PHP language does not ease the data encapsulation because it only provides a single way to build objects but we should be able to define several constructors depending on all our use cases. How to solve this problem? Named constructors! Named constructors are static factories, in other words static methods that build the object itself.\nLet’s take an example with the map object. How to initialize a map without any marker?</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">initialize</span><span class="p">(</span>\n <span class="kt">string</span> <span class="nv">$name</span><span class="p">,</span>\n <span class="kt">array</span> <span class="nv">$cartographerAllowedToEditMap</span>\n <span class="p">):</span> <span class="kt">self</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$name</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">CartographersAllowedToEditMap</span><span class="p">(</span><span class="nv">$cartographerAllowedToEditMap</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Here, we added a named constructor called <code class="language-plaintext highlighter-rouge">initialize</code> to the <code class="language-plaintext highlighter-rouge">Map</code> class. It uses the primary constructor to build the map object with an empty collection of Marker objects.</p>\n\n<p><strong>Tip:</strong> Some developers change the visibility of the primary constructor method to private but I am not a big fan of that. I use object comparison to test objects to avoid the usage of getters. I like keeping my primary constructor public because it allows me to build objects in any state to compare them to other ones.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">adds</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="n">marker</span><span class="err"> </span><span class="n">on</span><span class="err"> </span><span class="n">the</span><span class="err"> </span><span class="nf">map</span><span class="p">()</span>\n<span class="p">{</span>\n <span class="nv">$actualMap</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">initialize</span><span class="p">(</span>\n <span class="s1">'Bons plans sur Nantes'</span><span class="p">,</span>\n <span class="p">[</span><span class="s1">'Arnaud'</span><span class="p">]</span>\n <span class="p">);</span>\n\n <span class="nv">$actualMap</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">);</span>\n\n <span class="nv">$expectedMap</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="s1">'Bons plans sur Nantes'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">CartographersAllowedToEditMap</span><span class="p">([</span><span class="s1">'Arnaud'</span><span class="p">]),</span>\n <span class="k">new</span> <span class="nc">Marker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">)</span>\n <span class="p">);</span>\n \n <span class="nf">assertSame</span><span class="p">(</span><span class="nv">$actualMap</span><span class="p">,</span> <span class="nv">$expectedMap</span><span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Wed, 10 Mar 2021 00:00:00 -0600\n https://arnolanglade.github.io/oop-how-to-build-an-object.html?s=feed\n https://arnolanglade.github.io/oop-how-to-build-an-object.html\n \n OOP\n \n design-patterns\n \n \n \n \n \n How to validate a command?\n <p>In my previous <a href="http://arnolanglade.github.io/command-handler-patterns.html">blog post</a>, I talked about command and command handler design patterns. I got several questions about data validation and how to give feedback to users. We are going to talk about several kinds of data validation in this blog post. We will start with domain validation, this validation ensures we can build our domain objects in a good state depending on business rules. Then, we will talk about command validation and how we can use it to give feedback to users when they submit data to the application.</p>\n\n<p>Let’s take the same example I used in my previous blog post: an account creation. To create an account, my business expert expects that I provide a username and a password. The username should have at least three characters and should be unique. The password should have at least eight characters, an uppercase letter, a lowercase letter, and a number.</p>\n\n<h2 id="domain-validation">Domain validation</h2>\n\n<p>How to make sure the domain objects follow the business rules? Value object will help us to achieve that. I <strong>strongly recommend you</strong> to wrap all primitives into value objects. It is a good way to introduce new types in your codebase, make it clearer and business-focused. And don’t forget, value objects <strong>cannot</strong> be built in a wrong state.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Username</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$username</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span><span class="err">\\</span><span class="nb">strlen</span><span class="p">(</span><span class="nv">$username</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="err">\\</span><span class="nf">InvalidArgumentException</span><span class="p">(</span><span class="s1">'The username is too short, it should contain at least 3 characters'</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">Password</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span><span class="mi">1</span> <span class="o">!==</span> <span class="err">\\</span><span class="nb">preg_match</span><span class="p">(</span><span class="s1">'#(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,}#'</span><span class="p">,</span> <span class="nv">$password</span><span class="p">))</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="err">\\</span><span class="nf">InvalidArgumentException</span><span class="p">(</span>\n <span class="s1">'The password must contain at least 8 characters, an uppercase letter, lowercase letter and a number'</span>\n <span class="p">);</span>\n <span class="p">}</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then we are able to modelize the <code class="language-plaintext highlighter-rouge">Account</code> aggregate using the <code class="language-plaintext highlighter-rouge">Username</code> and <code class="language-plaintext highlighter-rouge">Password</code> value objects.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Account</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Username</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">Password</span> <span class="nv">$password</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">Username</span> <span class="nv">$username</span><span class="p">,</span>\n <span class="kt">Password</span> <span class="nv">$password</span>\n <span class="p">)</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, we are sure that as developers we cannot instantiate the <code class="language-plaintext highlighter-rouge">Account</code> aggregate in a wrong state. In the next section, we are going to see how to use the domain objects to give users feedback about their data.</p>\n\n<h2 id="command-validation">Command validation</h2>\n\n<p>As I explained in my previous <a href="http://arnolanglade.github.io/command-handler-patterns.html">blog post</a>, an account creation is represented by a <code class="language-plaintext highlighter-rouge">CreateAnAccount</code> command with two properties: the username and the password. We need to validate them to create the account aggregate without any errors and tell users if they provided valid data to perform this action. The command validation will be done by the Symfony validator. Don’t hesitate to have a look at the <a href="https://symfony.com/doc/current/validation.html">validator documentation</a> if you are not familiar with it.</p>\n\n<p>First, we will use the callback constraint to make sure the username and password follow the patterns given by the business expert. Thanks to annotation we will configure the validator to call a static method to validate command properties. I will call them “static validators“ in this blog post.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="cd">/** @Assert\\Callback({"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\UsernameShouldBeValid", "validate"}) */</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="cd">/** @Assert\\Callback({"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\PasswordShouldBeValid", "validate"}) */</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then, it is time to create those static validators. We just need to instantiate our value objects and check if they throw exceptions to catch them and turn them into violations.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">UsernameShouldBeValid</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">ExecutionContextInterface</span> <span class="nv">$context</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="k">try</span> <span class="p">{</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$username</span><span class="p">);</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="err">\\</span><span class="nc">InvalidArgumentException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>\n <span class="nv">$context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'account.usernameShouldBeValid'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">PasswordShouldBeValid</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">,</span> <span class="kt">ExecutionContextInterface</span> <span class="nv">$context</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="k">try</span> <span class="p">{</span>\n <span class="k">new</span> <span class="nc">Password</span><span class="p">(</span><span class="nv">$password</span><span class="p">);</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="err">\\</span><span class="nc">InvalidArgumentException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>\n <span class="nv">$context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'account.passwordShouldBeValid'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>For more complex use cases you can call any methods on value objects, but you need to keep in mind that you cannot inject services into those static validators.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="kt">BookFlightTicket</span> <span class="nv">$flightTicket</span><span class="p">,</span> <span class="kt">ExecutionContextInterface</span> <span class="nv">$context</span><span class="p">):</span> <span class="kt">void</span>\n<span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span>\n <span class="o">!</span><span class="nc">Date</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="nv">$flightTicket</span><span class="o">&gt;</span><span class="n">departureDate</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">laterThan</span><span class="p">(</span>\n <span class="nc">Date</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="nv">$flightTicket</span><span class="o">&gt;</span><span class="n">arrivalDate</span><span class="p">)</span>\n <span class="p">)</span>\n <span class="p">)</span> <span class="p">{</span>\n <span class="nv">$context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'flightTicket.dateShouldBeValid'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The first step is done! Thanks to those static validators, we apply domain validation on command properties to ensure we can instantiate domain objects. But, domain validation only works with a single account because the account aggregate only represents the account of a single user. For instance, an account cannot validate if a username is unique because it needs to be aware of the rest of the created account.</p>\n\n<p>To check if a username is used by another user we will need to ask the repository if an account already exists with the given username. That’s why we will need to create a custom validation constraint because those constraints are declared as services, and they can depend on other application services.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cd">/** @Annotation */</span>\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">UsernameShouldBeUnique</span> <span class="kd">extends</span> <span class="nc">Constraint</span>\n<span class="p">{</span>\n<span class="p">}</span>\n\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">UsernameShouldBeUniqueValidator</span> <span class="kd">extends</span> <span class="nc">ConstraintValidator</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span> <span class="o">=</span> <span class="nv">$accounts</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="nv">$username</span><span class="p">,</span> <span class="kt">Constraint</span> <span class="nv">$constraint</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nv">$constraint</span> <span class="k">instanceof</span> <span class="nc">UsernameShouldBeUnique</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">UnexpectedTypeException</span><span class="p">(</span><span class="nv">$constraint</span><span class="p">,</span> <span class="nc">UsernameShouldBeUnique</span><span class="o">::</span><span class="n">class</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">try</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span><span class="o">-&gt;</span><span class="nf">getByUsername</span><span class="p">(</span><span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$username</span><span class="p">));</span>\n\n <span class="c1">// an exception is thrown if an account does not exist so we don’t add violation</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'account.usernameShouldBeUnique'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">UnknownAccount</span> <span class="nv">$exception</span><span class="p">)</span> <span class="p">{</span>\n <span class="p">}</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Finally, we need to configure the validator to apply this new constraint to the username property.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cd">/**\n * @Assert\\GroupSequence({"CreateAnAccount", "Business"})\n */</span>\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="cd">/** \n * @Assert\\Callback({"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\UsernameShouldBeValid", "validate"})\n * @Domain\\Account\\UseCase\\ValidationRule\\UsernameShouldBeUnique(groups={"Business"})\n */</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$username</span><span class="p">;</span>\n \n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Caution:</strong> we need to apply static validators before applying custom constraints because we need to be sure we can instantiate all domain objects without raising any error. For instance, the instantiation of <code class="language-plaintext highlighter-rouge">Username</code> in <code class="language-plaintext highlighter-rouge">UsernameShouldBeUniqueValidator</code> must not raise any error because the goal of this constraint is not to check if the username contains at least three characters but if the username is already used. It can be done with <a href="https://symfony.com/doc/current/validation/sequence_provider.html">GroupSequence</a>. This validator feature allows adding groups to constraints and defining the validation constraint execution order.</p>\n\n<p>Now, this is the end of the story! If commands are invalid, we just need to serialize violations, give them to your front application, and print errors to users.</p>\n\n<h2 id="last-word">Last word</h2>\n\n<p>This might not be the only way to validate data but it worked on my previous project. Even if I use a service to validate my command I try to use as many domain objects as possible to avoid reinventing the wheel. I hope it answers Baptiste Langlade’s <a href="https://twitter.com/Baptouuuu/status/1364945053236494336">question</a> on Twitter. If you wonder, Baptiste is not my brother ;).</p>\n\n<p>Thanks to my proofreaders <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a> and <a href="https://twitter.com/jjanvier_">@jjanvier_</a>.</p>\n\n Thu, 04 Mar 2021 00:00:00 -0600\n https://arnolanglade.github.io/how-to-validate-a-command.html?s=feed\n https://arnolanglade.github.io/how-to-validate-a-command.html\n \n command-bus\n \n design-patterns\n \n \n \n \n \n Command and command handler design pattern\n <p>This pattern is really interesting; it can help you handle use cases. A command represents the user’s intent, while the command handler performs the actions needed to achieve the use case. Let’s dig a bit into these two concepts.</p>\n\n<h2 id="what-is-a-command">What is a command?</h2>\n\n<p>A command is an object used to encapsulate all the information needed to perform an action. This design pattern is used to represent user intents, and the command is given to a command handler.</p>\n\n<p>A command is often designed as a Data Transfer Object (DTO), which is an object without any behavior (a data structure). The most important design rule to consider is that a command should be easily serializable. This way, it can be sent to a queue such as RabbitMQ or pub-sub to be handled asynchronously.</p>\n\n<h2 id="what-is-a-command-handler">What is a command handler?</h2>\n\n<p>A command handler is just a callable that executes all the actions needed to fulfill a user’s intent. As you may understand, this design pattern is perfect for managing your business use cases.</p>\n\n<h2 id="how-does-it-work">How does it work?</h2>\n\n<p><img src="images/posts/command-handler/explain-command-handler.svg" alt="Command handler design pattern" /></p>\n\n<p>This pattern has some rules. The first one is that a command can be handled by a single command handler because there is only a single way to handle a use case. The second rule is that a command handler should receive a valid command. Validating the command ensures that the user provides the correct data to prevent the handling from failing. It also helps to provide early feedback to the user about the data they provided.</p>\n\n<p>The command is only a DTO that carries data while the command handler is responsible to handle use cases.</p>\n\n<h2 id="how-to-use-it">How to use it?</h2>\n\n<p>Let’s consider a simple example: creating an account. Our business expert expects users to provide an email and a password to create an account for login purposes. We will create a command named <code class="language-plaintext highlighter-rouge">CreateAnAccount</code> and its handler, <code class="language-plaintext highlighter-rouge">CreateAnAccountHandler</code>.\nFirst, we need to create a command named <code class="language-plaintext highlighter-rouge">CreateAnAccount</code> to represent the user’s intent.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="kt">readonly</span> <span class="n">string</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="k">public</span> <span class="kt">readonly</span> <span class="n">string</span> <span class="nv">$password</span><span class="p">;</span>\n \n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">)</span> \n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Next, we need to create a command handler to manage this use case. The command handler can be a function or an invocable object. It should return nothing (void) to be handled asynchronously as we don’t know when it will be processed and can’t expect an instant result. Using the command data, we perform all actions needed to handle the use case. In our example, we create an account aggregate and pass it to the account repository.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccountHandler</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span> <span class="o">=</span> <span class="nv">$accounts</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">CreateAnAccount</span> <span class="nv">$createAnAccount</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$account</span> <span class="o">=</span> <span class="nc">Account</span><span class="o">::</span><span class="nf">create</span><span class="p">(</span>\n <span class="nv">$createAnAccount</span><span class="o">-&gt;</span><span class="nf">username</span><span class="p">(),</span>\n <span class="nv">$createAnAccount</span><span class="o">-&gt;</span><span class="nf">password</span><span class="p">()</span>\n <span class="p">);</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span><span class="o">-&gt;</span><span class="nf">add</span><span class="p">(</span><span class="nv">$account</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Finally, let’s stick those pieces of code together in a controller (this example is made with a Symfony Framework). This controller receives JSON-encoded data to create a command, which is then validated and passed to the handler</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n \n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">Request</span> <span class="nv">$request</span><span class="p">):</span> <span class="kt">Response</span>\n <span class="p">{</span>\n <span class="nv">$command</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">serializer</span><span class="o">-&gt;</span><span class="nf">deserialize</span><span class="p">(</span>\n <span class="nv">$request</span><span class="o">-&gt;</span><span class="nf">getContent</span><span class="p">(),</span>\n <span class="nc">CreateAnAccount</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>\n <span class="s1">'json'</span>\n <span class="p">);</span>\n \n <span class="nv">$violations</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">validator</span><span class="o">-&gt;</span><span class="nf">validate</span><span class="p">(</span><span class="nv">$command</span><span class="p">);</span>\n \n <span class="k">if</span> <span class="p">(</span><span class="mi">0</span> <span class="o">&lt;</span> <span class="nv">$violations</span><span class="o">-&gt;</span><span class="nb">count</span><span class="p">())</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">BadRequestHttpException</span><span class="p">(</span><span class="cm">/*json encoded violation*/</span><span class="p">);</span>\n <span class="p">}</span>\n \n <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">createAnAccountHandler</span><span class="p">)(</span><span class="nv">$command</span><span class="p">);</span>\n \n <span class="k">return</span> <span class="k">new</span> <span class="nc">JsonResponse</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nc">Response</span><span class="o">::</span><span class="no">HTTP_CREATED</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n</code></pre></div></div>\n<p><strong>Tip:</strong> : To simplify command creation, you can use libraries such as the Symfony Serializer component. It eases object creation from a set of data (e.g., JSON), making the process easier and faster.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$createAccount</span> <span class="o">=</span> <span class="nv">$serializer</span><span class="o">-&gt;</span><span class="nf">deserialize</span><span class="p">(</span>\n <span class="s1">'{“username”:”arnaud”, “password”:“password”}'</span><span class="p">,</span>\n <span class="nc">CreateAnAccount</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>\n <span class="s1">'json'</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p>Tip: To avoid reinventing the wheel, you can leverage libraries like the Symfony Validator component to validate the command.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$violation</span> <span class="o">=</span> <span class="nv">$validator</span><span class="o">-&gt;</span><span class="nf">validate</span><span class="p">(</span><span class="nv">$createAccount</span><span class="p">);</span>\n</code></pre></div></div>\n\n<p>I’ve written a dedicated blog post explaining how to validate a command:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/how-to-validate-a-command.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/data-validation.webp" alt="How to validate a command?" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">How to validate a command?</span>\n </span>\n </a>\n</div>\n\n<h2 id="how-to-simplify-that">How to simplify that?</h2>\n\n<p>To simplify this controller, consider using a command bus, which is responsible for finding the right handler for a given command. For more information about this pattern, I’ve written a dedicated blog post explaining how it works:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-bus-design-pattern.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-bus/command-bus.svg" alt="The command bus design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">The command bus design pattern</span>\n </span>\n </a>\n</div>\n\n<p>The following example is built with <a href="https://symfony.com/doc/current/components/messenger.html">Symfony Messenger</a>.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">Request</span> <span class="nv">$request</span><span class="p">):</span> <span class="kt">Response</span>\n<span class="p">{</span>\n <span class="nv">$command</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">serializer</span><span class="o">-&gt;</span><span class="nf">deserialize</span><span class="p">(</span>\n <span class="nv">$request</span><span class="o">-&gt;</span><span class="nf">getContent</span><span class="p">(),</span>\n <span class="nc">CreateAnAccount</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>\n <span class="s1">'json'</span>\n <span class="p">);</span>\n \n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">commandBus</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nv">$command</span><span class="p">);</span>\n \n <span class="k">return</span> <span class="k">new</span> <span class="nc">JsonResponse</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nc">Response</span><span class="o">::</span><span class="no">HTTP_CREATED</span><span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Where is the command validation in this example? Command buses are often built with middleware, making them highly configurable. To ensure that all commands are valid before passing them to a command handler, we need to add middleware to the command bus for command validation.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">ValidationMiddleware</span> <span class="kd">implements</span> <span class="nc">MiddlewareInterface</span>\n<span class="p">{</span>\n <span class="c1">// …</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">handle</span><span class="p">(</span><span class="kt">Envelope</span> <span class="nv">$envelope</span><span class="p">,</span> <span class="kt">StackInterface</span> <span class="nv">$stack</span><span class="p">):</span> <span class="kt">Envelope</span>\n <span class="p">{</span>\n <span class="nv">$message</span> <span class="o">=</span> <span class="nv">$envelope</span><span class="o">-&gt;</span><span class="nf">getMessage</span><span class="p">();</span> \n <span class="nv">$violations</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">validator</span><span class="o">-&gt;</span><span class="nf">validate</span><span class="p">(</span><span class="nv">$message</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nv">$groups</span><span class="p">);</span>\n <span class="k">if</span> <span class="p">(</span><span class="err">\\</span><span class="nb">count</span><span class="p">(</span><span class="nv">$violations</span><span class="p">))</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">ValidationFailedException</span><span class="p">(</span><span class="nv">$message</span><span class="p">,</span> <span class="nv">$violations</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="nv">$stack</span><span class="o">-&gt;</span><span class="nb">next</span><span class="p">()</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nv">$envelope</span><span class="p">,</span> <span class="nv">$stack</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> Take a look at this blog post if you need to manage user permissions. Adding a middleware to the command bus can enhance the security of your application:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/how-to-handle-user-permissions-through-command-bus-middleware.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/how-to-handle-permissions-through-command-bus-middleware.webp" alt="How to handle user permissions through command bus middleware" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">How to handle user permissions through command bus middleware</span>\n </span>\n </a>\n</div>\n\n<h2 id="my-last-thoughts">My last thoughts</h2>\n\n<p>In many applications,I have seen a lot of classes named managers or services (e.g., AccountService, AccountManager) that gather all use case management into a single class. While this approach might be effective initially as development progresses, these classes tend to grow larger and larger, and become a “god object.” This makes maintenance challenging, reduces readability, and can quickly turn into a dump. I believe this pattern can address these issues.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Thu, 25 Feb 2021 00:00:00 -0600\n https://arnolanglade.github.io/command-handler-patterns.html?s=feed\n https://arnolanglade.github.io/command-handler-patterns.html\n \n command-bus\n \n design-patterns\n \n \n \n \n \n\n","date":"2024-01-08 08:11:03 -0600","content":"\n\n \n Arnaud Langlade\n \n https://arnolanglade.github.io/\n \n Mon, 08 Jan 2024 08:11:03 -0600\n Mon, 08 Jan 2024 08:11:03 -0600\n Jekyll v4.2.1\n \n \n Testing a React application: Secure your tests from internationalization impact\n <p>In my previous company, we automated the translation process. We used Lokalise, a cloud-based localization and translation management system. The developers imported all translation keys into the system, while the OPS team was responsible for translating all the keys.</p>\n\n<p><img src="images/posts/test-strategy-i18n-react-application/translation-management-workflow.svg" alt="translation management workflow with lokalized" /></p>\n\n<p>This process is excellent because you don’t have to wait for translations. As a developer, you add the new translation key and provide the default language. The OPS team is notified when a new key is imported into the tool. They don’t need a developer to provide translations; they are highly autonomous. Afterward, the developers need to pull the translations into the codebase and deploy the application.</p>\n\n<p>Let’s consider an example: a React Application that uses the <a href="https://github.com/formatjs/formatjs">React-Intl</a> as its internationalization system. This library provides a component called <code class="language-plaintext highlighter-rouge">FormattedMessage</code> that finds the translation for a given key and locale. This component must be used within a React Context called <code class="language-plaintext highlighter-rouge">IntlProvider</code>.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">translations</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">translation</span><span class="dl">'</span> <span class="p">};</span>\n\n\n<span class="p">&lt;</span><span class="nc">IntlProvider</span> <span class="na">locale</span><span class="p">=</span><span class="s">"en"</span> <span class="na">messages</span><span class="p">=</span><span class="si">{</span><span class="nx">translations</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">FormattedMessage</span> <span class="na">id</span><span class="p">=</span><span class="s">"key"</span> <span class="p">/&gt;</span>\n<span class="p">&lt;/</span><span class="nc">IntlProvider</span><span class="p">&gt;;</span>\n</code></pre></div></div>\n\n<p>I like wrapping the <code class="language-plaintext highlighter-rouge">IntlProvider</code> in a custom provider that allows configuring React Intl for the entire application and provides additional features like locale switching. To keep this example simple, I hardcoded the locale.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">AppIntlProvider</span><span class="p">({</span> <span class="nx">children</span> <span class="p">}:</span> <span class="p">{</span> <span class="nl">children</span><span class="p">:</span> <span class="nx">ReactElement</span> <span class="p">})</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">translations</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">translation</span><span class="dl">'</span> <span class="p">};</span>\n \n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">IntlProvider</span>\n <span class="na">messages</span><span class="p">=</span><span class="si">{</span><span class="nx">translations</span><span class="si">}</span>\n <span class="na">locale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="na">defaultLocale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">IntlProvider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now let’s go back to the testing problem. The following example is a test that checks if the <code class="language-plaintext highlighter-rouge">onClick</code> callback is called when the button with the label “OK” is clicked.`</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">MyComponent</span><span class="p">({</span> <span class="nx">onClick</span> <span class="p">}:</span> <span class="p">{</span> <span class="nl">onClick</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="k">void</span> <span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>\n // ...\n <span class="p">&lt;</span><span class="nc">Button</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">FormattedMessage</span> <span class="na">id</span><span class="p">=</span><span class="s">"validate"</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">Button</span><span class="p">&gt;</span>\n <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n<span class="c1">//const translations = { validate: 'OK' };</span>\n\n<span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">validate something</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">onClick</span> <span class="o">=</span> <span class="nx">jest</span><span class="p">.</span><span class="nx">fn</span><span class="p">();</span>\n <span class="nx">render</span><span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">MyComponent</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span> <span class="p">/&gt;,</span>\n <span class="p">{</span>\n <span class="na">wrapper</span><span class="p">:</span> <span class="nx">AppIntlProvider</span><span class="p">,</span>\n <span class="p">},</span>\n <span class="p">);</span>\n \n <span class="nx">userEvent</span><span class="p">.</span><span class="nx">click</span><span class="p">(</span><span class="nx">screen</span><span class="p">.</span><span class="nx">getByText</span><span class="p">(</span><span class="dl">'</span><span class="s1">OK</span><span class="dl">'</span><span class="p">));</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">onClick</span><span class="p">).</span><span class="nx">toHaveBeenCalled</span><span class="p">();</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>What happens if an OPS changes the translation of the ‘validate’ key from ‘OK’ to ‘GO’ for any reason? Your test will break even if the code and the test have not changed. That is a shame. Should translations break your test suites? I would like to answer this question with a no.\nThe solution that I use to prevent this problem is to override each translation that the test needs. I added an extra prop to the custom React Intl provider called overriddenTranslations that lets me override the translations my test needs.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">AppIntlProvider</span><span class="p">(</span>\n <span class="p">{</span> <span class="nx">children</span><span class="p">,</span> <span class="nx">overriddenTranslations</span> <span class="p">}:</span>\n <span class="p">{</span> <span class="nl">children</span><span class="p">:</span> <span class="nx">ReactElement</span><span class="p">,</span> <span class="nx">overriddenTranslations</span><span class="p">?:</span> <span class="nb">Partial</span><span class="o">&lt;</span><span class="nx">Translations</span><span class="o">&gt;</span> <span class="p">},</span>\n<span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">translations</span><span class="p">:</span> <span class="nx">Translations</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">translation</span><span class="dl">'</span> <span class="p">};</span>\n \n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">IntlProvider</span>\n <span class="na">messages</span><span class="p">=</span><span class="si">{</span> <span class="p">{</span> <span class="p">...</span><span class="nx">translations</span><span class="p">,</span> <span class="p">...</span><span class="nx">overriddenTranslations</span> <span class="p">}</span> <span class="si">}</span>\n <span class="na">locale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="na">defaultLocale</span><span class="p">=</span><span class="s">"en"</span>\n <span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">IntlProvider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, we only need to override the translation for the key ‘validate.’ Its value will remain ‘OK’ in the test context.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// const translations = { validate: 'GO' };</span>\n\n<span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">validate something</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">onClick</span> <span class="o">=</span> <span class="nx">jest</span><span class="p">.</span><span class="nx">fn</span><span class="p">();</span>\n <span class="nx">render</span><span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">MyComponent</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span> <span class="p">/&gt;,</span>\n <span class="p">{</span>\n <span class="na">wrapper</span><span class="p">:</span> <span class="p">(</span><span class="nx">children</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">AppIntlProvider</span> <span class="na">overriddenTranslations</span><span class="p">=</span><span class="si">{</span> <span class="p">{</span> <span class="na">validate</span><span class="p">:</span> <span class="dl">'</span><span class="s1">OK</span><span class="dl">'</span> <span class="p">}</span> <span class="si">}</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">AppIntlProvider</span><span class="p">&gt;</span>\n <span class="p">),</span>\n <span class="p">},</span>\n <span class="p">);</span>\n \n <span class="nx">userEvent</span><span class="p">.</span><span class="nx">click</span><span class="p">(</span><span class="nx">screen</span><span class="p">.</span><span class="nx">getByText</span><span class="p">(</span><span class="dl">'</span><span class="s1">OK</span><span class="dl">'</span><span class="p">));</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">onClick</span><span class="p">).</span><span class="nx">toHaveBeenCalled</span><span class="p">();</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>Overriding a translation makes the test more resilient; even if you change the translation, the test will still pass (be green). In this specific context, it allows the OPS team to change any translation without breaking the test suite.</p>\n\n Mon, 11 Dec 2023 00:00:00 -0600\n https://arnolanglade.github.io/test-strategy-i18n-react-application.html?s=feed\n https://arnolanglade.github.io/test-strategy-i18n-react-application.html\n \n react\n \n testing\n \n \n \n \n \n The Mikado Method: Small Steps, Big Improvements\n <p>In this blog post, I will introduce the Mikado Method. This method helps solve complex problems without breaking your codebase, even if you need to introduce significant changes.</p>\n\n<p>It is common to work using PR (Pull Request), you can work on your task without breaking your application and disturbing the rest of the team. However, when you start working on a task without maintaining something that works, you end up adding too many changes that are not production-ready. The drawback of this approach is that your PRs will be large and hard to merge.</p>\n\n<p>It often happens when you refactor your codebase. You start refactoring something but it breaks another part of this application, then you fix it but it introduces a new problem elsewhere. As a result, you accumulate many changes without being able to merge them.</p>\n\n<p>Merging big PR is more complicated than simple changes. First, we need to ask for code reviews, but it can be challenging for your teammate to understand what you did when your PR includes too many things. Then, another drawback is the need to rebase your PR several times due to other PRs being pushed to the main branch.</p>\n\n<p>Now, you understand why it’s difficult to introduce big changes in your codebase. It is better to work on small steps that can be mergeable at any time. The Mikado method takes its name from the Mikado game, where the goal is to remove one stick without disturbing the others. The Mikado method has the same philosophy. It aims to make small incremental improvements to a project without breaking the existing codebase. This way, you can push your changes at any time and they won’t break your application even if you did not finish your task.</p>\n\n<p>This method simplifies refactoring. You can continuously improve your codebase instead of stacking changes in a huge PR which can’t be merged because the test suites are broken. It’s better to regularly merge small changes that improve your codebase quality. This method is ideal for brownfield development. It enables you to add new features or alter existing ones without breaking the rest of the application. Moreover, it facilitates the improvement of the application’s architecture while allowing the delivery of new features concurrently.</p>\n\n<p>How does it work? Let’s take an example: MySQL doesn’t match the project’s needs; we need to use PostgreSQL. First, we need to define a goal that is clear and understandable for everyone. In our case, it is “Migrate the application from MySQL to PostgreSQL,” as you can see in the following example.</p>\n\n<p><img src="images/posts/mikado-method/define-goal.webp" alt="define a goal" /></p>\n\n<p><strong>Note:</strong> A goal can be what you want to improve in your application such as refactoring a section of the application to enhance its clarity or improving an existing feature.</p>\n\n<p>There are less chances that you can achieve your goal in a single attempt and quickly but we will try to solve it. Based on what we learn in this initial experimentation, we will split a big task (our goal) into smaller ones, which we call prerequisites. As mentioned earlier, this approach prevents ending up with a large pull request that is difficult to merge.</p>\n\n<p>To migrate the application to PostgreSQL, we first need to install the database. Then, we need to update our repositories because they use SQL queries specific to MySQL.</p>\n\n<p><img src="images/posts/mikado-method/add-prerequisites.webp" alt="add prerequisites to the mikado graph" /></p>\n\n<p>Now, you will start exploring all the prerequisites. Select a prerequisite from the list and start an experimentation to solve it. If you can easily achieve it, that’s excellent! Commit your changes, mark the prerequisite as completed, and proceed to the next one on the list.</p>\n\n<p><img src="images/posts/mikado-method/prerequisite-completed.webp" alt="prerequisite completed" /></p>\n\n<p>If you cannot easily solve it, you need to revert your changes and define a sublist of prerequisites to achieve the original prerequisite. The purpose is to avoid making big changes but to focus on working on small steps while keeping the codebase stable. Reverting changes may not be natural to a developer, but it’s an important step in the process. It allows you to continue working in smaller steps, while the exploration helps you learn what is necessary to solve a prerequisite.</p>\n\n<p><img src="images/posts/mikado-method/add-prerequisite-to-prerequisite.webp" alt="add prerequisite to prerequisite" /></p>\n\n<p>Continue to resolve all prerequisites until the end. When all prerequisites are done, your goal is completed!</p>\n\n<p><img src="images/posts/mikado-method/goal-completed.webp" alt="goal completed" /></p>\n\n<p>As you can see in the previous sections of the blog post, we can represent your progress as a graph. This is a useful way to communicate the progress of your task with the rest of the team. For example, you can show the mikado graph at the daily meeting to easily explain what you did. If, for any reason, you cannot complete your task, you can share the mikado graph with a colleague to explain what you’ve done and what remains to be done. Organizing your work becomes easier, especially when you are working on complex tasks. The Mikado graph is more visual than a simple to-do list because it allows you to see dependencies between prerequisites.</p>\n\n<p>I wrote a small application called MikadoApp to easily create and share your Mikado graphs. All the images in the blog posts are screenshots from the application. You can start using it thanks to this <a href="https://mikado-method-teal.vercel.app">link</a>, and you can find the source code on <a href="https://github.com/arnolanglade/mikado-app">GitHub</a>. Don’t hesitate to contribute to the application to improve it.</p>\n\n<p>Since I started using this method, my way of working has changed. I try to break down my work into small steps, and each commit can be pushed into production. If I refactor something, it’s great because I regularly push improvements. If I work on a feature, I can refactor what I need to create my feature without breaking the rest of the application.</p>\n\n<p>Now,I like working directly on the main branch, but I ensure that I only push stable commits. That’s what we call Trunk Based Development. This approach allows delivering small improvements to production quickly and frequently. Even though it can be practiced with PRs, I no longer prefer working with them due to the many associated processes that slow down the delivery.</p>\n\n Mon, 27 Nov 2023 00:00:00 -0600\n https://arnolanglade.github.io/mikado-method.html?s=feed\n https://arnolanglade.github.io/mikado-method.html\n \n methodology\n \n \n \n \n \n Open-Closed principle: Enhancing code modularity\n <p>Have you missed my last blog post about the <a href="/oop-inheritance-pitfalls.html">pitfalls of inheritance</a>? I explain how it could be a bad idea to use it too much. Applying composition prevents this problem; it is better to work with small classes to easily assemble. In this blog post, I will talk about the open-closed principle. This principle facilitates composition and helps avoid relying too much on inheritance.</p>\n\n<p>This principle is one of the SOLID principles, and I think it is super important because it allows you to write more flexible code. I wanted to explain it because its definition is quite simple, but it is not necessarily easy to grasp.</p>\n\n<blockquote>\n <p>The open closed principle states “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”; that is, such an entity can allow its behaviour to be extended without modifying its source code.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle">Wikipedia</a></p>\n</blockquote>\n\n<p>The first time I read the definition of this principle, I understood that I should not have to modify my code to add additional behavior. This part of the definition “open for extension” was a bit confusing. What did it mean? Does it refer to OOP inheritance? No, it doesn’t refer to OOP inheritance. I have written a blog post about OOP inheritance. It explains why extending a class to change its behavior may seem simple, but is it a good idea? It introduces a lot of coupling in your codebase and between your team.</p>\n\n<p>Before digging into the principle, let’s consider a scenario to illustrate the following example: a class called ‘DiscountCalculator’ is in charge of calculating discounts based on the products in the basket. We apply a 20% discount to products with the category ‘sport,’ a 50% discount to products with the category ‘home,’ and a 10% discount to products with the category ‘food.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">Product</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">public</span> <span class="nx">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span>\n <span class="k">public</span> <span class="nx">category</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span>\n <span class="k">public</span> <span class="nx">price</span><span class="p">:</span> <span class="kr">number</span>\n <span class="p">)</span> <span class="p">{}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">Basket</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">public</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[])</span> <span class="p">{}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">DiscountCalculator</span> <span class="p">{</span>\n <span class="nx">calculate</span><span class="p">(</span><span class="nx">basket</span><span class="p">:</span> <span class="nx">Basket</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="kd">let</span> <span class="nx">totalDiscount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>\n\n\n <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">product</span> <span class="k">of</span> <span class="nx">basket</span><span class="p">.</span><span class="nx">products</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">switch</span> <span class="p">(</span><span class="nx">product</span><span class="p">.</span><span class="nx">category</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">case</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">:</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.2</span><span class="p">;</span> <span class="c1">// 20% discount</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="k">case</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">:</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.5</span><span class="p">;</span> <span class="c1">// 50% discount</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="k">case</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">:</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.1</span><span class="p">;</span> <span class="c1">// 10% discount</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="p">}</span>\n <span class="p">}</span>\n \n <span class="k">return</span> <span class="nx">totalDiscount</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="c1">// Example usage:</span>\n<span class="nx">it</span><span class="p">.</span><span class="nx">each</span><span class="p">([</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Football</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">20</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Couch</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">100</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Banana</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>\n<span class="p">])(</span><span class="dl">'</span><span class="s1">calculates discounts for %s category</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">,</span> <span class="nx">expectedDiscount</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">product</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Product</span><span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">basket</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Basket</span><span class="p">([</span><span class="nx">product</span><span class="p">]);</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="k">new</span> <span class="nx">DiscountCalculator</span><span class="p">().</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">basket</span><span class="p">)).</span><span class="nx">toBe</span><span class="p">(</span><span class="nx">expectedDiscount</span><span class="p">);</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>This code does not follow the open-close principle because we need to modify this <code class="language-plaintext highlighter-rouge">DiscountCalculator</code> class every time we want to add or remove a discount rule. The problem is that<code class="language-plaintext highlighter-rouge">DiscountCalculator</code> may become really large if the business asks us to add a lot of discount rules. Large objects are hard to understand, so it won’t facilitate its maintenance and testability.</p>\n\n<p>Let’s refactor this code to enhance its modularity and align it with the Open-Closed principle. We will use the strategy pattern to rewrite the calculator to remove the hard-coded rules. First, we will introduce a new interface that specifies how a discount works. This interface has two methods: the first one is <code class="language-plaintext highlighter-rouge">isApplicable</code>, which determines if a discount can be applied to a product, while the second one <code class="language-plaintext highlighter-rouge">calculate</code> calculates the amount of the discount.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span>\n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span><span class="p">;</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">SportCategoryDiscount</span> <span class="k">implements</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">category</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">;</span>\n <span class="p">}</span>\n \n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.2</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">HomeCategoryDiscount</span> <span class="k">implements</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">category</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">;</span>\n <span class="p">}</span>\n \n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.5</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">FoodCategoryDiscount</span> <span class="k">implements</span> <span class="nx">Discount</span> <span class="p">{</span>\n <span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nx">boolean</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">category</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">;</span>\n <span class="p">}</span>\n \n <span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">product</span><span class="p">.</span><span class="nx">price</span> <span class="o">*</span> <span class="mf">0.1</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then, we need to update the calculator. It will determine whether a discount is applicable to a product and calculate the discount amount. With this approach, you can easily add or remove discount rules as needed.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">DiscountCalculator</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">discounts</span><span class="p">:</span> <span class="nx">Discount</span><span class="p">[])</span> <span class="p">{}</span>\n \n <span class="nx">calculateDiscount</span><span class="p">(</span><span class="nx">basket</span><span class="p">:</span> <span class="nx">Basket</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span>\n <span class="kd">let</span> <span class="nx">totalDiscount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>\n \n <span class="nx">basket</span><span class="p">.</span><span class="nx">products</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">discounts</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">discount</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">if</span><span class="p">(</span><span class="nx">discount</span><span class="p">.</span><span class="nx">isApplicable</span><span class="p">(</span><span class="nx">product</span><span class="p">))</span> <span class="p">{</span>\n <span class="nx">totalDiscount</span> <span class="o">+=</span> <span class="nx">discount</span><span class="p">.</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">product</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="p">});</span>\n <span class="p">});</span>\n \n <span class="k">return</span> <span class="nx">totalDiscount</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="c1">// Example usage:</span>\n<span class="nx">it</span><span class="p">.</span><span class="nx">each</span><span class="p">([</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Football</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">sport</span><span class="dl">'</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">20</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Couch</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">home</span><span class="dl">'</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">100</span><span class="p">],</span>\n <span class="p">[</span><span class="dl">'</span><span class="s1">Banana</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">food</span><span class="dl">'</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>\n<span class="p">])(</span><span class="dl">'</span><span class="s1">calculates discounts for %s category</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">,</span> <span class="nx">expectedDiscount</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">product</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Product</span><span class="p">(</span><span class="nx">productName</span><span class="p">,</span> <span class="nx">category</span><span class="p">,</span> <span class="nx">price</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">basket</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Basket</span><span class="p">([</span><span class="nx">product</span><span class="p">]);</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="k">new</span> <span class="nx">DiscountCalculator</span><span class="p">([</span>\n <span class="k">new</span> <span class="nx">SportCategoryDiscount</span><span class="p">(),</span>\n <span class="k">new</span> <span class="nx">HomeCategoryDiscount</span><span class="p">(),</span>\n <span class="k">new</span> <span class="nx">FoodCategoryDiscount</span><span class="p">(),</span>\n <span class="p">]).</span><span class="nx">calculate</span><span class="p">(</span><span class="nx">basket</span><span class="p">)).</span><span class="nx">toBe</span><span class="p">(</span><span class="nx">expectedDiscount</span><span class="p">);</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>We don’t need to over-engineer to apply the open-close principle. With the right design pattern, it is quite simple. Now, the discount calculator is more flexible. We didn’t introduce a lot of new code but we divided the class into smaller ones. Small classes are easier to test and understand, and it will facilitate the maintenance and the evolution of your application.</p>\n\n\n Mon, 13 Nov 2023 00:00:00 -0600\n https://arnolanglade.github.io/open-close-principle.html?s=feed\n https://arnolanglade.github.io/open-close-principle.html\n \n OOP\n \n SOLID\n \n \n \n \n \n The pitfalls of OOP's inheritance: Why simple isn't always better\n <p>In OOP, the simplest way to change the behavior of a class A is to create a class B that extends class A. Extensions allow you to override any public and protected methods of the parent class. That‘s quite simple, right?</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/simple-inheritance.svg" alt="Simple object inheritance" /></p>\n\n<p>Furthermore, you can extend a class multiple times with several levels of inheritance. In the following example, we can see that class B has two children, and the class hierarchy has four levels of inheritance. Now let’s explore why it is not a good idea and which problem can occur?</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/inheritance-with-several-levels.svg" alt="Object inheritance with several levels" /></p>\n\n<p>Designing code like this won’t facilitate refactoring. Let’s consider a scenario where Class A has a method that is overridden in both Class B and Class E. What happens if we decide to change the signature of this method in Class A? We will need to rewrite this method in Class B and Class E to match the new signature. Another frustrating aspect is that we will have to modify all portions of the code that use this method. In a small codebase, this may be manageable, but in a large one, it’s a different story!</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/refactoring-inheritance-with-several-levels.svg" alt="Refactoring with object inheritance with several levels" /></p>\n\n<p>This code won’t ease team collaboration. Let’s consider another scenario: where we are working on a huge monolith shared with several other teams. What happens if team A needs to change class A? That means teams B, C, and D must also update their codebases. We have introduced coupling between these three teams because of the coupling between classes A, B, C, and D. That’s a shame. This design will slow down your delivery because team A will need to coordinate with three other teams if it needs to change class A.</p>\n\n<p><img src="images/posts/pitfalls-of-oop-inheritance/refactoring-inheritance-with-several-teams.svg" alt="Refactoring with object inheritance with several teams" /></p>\n\n<p>I have worked on several codebases that heavily relied on inheritance, but now I barely use it due to the drawbacks I’ve described. Instead, I prefer to use composition. It is better to work with several small classes and assemble them, it’s like playing with Lego blocks. Moreover, it greatly simplifies testing.</p>\n\n<p>I try to apply the open-closed principle as much as possible to enhance code modularity and facilitate evolution. In a related blog post, I explain the principle and provide an example to illustrate how to refactor code that doesn’t follow this principle. Here is the link:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/open-close-principle.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/open-close-principle.webp" alt="Open-Closed principle: Enhancing code modularity" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Open-Closed principle: Enhancing code modularity</span>\n </span>\n </a>\n</div>\n\n\n Mon, 23 Oct 2023 00:00:00 -0500\n https://arnolanglade.github.io/oop-inheritance-pitfalls.html?s=feed\n https://arnolanglade.github.io/oop-inheritance-pitfalls.html\n \n OOP\n \n \n \n \n \n Why breaking encapsulation is not a good idea\n <p>In this blog post, I would like to speak about an important concept in Oriented Object Programming which is the encapsulation principle.</p>\n\n<p>Before speaking about encapsulation let’s talk a bit about OOP. What is the object’s life cycle? The first step of the object’s life cycle is to be instantiated. We give everything an object needs to initialise its internal state. Then we use its public API (public methods) to communicate with it. An object exposes a public API (behaviour) that manipulates its internal state (data).</p>\n\n<p><img src="images/posts/why-breaking-encapsulation-is-not-a-good-idea/object-life-cycle.svg" alt="Object life cycle" /></p>\n\n<p>So, what is encapsulation? This principle restricts direct access to the state of the object from outside. This means that the internal implementation details of a class are hidden. Accessing the state of the object is only allowed through its public API (public methods). This concept helps to protect the data from outside interference and ensures controlled and secured data manipulation.</p>\n\n<p><strong>Note:</strong> An object that only has getters and setters is not an object! This is a data structure because it has no behaviour.</p>\n\n<p>I worked on many applications that used getters and setters. They are good examples of what is breaking encapsulation. It is easy to break encapsulation but it is not a good idea. It will make your code less maintainable and your applications less evolutive. Let’s take a simple example to understand why breaking encapsulation is a bad idea. I want to find the closest point of interest on a map close to a given location.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Location</span> <span class="o">=</span> <span class="p">{</span>\n <span class="na">latitude</span><span class="p">:</span> <span class="kr">number</span>\n <span class="na">longitude</span><span class="p">:</span> <span class="kr">number</span>\n<span class="p">}</span>\n\n\n<span class="kd">type</span> <span class="nx">PointOfInterest</span> <span class="o">=</span> <span class="p">{</span>\n <span class="na">name</span><span class="p">:</span> <span class="kr">string</span>\n <span class="na">location</span><span class="p">:</span> <span class="nx">Location</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nb">Map</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">pointOfInterests</span><span class="p">:</span> <span class="nx">PointOfInterest</span><span class="p">[])</span> <span class="p">{}</span>\n\n\n <span class="nx">getPointOfInterests</span><span class="p">():</span> <span class="nx">PointOfInterest</span><span class="p">[]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">pointOfInterests</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">AClassWhereWeNeedToFindClosestPOI</span> <span class="p">{</span>\n <span class="nx">doSomething</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">pointOfInterest</span> <span class="o">=</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getPointOfInterests</span><span class="p">()</span>\n <span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">pointOfInterest</span><span class="p">:</span> <span class="nx">PointOfInterest</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">})[</span><span class="mi">0</span><span class="p">]</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">Map</code> class has a <code class="language-plaintext highlighter-rouge">getPointOfInterest</code> getter that gets the class property with the same name. Then we can use this getter to access the list of points of interest to iterate them and find the closest one.</p>\n\n<p>The drawback with this getter is that we will need to copy/paste this piece of code if we have to look for the closest point of interest in several places. It won’t help you to mutualize code. At best, you can extract this piece of code into a dedicated class like the following example:</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">POIFinder</span> <span class="p">{</span>\n <span class="nx">find</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">):</span> <span class="nx">PointOfInterest</span> <span class="p">{</span>\n <span class="k">return</span> <span class="nx">map</span><span class="p">.</span><span class="nx">getPointOfInterests</span><span class="p">()</span>\n <span class="p">.</span><span class="nx">filter</span><span class="p">((</span><span class="nx">pointOfInterest</span><span class="p">:</span> <span class="nx">PointOfInterest</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">})[</span><span class="mi">0</span><span class="p">]</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The problem with this code is that we extract the <code class="language-plaintext highlighter-rouge">Map</code> object behaviour into another class. We will turn the <code class="language-plaintext highlighter-rouge">Map</code> object into a data structure if we remove all methods that add a behaviour to it.</p>\n\n<p><strong>Note:</strong> A class that ends with -ER (like in the previous example) is a good insight into how this class does the job of another class.</p>\n\n<p>What happens if we need to change the internal of the POI list? Now, we don’t want to use an array anymore, we want to manage the POI list with a custom class named <code class="language-plaintext highlighter-rouge">PointOfInterestList</code>. It might be a simple refactoring for small applications but it is super painful for huge ones. If the getter method is used hundreds of times, we will have to refactor each <code class="language-plaintext highlighter-rouge">getPointOfInterest</code> usage to make them compatible with the new signature.</p>\n\n<p>To avoid this problem, we only need to apply the “Tell, don’t ask” principle. This principle says that we should tell an object to do something instead of asking for its internal state to do something in his stead.</p>\n\n<p>The solution would be to add a <code class="language-plaintext highlighter-rouge">findClosestPointOfInterest</code> method to the <code class="language-plaintext highlighter-rouge">Map</code> object. The only purpose of this method is to find the closest POI no matter how the POI list is designed. This allows you to refactor the internal state of the object as many times you want.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">ListOfPointOfInterest</span> <span class="p">{</span>\n <span class="nx">findClosest</span><span class="p">(</span><span class="nx">location</span><span class="p">:</span> <span class="nx">Location</span><span class="p">)</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nb">Map</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">pointOfInterests</span><span class="p">:</span> <span class="nx">ListOfPointOfInterest</span><span class="p">)</span> <span class="p">{}</span>\n\n\n <span class="nx">findClosestPointOfInterest</span><span class="p">(</span><span class="nx">location</span><span class="p">:</span> <span class="nx">Location</span><span class="p">):</span> <span class="nx">PointOfInterest</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">pointOfInterests</span><span class="p">.</span><span class="nx">findClosest</span><span class="p">(</span><span class="nx">location</span><span class="p">)</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> Breaking encapsulation to test your code is a bad idea too. I’ve written an article to present you with an alternative to the getter to prevent exposing the state of the objects. Here is the link:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/you-should-not-expose-objects-state-to-test-them.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/test-comparison.webp" alt="Why you should not expose objects' state to test them" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Why you should not expose objects' state to test them</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 19 Sep 2023 00:00:00 -0500\n https://arnolanglade.github.io/why-breaking-encapsulation-is-not-a-good-idea.html?s=feed\n https://arnolanglade.github.io/why-breaking-encapsulation-is-not-a-good-idea.html\n \n testing\n \n OOP\n \n \n \n \n \n Don’t test private methods\n <p>It is pretty easy to make mistakes when you start testing your code. One of the first mistakes I made was to test private methods. Spoiler alert: it was a bad idea because I had to use reflection to make them public to access them. If you need to test a private method, it probably means that your code is not well designed</p>\n\n<p>We don’t test private methods. Private methods are implementation details of objects and we should not care about them. Don’t worry! They are tested in the end. When you test public methods you also test the private ones as described in the next schema.</p>\n\n<p><img src="images/posts/do-not-test-private-method/test-private-methods-through-public-ones.svg" alt="Test private methods through public ones" /></p>\n\n<p>I needed to test the private methods because my object was a God object (huge object). It did a lot of things. It had a few public methods and a lot of private ones because too many things happened behind the scenes.</p>\n\n<p><img src="images/posts/do-not-test-private-method/object-with-too-many-private-methods.svg" alt="Object with too many private methods" /></p>\n\n<p>The problem with this design is this object did not follow the <strong>S</strong>ingle <strong>R</strong>esponsibility <strong>P</strong>rinciple, but what is this principle?</p>\n\n<blockquote>\n <p>There should never be more than one reason for a class to change. In other words, every class should have only one responsibility</p>\n\n <p><a href="https://en.wikipedia.org/wiki/SOLID">wikipedia</a></p>\n</blockquote>\n\n<p>My object was super huge because it did too many things. It had too many responsibilities. Because of that, I could not test it easily. How can we avoid that?</p>\n\n<p><img src="images/posts/do-not-test-private-method/complicated-to-test-objects-with-many-responsibilities.svg" alt="complicated to test objects with many responsibilities" /></p>\n\n<p>It’s better to work on small problems than a big one. The solution would have been to identify each responsibility to extract them into dedicated objects. We don’t need magic tricks to test small objects. It is simple to test them because they do a simple thing, and we only need to use their public API (public method) to test them. We don’t need reflection anymore.</p>\n\n<p><img src="images/posts/do-not-test-private-method/split-good-objects-into-small-classes.svg" alt="split good objects into small classes" /></p>\n\n<p>Then, we need to apply the composition pattern to assemble those classes to make them work as the God object. Composition is like playing Lego: we have many small bricks, and we put them together to make a big piece. Software is the same. You should work with small classes/functions to easily test them and piece them together to make your feature.</p>\n\n<p>Let’s take an example. The following class is in charge of importing products into an application as a PIM or an ERP. This class does several things, it gets product data from a CSV file and it imports them into a database. We need to test the whole class to ensure the product import works as expected. That’s a bit annoying because I can’t test the CSV file reading or the production saving.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Product</span> <span class="o">=</span> <span class="p">{</span>\n <span class="na">name</span><span class="p">:</span> <span class="kr">string</span>\n <span class="na">description</span><span class="p">:</span> <span class="kr">string</span>\n<span class="p">};</span>\n\n<span class="kd">class</span> <span class="nx">ProductImport</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">connection</span><span class="p">:</span> <span class="nx">Connection</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">async</span> <span class="k">import</span><span class="p">(</span><span class="nx">filePath</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">loadProductFromCsvFile</span><span class="p">(</span><span class="nx">filePath</span><span class="p">);</span>\n <span class="p">}</span>\n \n <span class="k">private</span> <span class="k">async</span> <span class="nx">loadProductFromCsvFile</span><span class="p">(</span><span class="nx">file</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="na">csvData</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>\n <span class="nx">createReadStream</span><span class="p">(</span><span class="nx">file</span><span class="p">)</span>\n <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">csvParser</span><span class="p">())</span>\n <span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">data</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="na">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">csvData</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">product</span><span class="p">))</span>\n <span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">end</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">for</span> <span class="p">(</span><span class="kd">const</span> <span class="nx">data</span> <span class="k">of</span> <span class="nx">csvData</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">saveProducts</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="p">});</span>\n <span class="p">}</span>\n\n <span class="k">private</span> <span class="k">async</span> <span class="nx">saveProducts</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">execute</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">INSERT INTO products (name, description) VALUES (?, ?)</span><span class="dl">'</span><span class="p">,</span>\n <span class="p">[</span><span class="nx">product</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">product</span><span class="p">.</span><span class="nx">description</span><span class="p">],</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>We need to split this class into smaller ones to ease testing. We will extract both private methods into dedicated classes.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">CsvProductLoader</span> <span class="p">{</span>\n <span class="k">async</span> <span class="nx">loadProduct</span><span class="p">(</span><span class="nx">file</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nx">Product</span><span class="p">[]</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="na">products</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>\n <span class="nx">createReadStream</span><span class="p">(</span><span class="nx">file</span><span class="p">)</span>\n <span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">csvParser</span><span class="p">())</span>\n <span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">data</span><span class="dl">'</span><span class="p">,</span> <span class="p">(</span><span class="na">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nx">products</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">product</span><span class="p">));</span>\n \n <span class="k">return</span> <span class="nx">products</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">MysqlProducts</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">connection</span><span class="p">:</span> <span class="nx">Connection</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">async</span> <span class="nx">save</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">connection</span><span class="p">.</span><span class="nx">execute</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">INSERT INTO products (name, description) VALUES (?, ?)</span><span class="dl">'</span><span class="p">,</span>\n <span class="p">[</span><span class="nx">product</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">product</span><span class="p">.</span><span class="nx">description</span><span class="p">],</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n<p>Now, we can test them stand-alone because these classes expose public methods. We don’t need a magic trick such as reflection to change their visibility to test them.</p>\n\n<p>We still need the <code class="language-plaintext highlighter-rouge">ProductImport</code> class. It will depend on both previous classes and act as a controller. It asks <code class="language-plaintext highlighter-rouge">CsvProductLoader</code> to get the product information from the CSV file and asks <code class="language-plaintext highlighter-rouge">CsvProductLoader</code> to save them into a database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">ProductImport</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">productLoader</span><span class="p">:</span> <span class="nx">CsvProductLoader</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">MysqlProducts</span><span class="p">,</span>\n <span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">async</span> <span class="k">import</span><span class="p">(</span><span class="nx">filePath</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">products</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">productLoader</span><span class="p">.</span><span class="nx">loadProduct</span><span class="p">(</span><span class="nx">filePath</span><span class="p">);</span>\n <span class="nx">products</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="na">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">products</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span><span class="nx">product</span><span class="p">));</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>That’s great because we extract IO usage into new classes. Both <code class="language-plaintext highlighter-rouge">MysqlProducts</code> and <code class="language-plaintext highlighter-rouge">CsvProductLoader</code> need to be tested with integration/contract tests since <code class="language-plaintext highlighter-rouge">ProductImport</code> can be unit tested.</p>\n\n<p>We need to make a last change. We cannot rely on concrete classes. We need to introduce interfaces to avoid coupling between <code class="language-plaintext highlighter-rouge">ProductImport</code> and its dependencies (<code class="language-plaintext highlighter-rouge">MysqlProducts</code> and <code class="language-plaintext highlighter-rouge">CsvProductLoader</code>).</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">ProductLoader</span> <span class="p">{</span>\n <span class="nx">loadProduct</span><span class="p">(</span><span class="nx">file</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nx">Product</span><span class="p">[]</span><span class="o">&gt;</span>\n<span class="p">}</span>\n\n<span class="kr">interface</span> <span class="nx">Products</span> <span class="p">{</span>\n <span class="nx">save</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nx">ProductImport</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">productLoader</span><span class="p">:</span> <span class="nx">ProductLoader</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">Products</span><span class="p">,</span>\n <span class="p">)</span> <span class="p">{}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note</strong>: I’ve written an article about how the inversion dependency design pattern will ease testing. Here is the link:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/inversion-dependency/ease-testing-thanks-to-the-dependency-inversion-design-pattern.webp" alt="Ease testing thanks to the dependency inversion design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Ease testing thanks to the dependency inversion design pattern</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 17 Jul 2023 00:00:00 -0500\n https://arnolanglade.github.io/do-not-test-private-methods.html?s=feed\n https://arnolanglade.github.io/do-not-test-private-methods.html\n \n testing\n \n OOP\n \n \n \n \n \n Ease testing thanks to the dependency inversion design pattern\n <p>In this new blog post, I would like to speak about the dependency inversion design pattern. This pattern makes your code more modular and helps to improve codebase testability. It’s quite simple and super powerful.</p>\n<h2 id="what-does-this-design-pattern-say">What does this design pattern say?</h2>\n<p>A class should not depend on another one to avoid coupling them together. If a class is coupled with another one, it means you won’t be able to use the first one without the second one.</p>\n\n<p><img src="images/posts/inversion-dependency/concrete-class-should-not-use-concrete-class.svg" alt="Concrete class should not use concrete class" /></p>\n\n<p>The classes should only depend on abstractions (e.g. interfaces). An interface can be implemented in several ways. It will make your code more modular because you can use a specific implementation depending on the context.</p>\n\n<p><img src="images/posts/inversion-dependency/depend-on-abstraction.svg" alt="Concrete class should depend on abstraction" /></p>\n\n<p>The interfaces should not depend on concrete implementations to avoid coupling them to another class.</p>\n\n<p><img src="images/posts/inversion-dependency/abstraction-should-not-use-concrete-class.svg" alt="Abstraction should not use concrete class" /></p>\n\n<h2 id="how-does-this-pattern-improve-testability">How does this pattern improve testability?</h2>\n\n<p>Let’s see with a simple example how dependency inversion helps to make your code easily testable. The following class lets a cartographer add a marker on a map.</p>\n\n<p><strong>Note:</strong> I wrote an article about unit testing to help you to understand the main mistakes that make your codebase less testable. Here is the link https://arnolanglade.github.io/why-unit-testing-can-be-hard.html.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">AddMarkerToMap</span> <span class="p">{</span>\n <span class="nx">execute</span><span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">repository</span> <span class="o">=</span> <span class="nx">PosgresqlMaps</span><span class="p">.</span><span class="nx">getInstance</span><span class="p">()</span>\n \n <span class="kd">const</span> <span class="nx">map</span> <span class="o">=</span> <span class="nx">repository</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="nx">marker</span><span class="p">.</span><span class="nx">mapId</span><span class="p">)</span>\n \n <span class="nx">map</span><span class="p">.</span><span class="nx">addMarker</span><span class="p">(</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span><span class="p">,</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="p">,</span>\n <span class="p">)</span>\n\n <span class="nx">repository</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">)</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>This class uses a singleton <code class="language-plaintext highlighter-rouge">PosgresqlMaps.getInstance()</code> to retrieve an instance of the <code class="language-plaintext highlighter-rouge">PosgresqlMaps</code> repository. This repository is in charge of saving map data into a PostgreSQL database. The problem is that we cannot run this code without a working database. This class is coupled to the <code class="language-plaintext highlighter-rouge">PosgresqlMaps</code> repository.</p>\n\n<p>We don’t want to use IO (your tools like a database) when we unit-test a piece of code because we want to avoid setting up any tools to a short feedback loop. We only want to check if a section of the application behaves as expected. We don’t want to test if the map data is well stored.</p>\n\n<p>Using the dependency inversion pattern will help us to remove the coupling between <code class="language-plaintext highlighter-rouge">AddMarkerToMap</code> and <code class="language-plaintext highlighter-rouge">PosgresqlMaps</code> and make it easy to unit test.</p>\n\n<p>First, we need to remove the coupling between both classes. We will create an abstraction to define how to retrieve and save maps in the application.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">Maps</span> <span class="p">{</span>\n <span class="kd">get</span><span class="p">(</span><span class="nx">mapId</span><span class="p">:</span> <span class="nx">MapId</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nb">Map</span><span class="o">&gt;</span><span class="p">;</span>\n <span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> When I cannot use a business term to name a repository I pluralize the name of my aggregate to name it. That’s why I name it <code class="language-plaintext highlighter-rouge">Maps</code> because I want to handle map aggregate persistence.</p>\n\n<p>Now, we can create as many implementations as we need. We will create a dedicated implementation for testing purposes. It will only keep it in memory which will avoid using a database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">InMemoryMaps</span> <span class="k">implements</span> <span class="nx">Maps</span> <span class="p">{</span>\n <span class="k">private</span> <span class="nx">maps</span><span class="p">:</span> <span class="nb">Record</span><span class="o">&lt;</span><span class="nx">MapId</span><span class="p">,</span> <span class="nb">Map</span><span class="o">&gt;</span><span class="p">;</span>\n \n <span class="k">async</span> <span class="kd">get</span><span class="p">(</span><span class="nx">mapId</span><span class="p">:</span> <span class="nx">MapId</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nb">Map</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">[</span><span class="nx">mapId</span><span class="p">];</span>\n <span class="p">}</span>\n\n <span class="k">async</span> <span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">[</span><span class="nx">map</span><span class="p">.</span><span class="nx">id</span><span class="p">()]</span> <span class="o">=</span> <span class="nx">map</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> I name all implementations with a prefix depending on what they are. If a repository uses a database, I will prefix the class with the name of the database. When I create an implementation for testing purposes, I use the <code class="language-plaintext highlighter-rouge">InMemory</code> prefix.</p>\n\n<p>As we want to create a working application, we will create an implementation which uses a database for the production environment.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">PosgresqlMaps</span> <span class="k">implements</span> <span class="nx">Maps</span> <span class="p">{</span>\n <span class="c1">// …</span>\n <span class="k">async</span> <span class="kd">get</span><span class="p">(</span><span class="nx">mapId</span><span class="p">:</span> <span class="nx">MapId</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nb">Map</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">map</span> <span class="o">=</span> <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span>\n <span class="s2">`SELECT * FROM maps WHERE id = </span><span class="p">${</span><span class="nx">mapId</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span>\n <span class="p">);</span>\n\n\n <span class="k">return</span> <span class="k">new</span> <span class="nb">Map</span><span class="p">(</span><span class="nx">map</span><span class="p">);</span>\n <span class="p">}</span>\n \n <span class="k">async</span> <span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">:</span> <span class="nb">Map</span><span class="p">):</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="k">void</span><span class="o">&gt;</span> <span class="p">{</span>\n <span class="k">await</span> <span class="k">this</span><span class="p">.</span><span class="nx">client</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span>\n <span class="s2">`INSERT INTO maps VALUES (</span><span class="p">${</span><span class="nx">map</span><span class="p">.</span><span class="nx">toState</span><span class="p">()}</span><span class="s2">)`</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>We need to refactor a bit the <code class="language-plaintext highlighter-rouge">AddMarkerToMap</code> class to be able to inject an implementation of the <code class="language-plaintext highlighter-rouge">Maps</code> interface.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">AddMarkerToMap</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">maps</span><span class="p">:</span> <span class="nx">Maps</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="nx">execute</span><span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">map</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="nx">marker</span><span class="p">.</span><span class="nx">mapId</span><span class="p">)</span>\n\n\n <span class="nx">map</span><span class="p">.</span><span class="nx">addMarker</span><span class="p">(</span>\n <span class="nx">marker</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="p">,</span> <span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span>\n <span class="p">)</span>\n \n <span class="k">this</span><span class="p">.</span><span class="nx">maps</span><span class="p">.</span><span class="nx">save</span><span class="p">(</span><span class="nx">map</span><span class="p">)</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Finally, we can test this class because we can instantiate the <code class="language-plaintext highlighter-rouge">AddMarkerToMap</code> class with the <code class="language-plaintext highlighter-rouge">InMemoryMaps</code> class. This implementation helps us to test this class because it does not use any IO. Here, we don’t want to test if the data are well persisted but we want to test the business logic of marker addition on a map.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">adds a new marker to the map</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">maps</span> <span class="o">=</span> <span class="nx">InMemoryMaps</span><span class="p">()</span>\n \n <span class="k">new</span> <span class="nx">AddMarkerToMap</span><span class="p">(</span><span class="nx">maps</span><span class="p">).</span><span class="nx">execute</span><span class="p">({</span>\n <span class="na">mapId</span><span class="p">:</span> <span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">,</span> <span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Le Sunset</span><span class="dl">'</span><span class="p">,</span>\n <span class="na">latitude</span><span class="p">:</span> <span class="mf">23.252353245</span><span class="p">,</span> <span class="na">longitude</span><span class="p">:</span> <span class="mf">43.5432563457</span>\n <span class="p">})</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">maps</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span>\n <span class="k">new</span> <span class="nb">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nx">Marker</span><span class="p">(</span><span class="dl">'</span><span class="s1">Le Sunset</span><span class="dl">'</span><span class="p">,</span> <span class="mf">23.252353245</span><span class="p">,</span> <span class="mf">43.5432563457</span><span class="p">)</span>\n <span class="p">)</span>\n <span class="p">)</span>\n<span class="p">})</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> We don’t use a unit test to ensure the application uses its tools well. We use integration tests for this. For instance, if we want to ensure that a repository works as expected.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 19 Jun 2023 00:00:00 -0500\n https://arnolanglade.github.io/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html?s=feed\n https://arnolanglade.github.io/ease-testing-thanks-to-the-dependency-inversion-design-pattern.html\n \n testing\n \n design-pattern\n \n OOP\n \n \n \n \n \n Use composition instead of props drilling\n <p>In this blog post, I would like to speak about how composition can improve your React codebase. It’s easy to add a lot of props to your component to make them configurable but it’s not a good idea.</p>\n\n<p>Let’s take an example. You are working on an e-Commerce webshop. A <code class="language-plaintext highlighter-rouge">ProductList</code> is used in the shop and the shop administration displays a list of products. In the shop administration, the component displays the product information and some calls to action (like product deletion and categorization for example) to manage products. In the shop you only need to display the product information, so, you don’t want to display the calls to action.</p>\n\n<p>As we can see in the next example, most of the <code class="language-plaintext highlighter-rouge">ProductList</code> props are used to render and configure the checkbox or the button.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductList</span><span class="p">({</span>\n <span class="nx">products</span><span class="p">,</span>\n <span class="nx">displayCheckbox</span><span class="p">,</span>\n <span class="nx">displayAction</span><span class="p">,</span>\n <span class="nx">actionLabel</span><span class="p">,</span>\n <span class="nx">onCheckboxClick</span><span class="p">,</span>\n <span class="nx">onActionClick</span><span class="p">,</span>\n<span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">products</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">product</span> <span class="o">=&gt;</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">displayCheckbox</span> <span class="o">&amp;&amp;</span>\n <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="p">=</span><span class="s">"checkbox"</span> <span class="na">onclick</span><span class="p">=</span><span class="si">{</span><span class="nx">onCheckboxClick</span><span class="si">}</span> <span class="p">/&gt;</span> <span class="p">:</span> <span class="kc">null</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">product</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">displayAction</span> <span class="o">&amp;&amp;</span>\n <span class="p">&lt;</span><span class="nt">button</span> <span class="na">onclick</span><span class="p">=</span><span class="si">{</span><span class="nx">onActionClick</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">actionLabel</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> <span class="p">:</span> <span class="kc">null</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n</code></pre></div></div>\n\n<p>This component is used in the <code class="language-plaintext highlighter-rouge">AdminShop</code>and <code class="language-plaintext highlighter-rouge">Shop</code> pages to display the product list to the customer or the shop owner.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Display to shop owner</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">AdminShop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getAllProducts</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span>\n <span class="na">products</span><span class="p">=</span><span class="si">{</span><span class="nx">products</span><span class="si">}</span>\n <span class="na">displayCheckbox</span><span class="p">=</span><span class="si">{</span><span class="kc">true</span><span class="si">}</span>\n <span class="na">displayAction</span><span class="p">=</span><span class="si">{</span><span class="kc">true</span><span class="si">}</span>\n <span class="na">actionLabel</span><span class="p">=</span><span class="s">"delete"</span>\n <span class="na">onCheckboxClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span>\n <span class="na">onActionClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span>\n <span class="p">/&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="c1">// Display to customers</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">Shop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getProductsAvailableforSale</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span>\n <span class="na">products</span><span class="p">=</span><span class="si">{</span><span class="nx">products</span><span class="si">}</span>\n <span class="na">displayCheckbox</span><span class="p">=</span><span class="si">{</span><span class="kc">false</span><span class="si">}</span>\n <span class="na">displayAction</span><span class="p">=</span><span class="si">{</span><span class="kc">false</span><span class="si">}</span>\n <span class="p">/&gt;</span>\n\n\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">ProductList</code> has to display elements depending on the given props. This big component will help mutualize the code but it will introduce complexity. Adding too many props will make your components complex, and hard to understand and maintain. Composition will help us to get rid of those props.</p>\n\n<p><strong>Note:</strong> The <code class="language-plaintext highlighter-rouge">ProductList</code> component only has 3 props because I wanted to keep the example simple but guess what happens when your components have tens of props to configure them?</p>\n\n<p>How can composition help us? It’s like playing Lego. You need several bricks from different sizes and colors to create something. The big <code class="language-plaintext highlighter-rouge">ProductList</code> component can be split into several small components used to build the product list depending on business cases.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductList</span><span class="p">({</span><span class="nx">children</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">children</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">Product</span><span class="p">({</span><span class="nx">label</span><span class="p">,</span> <span class="nx">checkbox</span><span class="p">,</span> <span class="nx">action</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">checkbox</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">label</span><span class="si">}</span>\n <span class="si">{</span><span class="nx">action</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductCheckbox</span><span class="p">({</span><span class="nx">onClick</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">&lt;</span><span class="nt">input</span> <span class="na">type</span><span class="p">=</span><span class="s">"checkbox"</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span><span class="p">/&gt;;</span>\n<span class="p">}</span>\n\n\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">ProductAction</span><span class="p">({</span><span class="nx">onClick</span><span class="p">,</span> <span class="nx">actionLabel</span><span class="p">})</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">&lt;</span><span class="nt">button</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">onClick</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">actionLabel</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>In the previous code example, we created 4 new components: <code class="language-plaintext highlighter-rouge">ProductList</code>, <code class="language-plaintext highlighter-rouge">Product</code>, <code class="language-plaintext highlighter-rouge">ProductCheckbox</code> and <code class="language-plaintext highlighter-rouge">ProductAction</code>. They are like Lego bricks and we can assemble them to create the product list with or without the call to action.</p>\n\n<p><strong>Note:</strong> It’s not mandatory to create a dedicated component for the checkbox and the button. It can be useful to wrap generic components into more business-oriented ones. It helps to make things clearer. It’s another way to apply composition.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Display to shop owner</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">AdminShop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getAllProducts</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">products</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">product</span> <span class="o">=&gt;</span> \n <span class="p">&lt;</span><span class="nc">Product</span>\n <span class="na">label</span><span class="p">=</span><span class="si">{</span><span class="nx">product</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span>\n <span class="na">checkbox</span><span class="p">=</span><span class="si">{</span><span class="p">&lt;</span><span class="nc">ProductCheckbox</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span> <span class="p">/&gt;</span><span class="si">}</span>\n <span class="na">action</span><span class="p">=</span><span class="si">{</span><span class="p">&lt;</span><span class="nc">ProductAction</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="cm">/* callback */</span><span class="si">}</span> <span class="na">actionLabel</span><span class="p">=</span><span class="si">{</span><span class="dl">"</span><span class="s2">delete</span><span class="dl">"</span><span class="si">}</span> <span class="p">/&gt;</span><span class="si">}</span>\n <span class="p">/&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n\n<span class="c1">// Display to customers</span>\n<span class="k">export</span> <span class="kd">function</span> <span class="nx">Shop</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">products</span><span class="p">,</span> <span class="nx">setProducts</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setProducts</span><span class="p">(</span><span class="nx">getProductAvailableforSale</span><span class="p">())</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">products</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">product</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nc">Product</span> <span class="na">label</span><span class="p">=</span><span class="si">{</span><span class="nx">product</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span> <span class="p">/&gt;)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ProductList</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Small components are easier to test. They help build more stable applications and are easier to maintain. Your codebase will be less complex to understand. It will decrease your and your teammates’ mental load because you won’t have any components with complex API and logic.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 22 May 2023 00:00:00 -0500\n https://arnolanglade.github.io/use-composition-instead-of-props-drilling.html?s=feed\n https://arnolanglade.github.io/use-composition-instead-of-props-drilling.html\n \n react\n \n testing\n \n \n \n \n \n How to use custom React hook to increase application testability\n <p>In my previous blog, I spoke about reducing coupling in a React app to improve testing. Now I will show you how a custom React hook can increase testability.</p>\n\n<p><strong>Note:</strong> I assume that you are comfortable with React hooks. If you aren’t, please have a look at the <a href="https://reactjs.org/docs/hooks-intro.html">React documentation</a></p>\n\n<p>First of all, I will show you some code that is not testable. In my <a href="https://mymaps.world">side project</a>, I use <code class="language-plaintext highlighter-rouge">react-map-gl</code> to create maps with <a href="https://www.mapbox.com/">Mapbox</a>. Unfortunately, I can’t render the map with the testing library because this library only works in a web browser. I might have done something wrong but I haven’t found any solution to solve this problem.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">MapPage</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span><span class="nx">mapId</span><span class="p">}</span> <span class="o">=</span> <span class="nx">useParams</span><span class="o">&lt;</span><span class="p">{</span> <span class="na">mapId</span><span class="p">:</span> <span class="kr">string</span> <span class="p">}</span><span class="o">&gt;</span><span class="p">();</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">markers</span><span class="p">,</span> <span class="nx">setMarkers</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">isMarkerOpened</span><span class="p">,</span> <span class="nx">setIsMarkerOpened</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setMarkers</span><span class="p">(</span><span class="nx">getMarkers</span><span class="p">(</span><span class="nx">mapId</span><span class="p">));</span>\n <span class="p">},</span> <span class="p">[</span><span class="nx">mapId</span><span class="p">]);</span>\n\n\n <span class="kd">const</span> <span class="nx">openMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">closeMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;&gt;</span>\n <span class="p">&lt;</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">markers</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span>\n <span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nc">Marker</span>\n <span class="na">longitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span><span class="si">}</span>\n <span class="na">latitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="si">}</span>\n <span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerIcon</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">openMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">Marker</span><span class="p">&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerPopup</span> <span class="na">isOpened</span><span class="p">=</span><span class="si">{</span><span class="nx">isMarkerOpened</span><span class="si">}</span> <span class="na">onClose</span><span class="p">=</span><span class="si">{</span><span class="nx">closeMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/&gt;</span>\n <span class="p">)</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><code class="language-plaintext highlighter-rouge">MapPage</code> is in charge of loading map data depending on the <code class="language-plaintext highlighter-rouge">mapId</code> and rendering a map with its markers. I can’t test the <code class="language-plaintext highlighter-rouge">MapBoard</code> component because the <code class="language-plaintext highlighter-rouge">ReactMapGL</code> component can’t be rendered through the test tooling. That’s sad because I still want to check if I can open the marker popup when a user clicks on a marker.</p>\n\n<p>React will help us to fix this issue! We need to refactor this component to extract the business logic into a hook. This way, the component will only be responsible for rendering things. Let’s begin by creating the hooks.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="nx">mapId</span><span class="p">,</span> <span class="p">{</span><span class="nx">defaultIsMarkerOpened</span><span class="p">}</span> <span class="o">=</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">false</span><span class="p">})</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">markers</span><span class="p">,</span> <span class="nx">setMarkers</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">([]);</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">isMarkerOpened</span><span class="p">,</span> <span class="nx">setIsMarkerOpened</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="nx">defaultIsMarkerOpened</span><span class="p">);</span>\n\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setMarkers</span><span class="p">(</span><span class="nx">getMarkers</span><span class="p">(</span><span class="nx">mapId</span><span class="p">));</span>\n <span class="p">},</span> <span class="p">[</span><span class="nx">mapId</span><span class="p">]);</span>\n\n\n <span class="kd">const</span> <span class="nx">openMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">closeMarkerPopup</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">setIsMarkerOpened</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n\n\n <span class="k">return</span> <span class="p">{</span>\n <span class="nx">markers</span><span class="p">,</span>\n <span class="nx">isMarkerOpened</span><span class="p">,</span>\n <span class="nx">closeMarkerPopup</span><span class="p">,</span>\n <span class="nx">openMarkerPopup</span><span class="p">,</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n<p>The hook exposes two variables: <code class="language-plaintext highlighter-rouge">markers</code> which is an array of map’s markers and <code class="language-plaintext highlighter-rouge">isMarkerOpened</code> which is a boolean that indicates if the popup is opened or closed. It exposes two functions, <code class="language-plaintext highlighter-rouge">openMarkerPopup</code> and <code class="language-plaintext highlighter-rouge">closeMarkerPopup</code> that let us mutate the <code class="language-plaintext highlighter-rouge">isMarkerOpened</code> boolean.</p>\n\n<p><strong>Note:</strong> We could only expose <code class="language-plaintext highlighter-rouge">setIsMarkerOpened</code> but I think <code class="language-plaintext highlighter-rouge">openMarkerPopup</code> and <code class="language-plaintext highlighter-rouge">closeMarkerPopup</code> function names are clearer and match the component logic.</p>\n\n<p>Now, we need to call the hook from the <code class="language-plaintext highlighter-rouge">MapPage</code> component and it will still work as before.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">MapPage</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span>\n <span class="nx">markers</span><span class="p">,</span>\n <span class="nx">isMarkerOpened</span><span class="p">,</span>\n <span class="nx">closeMarkerPopup</span><span class="p">,</span>\n <span class="nx">openMarkerPopup</span>\n <span class="p">}</span> <span class="o">=</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="nx">mapId</span><span class="p">);</span>\n\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;&gt;</span>\n <span class="p">&lt;</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">markers</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span>\n <span class="p">(</span><span class="nx">marker</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nc">Marker</span>\n <span class="na">longitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">longitude</span><span class="si">}</span>\n <span class="na">latitude</span><span class="p">=</span><span class="si">{</span><span class="nx">marker</span><span class="p">.</span><span class="nx">latitude</span><span class="si">}</span>\n <span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerIcon</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="nx">openMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">Marker</span><span class="p">&gt;</span>\n <span class="p">)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ReactMapGL</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">MarkerPopup</span> <span class="na">isOpened</span><span class="p">=</span><span class="si">{</span><span class="nx">isMarkerOpened</span><span class="si">}</span> <span class="na">onClose</span><span class="p">=</span><span class="si">{</span><span class="nx">closeMarkerPopup</span><span class="si">}</span> <span class="p">/&gt;</span>\n <span class="p">&lt;/&gt;</span>\n <span class="p">)</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">MapPage</code> is still untestable but we can start testing the hook to ensure hook logic matches business expectations. We can test if we can open a marker’s popup. That’s great because the testing library provides the <code class="language-plaintext highlighter-rouge">renderHook</code> helper that eases the hook testing.</p>\n\n<p><strong>Note:</strong> If you want to know how <code class="language-plaintext highlighter-rouge">renderHook</code> works you should have a look at this <a href="https://kentcdodds.com/blog/how-to-test-custom-react-hooks">blog post</a> written by <a href="https://twitter.com/kentcdodds">Kent C. Dodds</a>.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">describe</span><span class="p">(</span><span class="dl">'</span><span class="s1">Map Page</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">should open the marker popup</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span> <span class="nx">result</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">renderHook</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">useMapPage</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">false</span><span class="p">}</span>\n <span class="p">));</span>\n \n <span class="nx">act</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">openMarkerPopup</span><span class="p">());</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">isMarkerOpened</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n <span class="p">});</span>\n\n\n <span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">should close the marker popup</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span> <span class="nx">result</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">renderHook</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">useMapPage</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">true</span><span class="p">}</span>\n <span class="p">));</span>\n \n <span class="nx">act</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">closeMarkerPopup</span><span class="p">());</span>\n\n <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">isMarkerOpened</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>\n <span class="p">});</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>As I said at the beginning of this blog post I wrote a blog post to explain how to reduce coupling in a React application. Please, have a look at this <a href="/how-to-reduce-coupling-in-your-react-app.html">blog post</a> to understand how to make a dependency injection system.</p>\n\n<p>Now, we need to remove the <code class="language-plaintext highlighter-rouge">getMarkers</code> function call from the hooks if we want to test the map data loading. We don’t want to trigger side effects like HTTP calls in the unit test suite because we want to have the shortest feedback loop. We will get the <code class="language-plaintext highlighter-rouge">getMarkers</code> function to <code class="language-plaintext highlighter-rouge">useServiceContainer</code> which is a hook that provides any services.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">function</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="nx">mapId</span><span class="p">,</span> <span class="p">{</span><span class="nx">defaultIsMarkerOpened</span><span class="p">}</span> <span class="o">=</span> <span class="p">{</span><span class="na">defaultIsMarkerOpened</span><span class="p">:</span> <span class="kc">false</span><span class="p">})</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span><span class="nx">getMarkers</span><span class="p">}</span> <span class="o">=</span> <span class="nx">useServiceContainer</span><span class="p">();</span>\n <span class="c1">// ...</span>\n \n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">setMarkers</span><span class="p">(</span><span class="nx">getMarkers</span><span class="p">(</span><span class="nx">mapId</span><span class="p">));</span>\n <span class="p">},</span> <span class="p">[</span><span class="nx">mapId</span><span class="p">]);</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>By default, the <code class="language-plaintext highlighter-rouge">useServiceContainer</code> hooks return the production services, we will need to replace the <code class="language-plaintext highlighter-rouge">getMarkers</code> service with a fake service for testing purposes. The <code class="language-plaintext highlighter-rouge">useServiceContainer</code> hooks can’t work without a React Provider. I like to create a factory that wraps components I test with all needed providers. It avoids a lot of noise in the test suites and makes tests more readable.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">const</span> <span class="nx">createWrapper</span> <span class="o">=</span> <span class="p">(</span><span class="nx">serviceContainer</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="kd">function</span> <span class="nx">Wrapper</span><span class="p">(</span>\n <span class="p">{</span> <span class="nx">children</span> <span class="p">}:</span> <span class="p">{</span> <span class="nl">children</span><span class="p">:</span> <span class="nx">ReactElement</span> <span class="p">},</span>\n<span class="p">)</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span> <span class="na">value</span><span class="p">=</span><span class="si">{</span><span class="nx">serviceContainer</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">children</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">};</span>\n</code></pre></div></div>\n\n<p>Note: the factory has a parameter which is the service container. It will let us define the services we want to override for testing.</p>\n\n<p>The <code class="language-plaintext highlighter-rouge">renderHook</code> has a <code class="language-plaintext highlighter-rouge">wrapper</code> option that lets you define the component that will wrap the hook you are testing. We will use the <code class="language-plaintext highlighter-rouge">createWrapper</code> factory to wrap the hook into the <code class="language-plaintext highlighter-rouge">ContainerContext</code> provider and we create a fake <code class="language-plaintext highlighter-rouge">getMarkers</code> service.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">describe</span><span class="p">(</span><span class="dl">'</span><span class="s1">Map Page</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">test</span><span class="p">(</span><span class="dl">'</span><span class="s1">should load the markers of the map</span><span class="dl">'</span><span class="p">,</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">markers</span> <span class="o">=</span> <span class="p">[{</span><span class="na">id</span><span class="p">:</span> <span class="dl">'</span><span class="s1">makerId</span><span class="dl">'</span><span class="p">}];</span>\n <span class="kd">const</span> <span class="p">{</span> <span class="nx">result</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">renderHook</span><span class="p">(</span>\n <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">useMapPage</span><span class="p">(</span><span class="dl">'</span><span class="s1">mapId</span><span class="dl">'</span><span class="p">),</span>\n <span class="p">{</span><span class="na">wrapper</span><span class="p">:</span> <span class="nx">createWrapper</span><span class="p">({</span><span class="na">getMarkers</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">markers</span><span class="p">})}</span>\n <span class="p">);</span>\n \n <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">current</span><span class="p">.</span><span class="nx">markers</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="nx">markers</span><span class="p">);</span>\n <span class="p">});</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>Now, the <code class="language-plaintext highlighter-rouge">getMarkers</code> is predictable. That means we can test the map loading because the <code class="language-plaintext highlighter-rouge">getMarker</code> function will return <code class="language-plaintext highlighter-rouge">[{id: 'makerId'}]</code> every time.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 04 Apr 2023 00:00:00 -0500\n https://arnolanglade.github.io/how-to-use-custom-react-hook-to-increase-application-testability.html?s=feed\n https://arnolanglade.github.io/how-to-use-custom-react-hook-to-increase-application-testability.html\n \n react\n \n testing\n \n \n \n \n \n How to reduce coupling in your React app\n <p>Today, I would like to cover dependency injection in React. I worked with several frameworks using tools to build and inject dependencies. It is pretty convenient if you apply the dependency inversion principle because you can easily change a dependency with another one.</p>\n\n<p>I will start by briefly introducing what is a React Context and I will then show you how to solve coupling problems in a React application.</p>\n\n<h2 id="what-is-a-react-context">What is a React Context?</h2>\n\n<blockquote>\n <p>Context provides a way to pass data through the component tree without having to pass props down manually at every level.</p>\n\n <p><a href="https://reactjs.org/docs/context.html">React documentation</a></p>\n</blockquote>\n\n<p>Let’s take an example: several components display the username of the user who is connected. We have to pass the username as props to every application component that needs this information. It is annoying, but React context can help for this specific use case.</p>\n\n<p>First, we need to create a context:</p>\n\n<p>```ts self-taught\nconst UserContext = React.createContext<string>();</string></p>\n<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>\nThen, we need to wrap our components using a context provider and give it a value. The value is the data we want to share with the provider’s children components.\n\n```tsx\nfunction App() {\n return (\n &lt;UserContext.Provider value={'arn0'}&gt;\n &lt;Toolbar /&gt;\n &lt;OtherComponent /&gt;\n &lt;/UserContext.Provider&gt;\n );\n}\n</code></pre></div></div>\n\n<p>Finally, we can get this value (the username) from the context thanks to the useContext hooks.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">Toolbar</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">username</span> <span class="o">=</span> <span class="nx">useContext</span><span class="p">(</span><span class="nx">UserContext</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">div</span><span class="p">&gt;</span>\n Welcome <span class="si">{</span><span class="nx">username</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n\n</code></pre></div></div>\n<h2 id="which-problems-coupling-brings">Which problems coupling brings?</h2>\n\n<blockquote>\n <p>Coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)">Wikipedia</a></p>\n</blockquote>\n\n<p>The developer’s worst enemy is <strong>coupling</strong> because it makes your code less testable. To illustrate what I am saying we will take an example: a to-do list application. The <code class="language-plaintext highlighter-rouge">TodoList</code> component is responsible for retrieving data from the server and building the list of tasks to do.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">findTasks</span> <span class="o">=</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/tasks</span><span class="dl">'</span><span class="p">);</span>\n<span class="p">}</span>\n\n<span class="kd">function</span> <span class="nx">TodoList</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">setTasks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="o">&lt;</span><span class="nx">Task</span><span class="p">[]</span><span class="o">&gt;</span><span class="p">([]);</span>\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="p">(</span><span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">findTasks</span><span class="p">();</span>\n <span class="nx">setTasks</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>\n <span class="p">})();</span>\n <span class="p">},</span> <span class="p">[]);</span>\n \n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">task</span><span class="p">:</span> <span class="nx">Task</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nt">li</span> <span class="na">key</span><span class="p">=</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The problem with the <code class="language-plaintext highlighter-rouge">TodoList</code> component is that it depends on the <code class="language-plaintext highlighter-rouge">axios</code> library to get data from the server. It does not ease testing because we need to set up the server to make this component work. Unit testing requires a short feedback loop! We need to find a way to get rid of this HTTP call. It would be great to be able to do HTTP calls in production but using stub for testing.</p>\n\n<h2 id="how-react-context-reduces-coupling">How React Context reduces coupling?</h2>\n\n<p>The problem with the <code class="language-plaintext highlighter-rouge">TodoList</code> component is that we should be able to use several implementations of the <code class="language-plaintext highlighter-rouge">findTasks</code>, but we can’t with its design. We need an implementation for the production that will make an HTTP call and another one for testing that will return stub.</p>\n\n<p>The <code class="language-plaintext highlighter-rouge">findTasks</code> function should not be hardcoded but it should be injected as a component dependency. A React Context will help us to solve that issue.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">ServiceContainer</span> <span class="o">=</span> <span class="p">{</span><span class="na">findTasks</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nb">Promise</span><span class="o">&lt;</span><span class="nx">Task</span><span class="o">&gt;</span><span class="p">};</span>\n\n<span class="kd">const</span> <span class="nx">ContainerContext</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createContext</span><span class="o">&lt;</span><span class="nx">ServiceContainer</span><span class="o">&gt;</span><span class="p">({}</span> <span class="k">as</span> <span class="nx">ServiceContainer</span><span class="p">);</span>\n\n<span class="k">export</span> <span class="kd">const</span> <span class="nx">useServiceContainer</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">useContext</span><span class="p">(</span><span class="nx">ContainerContext</span><span class="p">);</span>\n\n<span class="kd">const</span> <span class="nx">findTasks</span> <span class="o">=</span> <span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">await</span> <span class="nx">axios</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">/tasks</span><span class="dl">'</span><span class="p">);</span>\n<span class="p">}</span>\n\n<span class="kd">function</span> <span class="nx">App</span><span class="p">()</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span> <span class="na">value</span><span class="p">=</span><span class="si">{</span><span class="nx">findTasks</span><span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">TodoList</span><span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">ServiceContainer</code> type represents all services we want to register in our application. The <code class="language-plaintext highlighter-rouge">ContainerContext</code> will share those services with <code class="language-plaintext highlighter-rouge">ContainerContext.Provider</code> children.</p>\n\n<p>Then, we only need to get the <code class="language-plaintext highlighter-rouge">findTasks</code> function from the React Context.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">TodoList</span><span class="p">()</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="p">{</span><span class="nx">findTasks</span><span class="p">}</span> <span class="o">=</span> <span class="nx">useServiceContainer</span><span class="p">();</span>\n <span class="kd">const</span> <span class="p">[</span><span class="nx">tasks</span><span class="p">,</span> <span class="nx">setTasks</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="o">&lt;</span><span class="nx">Task</span><span class="p">[]</span><span class="o">&gt;</span><span class="p">([]);</span>\n\n <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="p">(</span><span class="k">async</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">findTasks</span><span class="p">();</span>\n <span class="nx">setTasks</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>\n <span class="p">})();</span>\n <span class="p">},</span> <span class="p">[]);</span>\n\n <span class="k">return</span> <span class="p">(</span>\n <span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="si">{</span><span class="nx">tasks</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">task</span><span class="p">:</span> <span class="nx">Task</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">&lt;</span><span class="nt">li</span> <span class="na">key</span><span class="p">=</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">id</span><span class="si">}</span><span class="p">&gt;</span><span class="si">{</span><span class="nx">task</span><span class="p">.</span><span class="nx">label</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;)</span><span class="si">}</span>\n <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>\n <span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, the code is testable because we can easily replace the <code class="language-plaintext highlighter-rouge">findTasks</code> by stub in the test suite. We can easily set up a test because this new function does not use HTTP calls.</p>\n\n<div class="language-tsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">it</span><span class="p">(</span><span class="dl">'</span><span class="s1">render the todo list</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="nx">render</span><span class="p">(</span>\n <span class="p">&lt;</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span> <span class="na">value</span><span class="p">=</span><span class="si">{</span>\n <span class="p">{</span> <span class="na">findTasks</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">({</span><span class="na">id</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="na">label</span><span class="p">:</span> <span class="dl">'</span><span class="s1">label</span><span class="dl">'</span><span class="p">})</span> <span class="p">}</span>\n <span class="si">}</span><span class="p">&gt;</span>\n <span class="p">&lt;</span><span class="nc">TodoList</span><span class="p">/&gt;</span>\n <span class="p">&lt;/</span><span class="nc">ContainerContext</span><span class="p">.</span><span class="nc">Provider</span><span class="p">&gt;</span>\n <span class="p">)</span>\n\n <span class="c1">// …</span>\n<span class="p">});</span>\n</code></pre></div></div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 06 Mar 2023 00:00:00 -0600\n https://arnolanglade.github.io/how-to-reduce-coupling-in-your-react-app.html?s=feed\n https://arnolanglade.github.io/how-to-reduce-coupling-in-your-react-app.html\n \n react\n \n design-patterns\n \n \n \n \n \n What is the difference between CQS and CQRS patterns?\n <p>I recently found out that I did not grasp those design patterns. There are a lot of resources on the Internet about them but they are not always accurate. That’s a shame because they are pretty simple. I will share my understanding of them with you.</p>\n\n<h2 id="what-is-command-query-segregation-cqs">What is Command Query Segregation (CQS)?</h2>\n\n<blockquote>\n <p>The fundamental idea is that we should divide an object’s methods into two sharply separated categories:</p>\n <ul>\n <li>Queries: Return a result and do not change the observable state of the system (are free of side effects).</li>\n <li>Commands: Change the state of a system but do not return a value.</li>\n </ul>\n\n <p><a href="https://martinfowler.com/bliki/CommandQuerySeparation.html">Martin Fowler</a></p>\n</blockquote>\n\n<p>This concept is not specific to Object Oriented Programming but improves the object’s design. The object methods only have a single purpose: reading or changing the object state. We can see an object as a living entity. We can ask a question to someone because we need information. For example, we can ask someone what time it is. This is a query. We can ask someone to do something, we don’t expect an answer but we want to get the job done. For example, we can ask a child to finish his/her spinach. This is a command.</p>\n\n<p>We can apply this pattern to any object: like an aggregate. Let’s take an example! I would like to add markers on a map and then I would like to find which markers are the closest to a specific location (GPS Coordinates).\nk</p>\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nb">Map</span> <span class="p">{</span>\n <span class="nx">addMarker</span><span class="p">(</span><span class="nx">label</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">latitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">):</span> <span class="k">void</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n\n <span class="nx">findClosestMarkers</span><span class="p">(</span><span class="nx">location</span><span class="p">:</span> <span class="nx">Location</span><span class="p">):</span> <span class="nx">Marker</span><span class="p">[]</span> <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">addMarker</code> method is in charge of mutating the object state without returning any result, while the ‘findClosestMarkers’ method finds the right markers without changing the object’s state. This object follows the CQS definition.</p>\n\n<p>Let’s go further. If we design our aggregates following the CQS pattern, we should apply it to the classes that handle use cases.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">MapService</span> <span class="p">{</span>\n <span class="nx">addMarkerToTheMap</span><span class="p">(</span><span class="nx">label</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">latitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">);</span> <span class="k">void</span>\n <span class="nx">findAllMarkersCloseToLocation</span><span class="p">():</span> <span class="nx">Marker</span><span class="p">[]</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>This ensures there is no inconsistency in the codebase. The business services use and manipulate the aggregates. For example, if the <code class="language-plaintext highlighter-rouge">MapService.addMarkerToTheMap</code> method returns a result, it might mean that the <code class="language-plaintext highlighter-rouge">Map.addMarker</code> method will need to return the expected result.</p>\n\n<h2 id="what-is-command-query-responsibility-segregation-cqrs">What is Command Query Responsibility Segregation (CQRS)?</h2>\n\n<blockquote>\n <p>Starting with CQRS, CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).</p>\n\n <p><a href="https://web.archive.org/web/20190211113420/http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-sourcing-agh/">Greg Young</a></p>\n</blockquote>\n\n<p><strong>Note:</strong> Greg Young’s blog does not exist anymore but his blog posts are still available thanks to archived.org.</p>\n\n<p>CQRS is the separation of command and query into two different objects instead of only one. MapService does not follow the CQRS pattern because it has a query and a command. We need to cut this object in half.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">interface</span> <span class="nx">MapReadService</span> <span class="p">{</span>\n <span class="nx">addMarkerToTheMap</span><span class="p">(</span><span class="nx">label</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">latitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">longitude</span><span class="p">:</span> <span class="kr">number</span><span class="p">);</span> <span class="k">void</span>\n<span class="p">}</span>\n\n<span class="kr">interface</span> <span class="nx">MapWriteService</span> <span class="p">{</span>\n <span class="nx">findAllMarkersCloseToLocation</span><span class="p">():</span> <span class="nx">Marker</span><span class="p">[]</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>That’s pretty simple, right? Anyway, we don’t need to introduce complicated things in our application to use this tactical design pattern. We don’t need a write and a read model,\na command and query bus, an event sourcing architecture or multiple databases. Greg Young published this blog post in 2012 to explain what CQRS was not about.</p>\n\n<blockquote>\n <p>CQRS is not a silver bullet</p>\n\n <p>CQRS is not a top level architecture</p>\n\n <p>CQRS is not new</p>\n\n <p>CQRS is not shiny</p>\n\n <p>CQRS will not make your jump shot any better</p>\n\n <p>CQRS is not intrinsically linked to DDD</p>\n\n <p>CQRS is not Event Sourcing</p>\n\n <p>CQRS does not require a message bus</p>\n\n <p>CQRS is not a guiding principle / CQS is</p>\n\n <p>CQRS is not a good wife</p>\n\n <p>CQRS is learnable in 5 minutes</p>\n\n <p>CQRS is a small tactical pattern</p>\n\n <p>CQRS can open many doors.</p>\n</blockquote>\n\n<p><strong>Note:</strong> This blog does not exist anymore but it has been archived by archived.org. The post is available <a href="https://web.archive.org/web/20160729165044/https://goodenoughsoftware.net/2012/03/02/cqrs/">here</a></p>\n\n<p>Depending on the number of use cases the service classes can become really huge. CQRS helps to decrease their size but I am a big fan of them. I like to separate each use case into a dedicated class.</p>\n\n<p>I’ve written a blog post to explain what is a commands and we can apply it to query too:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-handler-patterns.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-handler/command-handler.webp" alt="Command and command handler design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Command and command handler design pattern</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 06 Feb 2023 00:00:00 -0600\n https://arnolanglade.github.io/what-is-the-difference-between-cqs-and-cqrs-patterns.html?s=feed\n https://arnolanglade.github.io/what-is-the-difference-between-cqs-and-cqrs-patterns.html\n \n software-architecture\n \n design-patterns\n \n \n \n \n \n Hexagonal architecture by example\n <p>In this blog post, I would like to explain the basics of hexagonal architecture thanks to a simple example: a product catalogue. The catalogue manager can add new products through a user interface and the nightly cron task imports new products from the ERP.</p>\n\n<p>Before going deeper into hexagonal architecture, let’s see what we need to create the product management application. We need two entry points: the first one will be consumed by the graphical client and the other one will be used by the cron task. Then, we will need another piece of code which will be in charge of persisting product data into storage.</p>\n\n<p><img src="images/posts/hexagonal-architecture/application-architecture.svg" alt="Application architecture" /></p>\n\n<h2 id="what-is-hexagonal-architecture">What is hexagonal architecture?</h2>\n\n<blockquote>\n <p>The hexagonal architecture, or ports and adapters architecture, is an architectural pattern used in software design. It aims at creating loosely coupled application components that can be easily connected to their software environment by means of ports and adapters. This makes components exchangeable at any level and facilitates test automation.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Hexagonal_architecture_(software)">Wikipedia</a></p>\n</blockquote>\n\n<p>There are three main areas in the hexagonal architecture:\nThe <strong>primary adapters (user interface)</strong> are the whole application entry points that can be consumed by clients like a UI or a CLI.\nThe <strong>secondary adapters (infrastructure)</strong> connect the application to tools like the database, file system, etc.\nThe <strong>domain</strong> is all pieces of code that represent the problem we are solving. This part must be side-effect free (it must not use any tools).</p>\n\n<h2 id="domain">Domain</h2>\n\n<p>The domain is the area where we solve our business problems no matter the technical constraints. We can start by designing the product aggregate.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">type</span> <span class="nx">Name</span> <span class="o">=</span> <span class="kr">string</span><span class="p">;</span>\n<span class="kd">type</span> <span class="nx">Description</span> <span class="o">=</span> <span class="kr">string</span><span class="p">;</span>\n\n<span class="k">export</span> <span class="kd">class</span> <span class="nx">Product</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">name</span><span class="p">:</span> <span class="nx">Name</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">description</span><span class="p">:</span> <span class="nx">Description</span>\n <span class="p">)</span> <span class="p">{}</span>\n\n <span class="nx">toState</span><span class="p">():</span> <span class="kr">string</span><span class="p">[]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">name</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">description</span><span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>As I said, we need to save products into the database but we don’t mind if the database is PostgreSQL, MySQL or whatever in the domain. We will define an <strong>abstraction (an interface)</strong> to avoid accessing any technical asset from the domain. This interface which is called a <strong>port</strong> will specify how to store a new product from a business point of view. This is nothing more than applying the dependency inversion design pattern.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kr">interface</span> <span class="nx">ProductCatalog</span> <span class="p">{</span>\n <span class="nx">add</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">):</span> <span class="k">void</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h3 id="what-about-testing">What about testing?</h3>\n\n<p>Moving IO as far as possible from your domain code is really convenient because it eases unit testing. We will mainly test this part of the application with unit testing. It offers a very short feedback loop, it will help you to design your domain step by step without setting up the whole application.</p>\n\n<p><strong>Tip:</strong> I’ve written a blog post about unit testing that explains why testing can be hard. It mainly gives you tips to move IO outside your code to make it testable.</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="why-unit-testing-can-be-hard.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/why-unit-testing-can-be-hard.webp" alt="Why unit testing can be hard?" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Why unit testing can be hard?</span>\n </span>\n </a>\n</div>\n\n<h3 id="coupling-rules">Coupling rules</h3>\n\n<p>The domain code must not use any IO: any tools like your database, randomness, or actual datetime, nor depend on the primary and the secondary adapters. We will explain what they are in the next sections.</p>\n\n<h2 id="secondary-adapters-infrastructure">Secondary adapters (Infrastructure)</h2>\n\n<p>The secondary or driven adapters implement the ports defined in the domain. In our example, the adapter will be a <code class="language-plaintext highlighter-rouge">PostgresProductCatalog</code> class that implements the <code class="language-plaintext highlighter-rouge">ProductCatalog</code> interface (port). Its purpose will be to store product data in a database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">PostgresProductCatalog</span> <span class="k">implements</span> <span class="nx">ProductCatalog</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span><span class="k">private</span> <span class="nx">pg</span><span class="p">:</span> <span class="nx">Client</span><span class="p">)</span> <span class="p">{}</span>\n\n <span class="nx">add</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">pg</span><span class="p">.</span><span class="nx">query</span><span class="p">(</span>\n <span class="dl">'</span><span class="s1">INSERT INTO product (name, properties) VALUES ($1, $2)</span><span class="dl">'</span><span class="p">,</span>\n <span class="nx">product</span><span class="p">.</span><span class="nx">toState</span><span class="p">()</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>An advantage of this architecture is that we can simply delay choices. At the beginning of a project, it may be hard to choose the right tools because you still need to learn and understand the business. In that case, you can implement an in-memory adapter, it will work the same way as the previous one but it will only keep product aggregate in memory.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nx">InMemoryProductCatalog</span> <span class="k">implements</span> <span class="nx">ProductCatalog</span> <span class="p">{</span>\n <span class="k">private</span> <span class="nx">products</span><span class="p">:</span> <span class="nx">Product</span><span class="p">[];</span>\n\n <span class="nx">add</span><span class="p">(</span><span class="nx">product</span><span class="p">:</span> <span class="nx">Product</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">products</span> <span class="o">=</span> <span class="p">[</span><span class="nx">product</span><span class="p">,</span> <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">products</span><span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> This adapter can be used in your test suites because it lets you bypass your tools constraints like foreign key constraints when we use a database, for instance.</p>\n\n<h3 id="what-about-testing-1">What about testing?</h3>\n\n<p>The part of the application is mainly covered by “integration” or “contract” tests. Those tests ensure that the tools used by the application work as expected. For example, you are able to save and query your database.</p>\n\n<p><strong>Tip:</strong> I encourage you to test all implementations of a given port with the same test because it will ensure they work the same way.</p>\n\n<h3 id="coupling-rules-1">Coupling rules</h3>\n\n<p>The infrastructure code only depends on the domain code.</p>\n\n<h2 id="primary-adapters-user-interface">Primary adapters (User interface)</h2>\n\n<p>The primary adapters or driving adapters are entry points that describe how the application is consumed by the clients. Their purpose is to tell the domain what to do. Actually, it can be a Web controller or CLI command for instance.</p>\n\n<p>In our example, we need two adapters: a web controller and a CLI command. Both of them will execute the same action, they will save product data but they have different input and output. The first one takes JSON and returns an HTTP response and the second one takes input and returns code status.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">try</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">productCatalog</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="k">new</span> <span class="nx">Product</span><span class="p">(</span>\n <span class="nx">request</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">name</span><span class="dl">'</span><span class="p">),</span> <span class="c1">// get name argument for cli command</span>\n <span class="nx">request</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="dl">'</span><span class="s1">description</span><span class="dl">'</span><span class="p">),</span> <span class="c1">// get description argument for cli command</span>\n <span class="p">))</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">HttpResponse</span><span class="p">(</span><span class="mi">201</span><span class="p">);</span> <span class="c1">// return 0 for cli command</span>\n<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nb">Error</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nx">HttpResponse</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span> <span class="c1">// return 1 for cli command</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>As you see, the only differences are the input and output of the adapter. We need to refactor this code to avoid duplication between both primary adapters. It should be extracted into a dedicated business service.</p>\n\n<p><strong>Tip:</strong> These business services can be written using the command and command handler patterns. I’ve written a blog post that explains these design patterns:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-handler-patterns.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-handler/command-handler.webp" alt="Command and command handler design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Command and command handler design pattern</span>\n </span>\n </a>\n</div>\n\n<p>I’ve written a bunch of articles about how to handle a command, validate its data, handle user permissions, and so on. Take a look at these articles:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/tag/command-bus">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/data-validation.webp" alt="See all blog posts about command handling." />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">See all blog posts about command handling.</span>\n </span>\n </a>\n</div>\n\n<h3 id="what-about-testing-2">What about testing?</h3>\n\n<p>There are several ways to test primary adapters.</p>\n\n<p>First option: the easiest one, your application only has one primary adapter. I advise you to write an acceptance test that boots the application and checks that the whole application works for each business use case.</p>\n\n<p>Second option: the complex one, your application has several primary adapters like our example (web and CLI). I advise you to check that your command handler works as expected thanks to an acceptance. That way you ensure your handler will work as expected for both adapters. Thus, you can write a test to ensure that the adapters return the right output (HTTP response or code status) depending on the case.</p>\n\n<h3 id="coupling-rules-2">Coupling rules</h3>\n\n<p>The user interface code only depends on the domain code.</p>\n\n<h2 id="flow-of-control">Flow of control</h2>\n\n<p><img src="images/posts/hexagonal-architecture/hexgonal-architecture-flow-control.svg" alt="Hexgonal architecture: flow control" /></p>\n\n<p>The application flow goes from the user interface <strong>(1)</strong> through the domain <strong>(2)</strong> to the infrastructure <strong>(3)</strong> then goes back through the domain <strong>(2)</strong> to the user interface <strong>(4)</strong>.</p>\n\n<p>Example: The UI sends data to an HTTP controller <strong>(1)</strong>, then a product aggregate is created <strong>(2)</strong>, then the repository saves data into the database <strong>(3)</strong>, and finally the web controller sends a 200 HTTP response <strong>(4)</strong>. We don’t need step <strong>(2)</strong> because nothing happens in the domain after the product creation.</p>\n\n<h2 id="code-organization">Code organization</h2>\n\n<p>The <strong>domain</strong> contains the aggregates, ports, business services and so on. Most importantly, they must not use IO and must be business oriented.</p>\n\n<p>The <strong>infrastructure</strong> contains all secondary adapters that use external tools (IO) like your database.</p>\n\n<p>The <strong>user interface</strong> contains all primary adapters that are the application entry points. Users and machines use them to interact with the application.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>src\n├── domain\n│ ├── ProductCatalog.ts\n│ └── Product.ts\n├── infra\n│ ├── InMemoryProductCatalog.ts\n│ └── PostgresProductCatalog.ts\n└── user-interface\n ├── CliCreateProduct.ts\n └── WebCreateProduct.ts\n</code></pre></div></div>\n\n<p><strong>Note:</strong> I decided to split each class/interface into a dedicated module because I wanted to show you where things are. Feel free to organize your module as you wish.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 09 Jan 2023 00:00:00 -0600\n https://arnolanglade.github.io/hexagonal-architect-by-example.html?s=feed\n https://arnolanglade.github.io/hexagonal-architect-by-example.html\n \n software-architecture\n \n \n \n \n \n What is the event sourcing pattern?\n <p>Event sourcing consists in storing all changes that happened to an application as a sequence of events instead of only storing the current state of the application. The sum of all events is the current application state. When I heard about this pattern a few years ago, I was really confused. I used to only persist the current application state in a database and that was fine! So I asked myself do I need that?</p>\n\n<p>I will show you an example to help you understand what this pattern stands for. People used to explain it with a bank account but I wanted to find something funnier: a table soccer game. A complete example is available on a Github repository:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="https://github.com/arnolanglade/table-soccer">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/github-logo.png" alt="Have a look at the GitHub repository" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Have a look at the GitHub repository</span>\n </span>\n </a>\n</div>\n\n<p>Let’s start! A group of developers who are fans of table soccer wants to create an application to see who’s the best player. They decided to save the results of matches and rank themselves.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">redTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">blueTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">gameScore</span><span class="p">:</span> <span class="nx">Score</span><span class="p">,</span>\n <span class="p">)</span> <span class="p">{}</span>\n\n <span class="k">public</span> <span class="nx">recordScore</span><span class="p">(</span><span class="nx">redPlayerScore</span><span class="p">:</span> <span class="kr">number</span><span class="p">,</span> <span class="nx">bluePlayerScore</span><span class="p">:</span> <span class="kr">number</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">,</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">,</span>\n <span class="k">new</span> <span class="nx">Score</span><span class="p">(</span><span class="nx">redPlayerScore</span><span class="p">,</span> <span class="nx">bluePlayerScore</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n\n <span class="c1">// example: ['arn0', 'momos', 'Popeye', 'coco', 10, 1]</span>\n <span class="k">public</span> <span class="nx">toState</span><span class="p">():</span> <span class="p">[</span><span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">,</span> <span class="kr">number</span><span class="p">,</span> <span class="kr">number</span><span class="p">]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="p">[</span>\n <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">.</span><span class="nx">toState</span><span class="p">(),</span>\n <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">.</span><span class="nx">toState</span><span class="p">(),</span>\n <span class="p">...</span><span class="k">this</span><span class="p">.</span><span class="nx">gameScore</span><span class="p">.</span><span class="nx">toState</span><span class="p">()</span>\n <span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">Game</code> Aggregate has a <code class="language-plaintext highlighter-rouge">recordScore</code> method to record the score at the end of the game. Then we get the current state of <code class="language-plaintext highlighter-rouge">Game</code> with the <code class="language-plaintext highlighter-rouge">toState</code> method to save it in the database.</p>\n\n<p>That works perfectly for the one versus one games but what happens for two versus two games? Let’s focus on one of the players, we will call him Popeye. Actually, Popeye is not a really good player even if he is full of goodwill. He is smart, he always wants to play with the best player to have more chances to win. We cannot know who is the best player with only the result of the game. Who has really scored? Popeye or its teammate?</p>\n\n<p>Event sourcing is the solution. Instead of saving the score of the game, we will store what really happens. We will refactor the <code class="language-plaintext highlighter-rouge">Game</code> aggregate to make it compliant with the event sourcing pattern.</p>\n\n<p>First, we will rework the aggregate construction. We still want to encapsulate its current state but we want to record all events that happened too. In the following example, we added an <code class="language-plaintext highlighter-rouge">events</code> argument to the primary constructor and a named constructor (secondary construct) called <code class="language-plaintext highlighter-rouge">start</code> to the <code class="language-plaintext highlighter-rouge">Game</code> class. From a business point of view, its goal is to initialize the game and from a technical point of view, it lets us record the <code class="language-plaintext highlighter-rouge">GameStarted</code> event.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">constructor</span><span class="p">(</span>\n <span class="k">private</span> <span class="nx">redTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">blueTeam</span><span class="p">:</span> <span class="nx">Team</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">gameScore</span><span class="p">:</span> <span class="nx">Score</span><span class="p">,</span>\n <span class="k">private</span> <span class="nx">events</span><span class="p">:</span> <span class="nx">Event</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[]</span>\n <span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">public</span> <span class="k">static</span> <span class="nx">start</span><span class="p">(</span>\n <span class="nx">redAttacker</span><span class="p">:</span> <span class="nx">Player</span><span class="p">,</span>\n <span class="nx">redDefender</span><span class="p">:</span> <span class="nx">Player</span><span class="p">,</span>\n <span class="nx">blueAttacker</span><span class="p">:</span> <span class="nx">Player</span><span class="p">,</span>\n <span class="nx">blueDefender</span><span class="p">:</span> <span class="nx">Player</span>\n <span class="p">):</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">redTeam</span> <span class="o">=</span> <span class="nx">Team</span><span class="p">.</span><span class="nx">ofTwoPlayer</span><span class="p">(</span><span class="nx">redAttacker</span><span class="p">,</span> <span class="nx">redDefender</span><span class="p">);</span>\n <span class="kd">const</span> <span class="nx">blueTeam</span> <span class="o">=</span> <span class="nx">Team</span><span class="p">.</span><span class="nx">ofTwoPlayer</span><span class="p">(</span><span class="nx">blueAttacker</span><span class="p">,</span> <span class="nx">blueDefender</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span>\n <span class="nx">redTeam</span><span class="p">,</span>\n <span class="nx">blueTeam</span><span class="p">,</span>\n <span class="nx">Score</span><span class="p">.</span><span class="nx">playersHaveNotScored</span><span class="p">(),</span>\n <span class="p">[</span><span class="k">new</span> <span class="nx">GameStarted</span><span class="p">(</span><span class="nx">redTeam</span><span class="p">,</span> <span class="nx">blueTeam</span><span class="p">)],</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then we will add a new method to <code class="language-plaintext highlighter-rouge">Game</code> to record all goals scored by any players. That will let us know who is the best striker in the game. In the following example, we record two events: <code class="language-plaintext highlighter-rouge">GoalScored</code> and <code class="language-plaintext highlighter-rouge">GameEnded</code>. The first one is recorded every time a player scores and the second one is recorded when the first team has 10 points meaning the game is over.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span> \n <span class="c1">// …</span>\n <span class="k">public</span> <span class="nx">goalScoredBy</span><span class="p">(</span><span class="nx">player</span><span class="p">:</span> <span class="nx">Player</span><span class="p">):</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">const</span> <span class="nx">teamColor</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">.</span><span class="nx">isTeammate</span><span class="p">(</span><span class="nx">player</span><span class="p">)</span> <span class="p">?</span> <span class="nx">TeamColor</span><span class="p">.</span><span class="nx">Red</span> <span class="p">:</span> <span class="nx">TeamColor</span><span class="p">.</span><span class="nx">Blue</span><span class="p">;</span>\n <span class="kd">const</span> <span class="nx">gameScore</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">gameScore</span><span class="p">.</span><span class="nx">increase</span><span class="p">(</span><span class="nx">teamColor</span><span class="p">);</span>\n\n <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">GoalScored</span><span class="p">(</span><span class="nx">teamColor</span><span class="p">,</span> <span class="nx">player</span><span class="p">,</span> <span class="nx">gameScore</span><span class="p">))</span>\n\n <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">gameScore</span><span class="p">.</span><span class="nx">canIncrease</span><span class="p">(</span><span class="nx">teamColor</span><span class="p">))</span> <span class="p">{</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="k">new</span> <span class="nx">GameEnded</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">,</span> <span class="nx">gameScore</span><span class="p">))</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">,</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">,</span>\n <span class="nx">gameScore</span><span class="p">,</span>\n <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">,</span>\n <span class="p">);</span>\n <span class="p">}</span>\n <span class="c1">// …</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Note:</strong> We can drop the <code class="language-plaintext highlighter-rouge">recordScore</code> method because we won’t want to only record the score of the game at the end of the game.</p>\n\n<p>Finally, the last thing to refactor is the persistence mechanism. We need to rework the <code class="language-plaintext highlighter-rouge">toState</code> because we won’t store a snapshot of the <code class="language-plaintext highlighter-rouge">Game</code> state but we want to save all events raised during the game. This method will return all serialized events and metadata like the name of the aggregate. Normally, we should persist some extra metadata like the aggregate id or the date when the event has been raised. Then, those data will be used in the <code class="language-plaintext highlighter-rouge">Game</code> repository to persist changes in the database.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span> \n <span class="c1">// …</span>\n <span class="k">public</span> <span class="nx">toState</span><span class="p">():</span> <span class="p">[[</span><span class="kr">string</span><span class="p">,</span> <span class="kr">string</span><span class="p">]]</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">events</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">event</span><span class="p">:</span> <span class="nx">Event</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="dl">'</span><span class="s1">Game</span><span class="dl">'</span><span class="p">,</span> <span class="nx">event</span><span class="p">.</span><span class="nx">toState</span><span class="p">()]);</span>\n <span class="p">}</span>\n <span class="c1">// …</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Last thing, we will add a named constructor to be able to build the object from the persisted state (a list of events). The <code class="language-plaintext highlighter-rouge">fromEvents</code> will iterate on all events to compute and set the current state of a game.</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="kd">class</span> <span class="nx">Game</span> <span class="p">{</span> \n <span class="c1">// …</span>\n <span class="k">public</span> <span class="k">static</span> <span class="nx">fromEvents</span><span class="p">(</span><span class="nx">events</span><span class="p">:</span> <span class="nx">Event</span><span class="p">[]):</span> <span class="nx">Game</span> <span class="p">{</span>\n <span class="kd">let</span> <span class="nx">redTeam</span><span class="p">,</span> <span class="nx">blueTeam</span><span class="p">,</span> <span class="nx">score</span><span class="p">;</span>\n <span class="nx">events</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">event</span><span class="p">:</span> <span class="nx">Event</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>\n <span class="k">switch</span> <span class="p">(</span><span class="kc">true</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">case</span> <span class="nx">event</span> <span class="k">instanceof</span> <span class="na">GameStarted</span><span class="p">:</span>\n <span class="nx">redTeam</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">redTeam</span><span class="p">;</span>\n <span class="nx">blueTeam</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">blueTeam</span><span class="p">;</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="k">case</span> <span class="nx">event</span> <span class="k">instanceof</span> <span class="na">GameEnded</span><span class="p">:</span>\n <span class="nx">score</span> <span class="o">=</span> <span class="nx">event</span><span class="p">.</span><span class="nx">score</span><span class="p">;</span>\n <span class="k">break</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="p">});</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nx">Game</span><span class="p">(</span><span class="nx">redTeam</span><span class="p">,</span> <span class="nx">blueTeam</span><span class="p">,</span> <span class="nx">score</span><span class="p">,</span> <span class="nx">events</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="c1">// …</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, we have all the data we need to know if Popeye really helps his teammate. In the following code example, we can see that Momos and arn0 were not in a good shape. Coco and Popeye won easily but we can see that Popeye did not score. Perhaps, he is a good defender, who knows?</p>\n\n<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">game</span> <span class="o">=</span> <span class="nx">Game</span><span class="p">.</span><span class="nx">startTwoVersusTwo</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">Popeye</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">momos</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">arn0</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n<span class="nx">game</span> <span class="o">=</span> <span class="nx">game</span><span class="p">.</span><span class="nx">goalScoredBy</span><span class="p">(</span><span class="dl">'</span><span class="s1">coco</span><span class="dl">'</span><span class="p">)</span>\n</code></pre></div></div>\n\n<p>I explained to you how to save <code class="language-plaintext highlighter-rouge">Game</code> aggregate events and create the aggregate from events in the previous sections of the blog post. The last missing feature is the leaderboard! How to create it? It won’t be as simple as querying a SQL table in the database because we need to get all game events for each game and compute them to know who is the better striker. Even though it can be fast in the beginning, the more games you have, the longer it will be.</p>\n\n<p>To prevent this problem, we need to create data projections. That means we will compute a representation of the data we want to query from the event stream. We will compute the new projection of the leaderboard each time a game ends.</p>\n\n<p>Last but not least, We often associate CQRS with the event sourcing pattern even if there are two different patterns.</p>\n\n<p>Don’t forget that a complete example is available on a Github repository.</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="https://github.com/arnolanglade/table-soccer">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/github-logo.webp" alt="Have a look at the GitHub repository" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Have a look at the GitHub repository</span>\n </span>\n </a>\n</div>\n\n<p>Any resemblance to real and actual names is purely coincidental!</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 28 Nov 2022 00:00:00 -0600\n https://arnolanglade.github.io/what-is-the-event-sourcing-pattern.html?s=feed\n https://arnolanglade.github.io/what-is-the-event-sourcing-pattern.html\n \n software-architecture\n \n \n \n \n \n My feedback about example mapping\n <p>Example mapping is a workshop that gathers tech and non-tech people to ensure everyone has the same understanding of the domain problem. It also helps clarify the acceptance criteria for a given story. Because it’s always better to understand what is expected and raise all bottlenecks before developing a story.</p>\n\n<p>Disclaimer! I won’t explain how to run such a workshop, you can easily find a bunch of articles on the web. You can also have a look at <a href="/agile-tour-rennes-example-mapping.html">these slides</a>, they come from one of my talks about example mapping if you’re not familiar with it. In this blog article, I want to share with you my experience on Example Mapping and how it helps me to prepare and organize the team’s work.</p>\n\n<p><strong>Caution:</strong> A little while ago, I got feedback from <a href="https://twitter.com/brunoboucard">Bruno Boucard</a> about using sticky notes. He advised me to use index cards instead of sticky notes. The workshop attendees can put them on a table and easily move them, unlike stick notes. I speak about sticky notes in this blog post because I only practiced this workshop remotely using tools like <a href="https://www.miro.com">Miro</a>.</p>\n\n<h2 id="who-will-attend-the-workshop">Who will attend the workshop?</h2>\n\n<p>The methodology recommends to involve at least the product managers, developers and testers. The goal of example mapping is that the product manager shares the problem with the person(s) who will solve it. I will go further, you can invite anyone who wants to understand what you are doing. It is a good way to share knowledge.</p>\n\n<p>During my last year at Akeneo, I worked on a new product called Shared Catalogs. All my teammates including devs, product manager, and engineering managers were newcomers. Even if they were really well onboarded on Akeneo’s products, they had a micro vision of what Akeneo PIM did, and the software’s functional perimeter was pretty huge. At this time, I was working at Akeneo for 4 years, andI had a good understanding of the product. During the example mapping sessions I shared as much knowledge as possible with my teammates, it helped the team to quickly improve their functional skills.</p>\n\n<h2 id="when-do-we-plan-it">When do we plan it?</h2>\n\n<p>From my experience, a 30-minute slot is a good tradeoff. It’s not too long and you can easily illustrate the main business rules of the story and detect all bottlenecks. With a 30-minute meeting, you’re sure that your teammates will stay focused, especially when you work remotely. Having regular and short workshops is better than doing a big and long one.</p>\n\n<p>Depending on their roles, some team members can be really busy. For instance, I worked with several PMs who were often in meetings and it was really hard to catch them. To be sure that everyone can be available, each team member booked a 30 minutes slot after the daily meeting. Doing an example mapping was not mandatory, we only did the workshop if we needed to prepare stories.</p>\n\n<h2 id="how-organize-the-team">How organize the team</h2>\n\n<p>The attendees can have different roles: onek person writes sticky notes, another animates the workshop and the others ask questions and drive the person who writes sticky notes. I think it is important to switch his/her role each session to keep everyone involved during the workshop.</p>\n\n<p>I worked with some product managers and domain experts who wanted to contribute and write sticky notes. It is not a good idea because they should focus on sharing the knowledge and let the rest of the team grasp the business expectations. You won’t help someone if you do his/her job.</p>\n\n<h2 id="how-to-start">How to start</h2>\n\n<p>Writing the title of a story on a yellow sticky note is pretty simple but I sometimes had difficulties getting the business rules and the examples listed. Especially, when you are doing this workshop with a team for the first time. I found out that it was easier to sometimes start by writing the example first or sometimes by writing the business rules first.</p>\n\n<p>First option: start by writing the business rules and then write the examples if your team is comfortable with the exercise and your product manager has a clear vision of what is expected.</p>\n\n<p>Second option: start by writing examples and then extract business rules from examples if your team is not comfortable with the workshop or if your product manager needs to explore a topic and he/she waits for your feedback. It will let you and your teammates speak, and understand what is going on. When you have enough examples and your understanding of business is better you can extract the business rules.</p>\n\n<p>Don’t be afraid if it is a bit complicated to be efficient in the beginning. One day, my teammates and I prepared a story about exporting a CSV file, quite simple, right? We only needed to “take data from the DB and build a file” but it wasn’t that simple! We turned this “simple” story into at least 15 stories. We discovered a lot of “hidden” business rules. We thought it was a story but it was an epic…</p>\n\n<h2 id="how-to-write-example">How to write example</h2>\n\n<p>Don’t try to write gherkins scenarios at all costs because it can be time-consuming. The goal of this workshop is to ensure all teammates grasp what the business expects and it is the right time to raise all problems and incomprehension.</p>\n\n<p>The simplest format I used to define the example looked like the Given / When / Then but a really simplified version.</p>\n\n<p><img src="images/posts/example-mapping/write-simple-exmaple.webp" alt="Simplified gherkins" /></p>\n\n<p>Sometimes it can be more readable to draw something.</p>\n\n<p><img src="images/posts/example-mapping/draw-example.webp" alt="Draw examples" /></p>\n\n<p>Don’t limit yourself, if you prefer another format, use it. The most important thing is that everyone understands what is expected.</p>\n\n<h2 id="dont-forget-red-sticky-notes">Don’t forget red sticky notes</h2>\n\n<p>Avoid endless debates! Don’t hesitate to use red sticky notes if your teammates disagree on something. Keep in mind that your product manager can’t answer all questions during the workshops. It’s normal, the product manager is not a super(wo)man! Thus, add a red sticky note and take time to think about it, he/she’ll answer all questions in the next session.</p>\n\n<h2 id="have-small-stories">Have small stories</h2>\n\n<p>I like to talk with the PM when the story is ready to be developed (when there are no more red stickies and when all teammates are OK with it). I usually challenge him/her to know which business rules are really mandatory and which ones are nice-to-have. It ensures your stories are really small and it eases the prioritization. You can focus on what is really important and keep what is nice-to-have for later.</p>\n\n<p><strong>Tip:</strong> If your story has too many business rules, it’s a smell! That means you should split it into small ones. It will be easier to ship several small stories than a big one. If a business rule has too many examples, that’s a smell too. You might have missed some business rules.</p>\n\n<p><img src="images/posts/example-mapping/split-story.webp" alt="Split story into small ones" /></p>\n\n<p>I am not a big fan of estimates, it’s a waste of time. We should focus on understanding the problem we want to solve, instead of giving figures that will probably be wrong. Having a really small story will help you to be more predictive. You can count the stories done during a time frame and easily forecast what your team will be able to do during the next iteration.</p>\n\n<h2 id="final-thoughts">Final thoughts</h2>\n\n<p>The first example mapping workshop can be complex but don’t give up. The more you practice, the more comfortable your team will be with the workshop. Example mapping is a good way to align the team’s understanding with the stakeholders expectations. It will help your team to better collaborate and break all silos between all kinds of positions in your team. Last but not least, it will help you refine your stories and improve your backlog prioritization.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 31 Oct 2022 00:00:00 -0500\n https://arnolanglade.github.io/my-feedback-about-example-mapping.html?s=feed\n https://arnolanglade.github.io/my-feedback-about-example-mapping.html\n \n BDD\n \n methodology\n \n \n \n \n \n How I have learned programming by myself\n <p>I am, what we call, a self-taught. I studied telecommunications and networks at school, unfortunately, I only learned the basics of programming. I had to learn and improve my skills by myself for many years during my free time. I did not take the easiest path to learn! That’s why I wanted to share with you my own experience and what I did to learn software development. I hope this post will help some of you.</p>\n\n<h2 id="find-a-mentor">Find a mentor</h2>\n\n<p>In the beginning, even though I knew some basics of programming I was a bit lost. I wasn’t able to build an application end to end and I did not know which subject I had to study to solve that. That’s why I advise junior engineers to find at least one mentor. A mentor can teach you what is important like how to test, design patterns, software architecture, and so on. A mentor will help you focus on the right topics like how to build robust applications instead of focusing on hype technologies.</p>\n\n<p><strong>Tip:</strong> If you’re a junior, I would recommend you focus on testing: TDD will help you to design your code step by step. Architectural patterns like hexagonal architecture will help you to decouple your code from IO. Agile: eXtreme programming will help you to reduce the cost of changes by having multiple short development cycles rather than a long one.</p>\n\n<h2 id="play-and-have-fun-with-a-side-project">Play and have fun with a side project</h2>\n\n<p>You can have strong constraints at work, so it can be really hard to try new things because of bad processes, bad code quality, impossible deadlines etc. I have worked on several side projects for the last 10 years. I tried twice to release an application for a French NGO to manage their volunteer data. Then I tried to make an application to organize my trips. The last one is about making maps to remember places I have been. I learned a lot from those projects, they let me try what I read in blog posts, books or what I saw in conferences without any pressure of production. The funny thing is that I learned more from failures. Only my last side project <a href="https://mymaps.world">“mymaps”</a> is live, I did not release the other ones! This is because they were only playgrounds rather than real projects. They helped me understand why being pragmatic is important, focusing only on technical aspects does not help to build an application. Keep in mind that a good codebase is not the only thing you need to make a successful project.</p>\n\n<h2 id="contribute-to-an-open-source-project">Contribute to an open-source project</h2>\n\n<p>I worked on <a href="https://sylius.com">Sylius</a> which is an open-source e-commerce framework. The community of Sylius is great. I learned a lot of good practices like testing, code review and behaviour-driven development for instance. I mainly worked on the <code class="language-plaintext highlighter-rouge">SyliusResourceBundle</code> which is a library that eases CRUD management. During this period, I was working for a web agency, it helped me to be more efficient at work and ship projects faster.</p>\n\n<p><strong>Caution:</strong> Many companies use open-source projects but they don’t contribute to them. I was happy to contribute to this project during my free time, but you should negotiate allocated time with your company to help those projects if they help you deliver value to your customers.</p>\n\n<p>I would like to thank <a href="https://pjedrzejewski.com">Pawel</a> for making me a core team member. Contributing to Sylius has opened many doors to me.</p>\n\n<p>Thanks to what I have done in that library, I had the chance to do my first conference (<a href="https://live.symfony.com/2015-paris">Symfony live</a>) as a speaker. That was so great! I was so excited and terrified at the same time. Then I got hired by a french startup <a href="https://www.akeneo.com/">Akeneo</a> to work on an open-source PIM (Product Information Management). I only worked for service companies before Akeneo, this experience made me discover what was software edition.</p>\n\n<h2 id="attend-conferences-and-meetups">Attend conferences and meetups</h2>\n\n<p>Attending conferences is a great way to learn and open your mind to new things. You can have a chat with other attendees during breaks as well. It is a good way to meet new people and to have interesting talks. One of my favourite conferences is <a href="http://www.ncrafts.io">newcraft</a>, its local edition at <a href="https://bordeaux.ncrafts.io/">Bordeaux</a> was really great too.</p>\n\n<p>When you will be comfortable the next step will be to do a presentation. Preparing a talk is good to dive into the topic you will present and formalize your ideas. Even if you know this topic, it may not be that easy to clearly explain it to someone else. Don’t be shy, submit your talks! A lot of conference organizations help new speakers. I did not think too much when I submitted my first talk. I thought it wouldn’t be selected but I received an email that said my talk was accepted. I was so happy and excited! I realized what happened and I really started to panic (true story, a little panic attack) so I started to work on my talk to be ready for D-day. You can have a look at <a href="http://arnolanglade.github.io/talks.html">my talks</a>.</p>\n\n<h2 id="read-books">Read books</h2>\n\n<p>Another way to learn is through books. This is a good way to shut down your computer while still learning new things about software engineering.</p>\n\n<p><strong>Tip:</strong> Some books in my library: <a href="https://www.oreilly.com/library/view/accelerate/9781457191435/">Accelerate</a>, <a href="https://www.oreilly.com/library/view/extreme-programming-explained/0201616416/">Extreme Programming Explained</a>, <a href="https://www.oreilly.com/library/view/domain-driven-design-distilled/9780134434964/">Domain-Driven Design Distilled</a>, <a href="https://www.oreilly.com/library/view/patterns-principles-and/9781118714706/">Patterns, Principles, and Practices of Domain-Driven Design</a>, <a href="https://www.yegor256.com/elegant-objects.html">Elegant Objects</a> and so on.</p>\n\n<h2 id="final-thoughts">Final thoughts</h2>\n\n<p>A few weeks ago, I saw some software engineers saying on social media that we should self-train in our free time. Learning in your free time will help you progress faster but it can be time and energy consuming. Don’t forget that burnouts are real. One of my friends experienced burnout and couldn’t do anything for almost a year, he was completely out of energy.</p>\n\n<p>I also had to take several breaks in my learning process to avoid going to the dark side of the force. <strong>Only do things when you want in your free time! Don’t put pressure on yourself!</strong> And keep in mind that learning should be fun!</p>\n\n<p>Learning is a part of your job. Companies should let you learn during business hours. On a day-to-day basis, pair and mob programming is a good way to learn and challenge your ideas. Your company should train you as well. For instance, <a href="https://matthiasnoback.nl">Mathias Noback</a> gave us some training when I was at Akeneo. I learned a lot from him, and I definitely recommend him!</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 17 Oct 2022 00:00:00 -0500\n https://arnolanglade.github.io/how-I-have-learned-programming-by-myself.html?s=feed\n https://arnolanglade.github.io/how-I-have-learned-programming-by-myself.html\n \n learning\n \n \n \n \n \n Increase your test quality thanks to builders or factories\n <p>In a previous <a href="http://arnolanglade.github.io/you-should-not-expose-objects-state-to-test-them.html">blog post</a>, I explained why it’s better to compare object instances instead of exposing their state to test them. This avoids breaking encapsulation and it does not have any impact on their design.</p>\n\n<p>Let’s take an example! My side project allows me to create maps to remember places I have been. A map has a name and, as a cartographer, I am allowed to rename it. Real basic use case but more than enough! The following test ensures I can rename this map:</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="s1">'Pepito'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="s1">'Bordeaux city'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="s1">'Good places in Anglet'</span><span class="p">),</span>\n <span class="nc">Tag</span><span class="o">::</span><span class="nf">city</span><span class="p">(),</span>\n <span class="nc">MarkerList</span><span class="o">::</span><span class="nb">empty</span><span class="p">(),</span>\n<span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">);</span>\n\n<span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span>\n <span class="nv">$map</span><span class="p">,</span>\n <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="s1">'Pepito'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="s1">'Good places in Anglet'</span><span class="p">),</span>\n <span class="nc">Tag</span><span class="o">::</span><span class="nf">city</span><span class="p">(),</span>\n <span class="nc">MarkerList</span><span class="o">::</span><span class="nb">empty</span><span class="p">(),</span>\n <span class="p">)</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p>We can see that comparing object instances is great for encapsulation because we don’t expose the object’s state but this makes the test less readable. Here, the only thing we want to focus on is the value of <code class="language-plaintext highlighter-rouge">MapName</code>. The values of the other value object are only noise because they are not useful for this test. But, this is not the only drawback of this test. What happens if you want to add an extra property to the <code class="language-plaintext highlighter-rouge">Map</code> object? In this case, we will need to refactor all the tests that create a map object. It might be easily doable in small projects but it can become messy for big ones.</p>\n\n<p>Now, let’s show how we can improve this test. The title of my blogpost can give you a huge hint on the solution. We will add a named constructor called <code class="language-plaintext highlighter-rouge">whatever</code> to the <code class="language-plaintext highlighter-rouge">Map</code> object to centralize the object construction. Named constructors are static factories that build the object itself.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">Map</span> \n<span class="p">{</span>\n <span class="cd">/** @internal */</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">whatever</span><span class="p">(</span>\n <span class="kt">string</span> <span class="nv">$mapId</span> <span class="o">=</span> <span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$addedBy</span> <span class="o">=</span> <span class="s1">'Pepito'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$name</span> <span class="o">=</span> <span class="s1">'Anglet city'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$description</span> <span class="o">=</span> <span class="s1">'Good places in Anglet'</span><span class="p">,</span>\n <span class="kt">string</span> <span class="nv">$tag</span> <span class="o">=</span> <span class="s1">'city'</span><span class="p">,</span>\n <span class="kt">array</span> <span class="nv">$markers</span> <span class="o">=</span> <span class="p">[],</span>\n <span class="p">):</span> <span class="kt">self</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="nv">$mapId</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$addedBy</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$name</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="nv">$description</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Tag</span><span class="p">(</span><span class="nv">$tag</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MarkerList</span><span class="p">(</span><span class="nv">$markers</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> I like to add a <code class="language-plaintext highlighter-rouge">@internal</code> annotation to remind all teammates that the object constructor should only be used in tests.</p>\n\n<p>The value object instantiation is delegated to the <code class="language-plaintext highlighter-rouge">whatever</code> constructor. I try to use primitive data types like arguments as much as possible, it makes me write less code and it’s easier to read. All constructor arguments have a default value, then I can override a given value depending on the needs thanks to the named argument feature.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">whatever</span><span class="p">(</span><span class="n">name</span><span class="o">:</span> <span class="s1">'Bordeaux city'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">);</span>\n\n<span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span>\n <span class="nv">$map</span><span class="p">,</span>\n <span class="nc">Map</span><span class="o">::</span><span class="nf">whatever</span><span class="p">(</span><span class="n">name</span><span class="o">:</span> <span class="s1">'Anglet city'</span><span class="p">)</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p>Now, the test is clear and focuses on the right thing. Everyone can easily understand it, and it will help your teammates to grasp the code you wrote. Refactoring will be simplified as you only have to rewrite the <code class="language-plaintext highlighter-rouge">whatever</code> constructor if the signature of the primary constructor of <code class="language-plaintext highlighter-rouge">Map</code> changes.</p>\n\n<p>I know that some people won’t like the idea of adding a method to objects only for testing purposes. If you don’t like that, you can replace this static factory with a builder.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MapBuilder</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$mapId</span> <span class="o">=</span> <span class="s1">'e9a01a8a-9d40-476e-a946-06b159cd484a'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$addedBy</span> <span class="o">=</span> <span class="s1">'Pepito'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$name</span> <span class="o">=</span> <span class="s1">'Anglet city'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$description</span> <span class="o">=</span> <span class="s1">'Good places in Anglet'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$tag</span> <span class="o">=</span> <span class="s1">'city'</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">array</span> <span class="nv">$markers</span> <span class="o">=</span> <span class="p">[];</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">identifiedBy</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span> <span class="o">=</span> <span class="nv">$mapId</span><span class="p">;</span>\n \n <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">named</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$name</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>\n\n <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="c1">// ... other setters ....</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">build</span><span class="p">():</span> <span class="kt">Map</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">addedBy</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Description</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">description</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">Tag</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">tag</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">MarkerList</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markers</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then your test will look like this:</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="p">(</span><span class="k">new</span> <span class="nc">MapBuilder</span><span class="p">())</span><span class="o">-&gt;</span><span class="nf">named</span><span class="p">(</span><span class="s1">'Bordeaux city'</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">();</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">);</span>\n\n<span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span>\n <span class="nv">$map</span><span class="p">,</span>\n <span class="p">(</span><span class="k">new</span> <span class="nc">MapBuilder</span><span class="p">())</span><span class="o">-&gt;</span><span class="nf">named</span><span class="p">(</span><span class="s1">'Anglet city'</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">build</span><span class="p">()</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> Read or anemic models don’t have logic to ensure they are built in a good way. If you use this method for them you can add some logic to your builder/factories to ensure they are created with consistent data. It will make your tests stronger.</p>\n\n<h2 id="final-thought">Final thought</h2>\n\n<p>Builders or factories ease test refactoring and make tests more readable. Don’t forget that bad test suites are a nightmare to maintain and can drastically slow down your delivery. Taking care of your test quality will help you to ship fast. Moreover, good tests are free documentation.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 10 Oct 2022 00:00:00 -0500\n https://arnolanglade.github.io/increase-your-test-quality-thanks-to-builders-or-factories.html?s=feed\n https://arnolanglade.github.io/increase-your-test-quality-thanks-to-builders-or-factories.html\n \n testing\n \n \n \n \n \n How to handle user permissions through command bus middleware\n <p>Applying user permissions might be very complex and can lead to introducing a lot of accidental complexity to your application. In this blog post, I want to share with you how to do it by simply adding a middleware to your command bus.</p>\n\n<p><strong>Note:</strong> If you’re not familiar with this pattern, please have a look at this <a href="http://arnolanglade.github.io/command-bus-design-pattern.html">blog post</a>, it explains what a command bus and a middleware are.</p>\n\n<p>Let’s imagine a basic use case: an application with two kinds of users: regular ones and admins. We want to allow certain actions only to admin users.</p>\n\n<p>First, I will introduce an interface <code class="language-plaintext highlighter-rouge">OnlyPerformedByAdministrator</code> that will be implemented by the command restricted to the admin users.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">interface</span> <span class="nc">OnlyPerformedByAdministrator</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">username</span><span class="p">():</span> <span class="kt">string</span><span class="p">;</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">CreateNewProduct</span> <span class="kd">implements</span> <span class="nc">OnlyPerformedByAdministrator</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">username</span><span class="p">():</span> <span class="kt">string</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then, we will add a <code class="language-plaintext highlighter-rouge">CheckAccessPermission</code> middleware to the command bus that will check if the user can execute an action. If he/she can’t, an <code class="language-plaintext highlighter-rouge">AccessDenied</code> exception will be thrown. It will be caught later in the execution flow to be turned into something that will be understandable to the user.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">AccessDenied</span> <span class="k">extends</span> <span class="err">\\</span><span class="nc">Exception</span>\n<span class="p">{</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">CheckAccessPermission</span> <span class="kd">implements</span> <span class="nc">Middleware</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">private</span> <span class="nc">Users</span> <span class="nv">$users</span><span class="p">)</span> <span class="p">{}</span>\n\n <span class="k">final</span> <span class="k">public</span> <span class="k">function</span> <span class="n">handle</span><span class="p">(</span><span class="kt">Command</span> <span class="nv">$command</span><span class="p">,</span> <span class="kt">Middleware</span> <span class="nv">$next</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$user</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">users</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">username</span><span class="p">()));</span>\n <span class="k">if</span> <span class="p">(</span><span class="nv">$command</span> <span class="k">instanceof</span> <span class="nc">OnlyPerformedByAdministrator</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="nf">isAdmin</span><span class="p">())</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">AccessDenied</span><span class="p">();</span>\n <span class="p">}</span>\n\n <span class="nv">$next</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nv">$command</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>This middleware will stop the command processing if an error is raised. We need to catch this exception to return a 403 HTTP response in the web controller, or to return a status code greater than 0 in the CLI command.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">WebToggleCartographerPremiumStatus</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">private</span> <span class="nc">CommandBus</span> <span class="nv">$commandBus</span><span class="p">)</span> <span class="p">{}</span>\n \n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">Request</span> <span class="nv">$request</span><span class="p">):</span> <span class="kt">Response</span>\n <span class="p">{</span>\n <span class="k">try</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">commandBus</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="k">new</span> <span class="nc">CreateNewProduct</span><span class="p">(</span><span class="cd">/** ... */</span><span class="p">));</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">AccessDenied</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">Response</span><span class="p">(</span><span class="mi">403</span><span class="p">,</span> <span class="s1">'Access denied'</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">Response</span><span class="p">(</span><span class="mi">200</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h2 id="why-do-i-handle-permissions-with-a-middleware">Why do I handle permissions with a middleware?</h2>\n\n<p>I decided to add a middleware to the command bus because it ensures that permissions are checked no matter where commands are dispatched. For example: from the web controller or a CLI command. Moreover, I don’t depend on a security library or any framework configuration. All permission business rules are coded in the domain.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 26 Sep 2022 00:00:00 -0500\n https://arnolanglade.github.io/how-to-handle-user-permissions-through-command-bus-middleware.html?s=feed\n https://arnolanglade.github.io/how-to-handle-user-permissions-through-command-bus-middleware.html\n \n command-bus\n \n \n \n \n \n The command bus design pattern\n <p><strong>Note:</strong> Before reading this blog post, if you don’t know what a command and a command handler are, I advise you to first read the blog post I’ve written about those design patterns. It will help you to understand this new article:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-handler-patterns.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-handler/command-handler.webp" alt="Command and command handler design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">Command and command handler design pattern</span>\n </span>\n </a>\n</div>\n\n<h2 id="what-is-a-bus">What is a bus?</h2>\n\n<p>Let’s start with the basics, what is a bus? In computer science, a bus is a system that connects several components and transfers data between them. In software, those components are called middleware. A middleware processes an incoming request and returns a response. As you can see in the schema below, the main advantage of a bus is that it is highly customizable as you can add as many middleware as you want.</p>\n\n<p><img src="images/posts/command-bus/bus.svg" alt="A bus" /></p>\n\n<p>In the next sections, we will speak about the command bus which is often associated with an event bus. Using an event bus is not mandatory but we will see how it will make your application more modular and evolutive. Their goal is to deliver a command or an event to their handler(s). Events and commands are objects used to encapsulate information needed to achieve an action (a command) or to tell what happened in the system (an event).</p>\n\n<h2 id="the-command-bus">The command bus</h2>\n\n<p><strong>Quick reminder about command and command handler:</strong> A command represents a user’s intent. The data carried by the command has to be valid. It can be only handled by only one handler that is just a callable that will perform the user action.</p>\n\n<p>Now, we will build a command bus following the same architecture that I described in the previous section. The only difference is that the command bus will return void. As commands canmight be handled asynchronously, we don’t want to wait for the result of the command processing.</p>\n\n<p><img src="images/posts/command-bus/command-bus.svg" alt="A command bus" /></p>\n\n<p>Let’s see the most common middleware used to build a command bus. The first one is probably the “logging middleware”. It helps to make your application observable and it is really useful for bug hunting. Then the “validation middleware” ensures that the command is valid before giving it to the handler. Its purpose is to stop the command processing if data is invalid. It is pretty convenient because it avoids validating them manually. When your application uses a database, the “transaction middleware” wraps the handler execution into a SQL transaction. It makes sure all database changes are done, otherwise it rollbacks the transaction. Finally, the last middleware is responsible for finding and executing the handler that matches the command.</p>\n\n<h2 id="the-event-bus">The event bus</h2>\n\n<p>An event represents something that happened in the application. Unlike a command, an event can be handled by several handlers. Listening to events allows us to enhance existing features or add new ones very quickly. Several teams can listen to the same event to perform additional tasks depending on business needs. It makes applications more evolutive without adding accidental complexity and lets your team work isolated from each other.</p>\n\n<p><strong>Tip:</strong> I would like to encourage you to mainly use business-oriented events instead of technical ones. They clearly describe what happened from a business point of view. For example, <code class="language-plaintext highlighter-rouge">NewAccountHasBeenCreated</code> is more understandable than <code class="language-plaintext highlighter-rouge">ResourceCreated</code> with a resource property equal to ‘Account’</p>\n\n<p>Even if the event bus is built the same way as the command bus we don’t need all the different middleware. We don’t need the validation middleware because events are generated by the aggregates with value objects. Those objects ensure domain invariant which means they are always valid. We also don’t need the transactional middleware because the event will be processed into the transaction begun during the command processing. Moreover, depending on your business needs you may not want to process events into this transaction. Let’s take a simple example. After creating an account, an event <code class="language-plaintext highlighter-rouge">AccountCreated</code> is dispatched, then a welcome email is sent during <code class="language-plaintext highlighter-rouge">AccountCreated</code> processing. If the email sending fails, do we want to roll back the account creation? Not sure! In that case, you need to speak with your product manager to decide how to process this event.</p>\n\n<p>As I said previously, events are recorded by aggregates and they should be business oriented. I will share with you two ways to dispatch events into the event bus.</p>\n\n<p><img src="images/posts/command-bus/event-bus.svg" alt="A event bus" /></p>\n\n<p><strong>Solution 1:</strong> You can collect them from your repository if no errors have been raised during the aggregate persisting and then dispatch them.</p>\n\n<p><strong>Solution 2:</strong> The other solution is to collect events from the command handler. The handler can return them, and then the “handle command” middleware catches and dispatches them.</p>\n\n<p><strong>Note:</strong> My previous <a href="http://arnolanglade.github.io/command-handler-patterns.html">blog post</a> about the command and command handler pattern said that a command handler should return void. Here, the idea is that the command bus should return void only the “handle command” should be aware of the result of the handler execution.</p>\n\n<p>I’ve written a bunch of articles about how to handle a command, validate its data, handle user permissions, and so on. Take a look at these articles:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/tag/command-bus">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/data-validation.webp" alt="See all blog posts about command handling." />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">See all blog posts about command handling.</span>\n </span>\n </a>\n</div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Mon, 12 Sep 2022 00:00:00 -0500\n https://arnolanglade.github.io/command-bus-design-pattern.html?s=feed\n https://arnolanglade.github.io/command-bus-design-pattern.html\n \n command-bus\n \n design-patterns\n \n \n \n \n \n Objective: set up your projects more easily\n <p>For the last decade I worked on several more or less complex projects. I often had problems with their installation. Sometimes, the project was not documented or the existing documentation was not up to date. I had to run commands but I did not understand all of them. When I got errors it was hard to understand what happened. That was not always simple.</p>\n\n<p>During my last projects, I used makefile to provide an abstraction to simplify their installation and hide complexity. It let me install projects with a single command and provided a minimal set of targets which made my daily work easier.</p>\n\n<h2 id="how-does-makefile-work">How does makefile work?</h2>\n\n<p>A makefile is a set of “rules” that looks like:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>target: prerequisites prerequisites\n recipe\n recipe\n ...\n</code></pre></div></div>\n\n<p>A <strong>target</strong> is the name of a file (or a folder) that is generated by <code class="language-plaintext highlighter-rouge">make</code>. It could also be the name of an action to perform but you need to declare it as PHONY.</p>\n\n<p>A <strong>prerequisite</strong> are the files (or folders) needed to create the target, you can see them as target dependencies.</p>\n\n<p>A <strong>recipe</strong> are all actions executed when the target is run. <strong>Caution:</strong> you need to indent all recipes using a “real” tab character otherwise you will get errors.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.env:\n <span class="nb">cp</span> .env.dist .env\n</code></pre></div></div>\n\n<p>If the <code class="language-plaintext highlighter-rouge">.env</code> file does not exist, the recipe will be carried out, but if it does exist the recipe won’t be executed #magic.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: cache\ncache: .env\n bin/console c:c\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">cache</code> target does not target a file. Declaring this target as PHONY allows having a file named <code class="language-plaintext highlighter-rouge">cache</code> in the same directory as the Makefile.</p>\n\n<p><strong>Note:</strong> If the <code class="language-plaintext highlighter-rouge">.env</code> file does not exist the <code class="language-plaintext highlighter-rouge">.env</code> target will be performed before the <code class="language-plaintext highlighter-rouge">cache</code> target.</p>\n\n<h2 id="lets-take-an-example">Let’s take an example</h2>\n\n<p>For instance, a project orchestrated by docker-compose having:</p>\n<ul>\n <li>a front application written in JS using React framework,</li>\n <li>a back application written in PHP using Symfony framework,</li>\n <li>a PostgreSQL database managed by Doctrine DBAL and Doctrine migration</li>\n</ul>\n\n<p><strong>Caution:</strong> I will only speak about projects setup for dev purposes. I won’t talk about making docker images ready for production.</p>\n\n<p>Let’s start installing the project dependencies. The following targets install project dependencies if they have not been downloaded yet. They can guess if they are outdated to upgrade them thanks to target prerequisites. Another interesting thing is that nothing will be done if dependencies are already installed and up to date.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Front</span>\nweb/yarn.lock: web/package.json\n docker-compose run <span class="nt">--rm</span> node yarn <span class="nb">install\n\n</span>web/node_modules: web/yarn.lock\n docker-compose run <span class="nt">--rm</span> node yarn <span class="nb">install</span> <span class="nt">--frozen-lockfile</span>\n docker-compose run <span class="nt">--rm</span> node yarn check <span class="nt">--integrity</span>\n\n<span class="c"># back</span>\napi/composer.lock: api/composer.json\n docker-compose run <span class="nt">--rm</span> fpm composer update\n\napi/vendor: api/composer.lock\n docker-compose run <span class="nt">--rm</span> fpm composer <span class="nb">install</span>\n\n</code></pre></div></div>\n\n<p>Then, we need to “up” all docker-compose services: the web server, the PHP process manager, the datatable, and the node to run the front application in development mode.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: up\nup:\n docker-compose up <span class="nt">-d</span>\n</code></pre></div></div>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker-compose ps \n Name Command State Ports \n<span class="nt">---------------------------------------------------------------------------------------------------------------------------------------------</span> \nmy-maps-node docker-entrypoint.sh yarn ... Up \nmy-maps-web nginx <span class="nt">-g</span> daemon off<span class="p">;</span> Up 80/tcp \nmy-maps_database_1 docker-entrypoint.sh postgres Up 5432/tcp \nmy-maps_fpm_1 php-fpm <span class="nt">-F</span> Up \n</code></pre></div></div>\n\n<p>The last thing to do is to create the database schema using Doctrine migration.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: db-migration\ndb-migration: api/vendor\n docker-compose run <span class="nt">--rm</span> fpm bin/console doctrine:migrations:migrate <span class="nt">--no-interaction</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> To ease my daily work, I like introducing other targets like <code class="language-plaintext highlighter-rouge">db</code> target that resets database quickly or <code class="language-plaintext highlighter-rouge">fixture</code> to load some data fixtures.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.PHONY: db\ndb: api/vendor\n docker-compose run <span class="nt">--rm</span> fpm bin/console doctrine:database:drop <span class="nt">--force</span> <span class="nt">--no-interaction</span>\n docker-compose run <span class="nt">--rm</span> fpm bin/console doctrine:database:create <span class="nt">--no-interaction</span>\n\n.PHONY: fixtures\nfixtures: api/vendor\n docker-compose run <span class="nt">--rm</span> fpm bin/console project:fixtures:load\n</code></pre></div></div>\n\n<p>Now, we have all atomic targets to set up all parts of the application. Another interesting thing with make, is that it can run several targets within a single command <code class="language-plaintext highlighter-rouge">make up api/vendor web/node_modules</code>.This is pretty useful to create scenarios. For instance, to set up and run the project I only need to run the following command:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>make up api/vendor web/node_modules db db-migration fixtures\n</code></pre></div></div>\n\n<p>But it works with everything:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>make db db-migration fixtures\nmake api/vendor web/node_modules\n</code></pre></div></div>\n\n<p>To make your day-to-day basis, you can introduce targets that run those scenarios.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># It builds and runs the application</span>\n.PHONY: app-dev\napp-dev: up api/vendor web/node_modules db db-migration fixtures\n\n<span class="c"># It resets the database</span>\n.PHONY: db-reset\ndb-reset: db db-migration fixtures\n\n<span class="c"># It resets the database</span>\n.PHONY: dependencies\ndependencies: api/vendor web/node_modules\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> I advise you to introduce the minimum set of targets into the makefile. Keep it simple! Don’t forget that everyone uses it! To let developers have their custom targets you may want to include custom makefiles using <a href="https://www.gnu.org/software/make/manual/html_node/Include.html">include</a>. Don’t forget to add an entry into <code class="language-plaintext highlighter-rouge">.ignore</code> to avoid committing those files. Now, developers can create their own makefile with their personal targets.</p>\n\n<h2 id="one-last-word">One last word</h2>\n\n<p>Makefile is only a solution, this is not THE solution. The important thing to keep in mind is that you should be able to easily run your project to reduce the developer’s mental load and let them focus on the right thing. It will improve the day-to-day basis and make newcomers’ onboarding easier.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Wed, 02 Jun 2021 00:00:00 -0500\n https://arnolanglade.github.io/objective-set-up-your-projects-more-easily.html?s=feed\n https://arnolanglade.github.io/objective-set-up-your-projects-more-easily.html\n \n makefile\n \n \n \n \n \n Why unit testing can be hard?\n <blockquote>\n <p>Unit tests are typically automated tests written and run by software developers to ensure that a section of an application (known as the “unit”) meets its design and behaves as intended</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Unit_testing">Wikipedia</a></p>\n</blockquote>\n\n<p>I remember when I started to test my code it was really hard! It was mainly because I misunderstood some basics like what testing was about and the need of well-designed code. Unit tests ensure your code works as expected, but we often forget that unit testing is also the simplest way to have quick feedback during development phase.</p>\n\n<p>In this blog post, I will share what I learned to easily unit test my codebases.</p>\n\n<h2 id="test-your-public-methods">Test your public methods</h2>\n\n<p>Objects should be seen as black boxes. Public methods are the only way to interact with objects, while private and protected methods are implementation details. We should not pay attention to how objects work internally. That’s why we don’t test private and protected methods. If you need to test them, that’s a design smell! Your objects might do too many things and they probably do not respect the <strong>S</strong>ingle <strong>R</strong>esponsibility <strong>P</strong>rinciple.</p>\n\n<blockquote>\n <p>The single-responsibility principle (SRP) is a computer-programming principle that states that every class in a computer program should have responsibility over a single part of that program’s functionality, which it should encapsulate.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Single-responsibility_principle">Wikipedia</a></p>\n</blockquote>\n\n<p>Actually, it is better to have several small objects solving simple problems instead of having god objects that are doing everything the wrong way. If your objects become too big, split them into smaller ones because they are easier to maintain and to test.</p>\n\n<h2 id="do-not-unit-test-code-that-uses-ios">Do not unit test code that uses IOs</h2>\n\n<blockquote>\n <p>Input/output (I/O, or informally io or IO) is the communication between an information processing system, such as a computer, and the outside world, possibly a human or another information processing system.</p>\n\n <p><a href="https://press.rebus.community/programmingfundamentals/chapter/input-and-output/">Wikipedia</a></p>\n</blockquote>\n\n<p>For example, IO are side effects like: network calls, database queries, filesystem operations, actual timestamps or randomness.</p>\n\n<h3 id="do-not-deal-with-the-outside">Do not deal with the outside</h3>\n\n<p>The code covered by unit tests should not depend on the outside world like databases, external services and so on. Unit tests should not require any application setup, they have to remain as simple as possible. Their goal is to give you quick feedback by checking that a small piece of code (a unit) matches a business expectation. If you want to be sure that all application parts are well integrated with the outside world, you have to use an integration test.</p>\n\n<p>The following example shows a piece of code that depends on the external service. Here, we can’t build the <code class="language-plaintext highlighter-rouge">Map</code> object without a working database.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HandleMarkerAddition</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nv">$connection</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">AddMarkerToMap</span> <span class="nv">$command</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$mapState</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="s1">'SELECT ... FROM ...'</span><span class="p">,</span> <span class="p">[</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">mapId</span><span class="p">()]);</span>\n\n <span class="nv">$map</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">fromState</span><span class="p">(</span><span class="nv">$mapState</span><span class="p">);</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">name</span><span class="p">(),</span> <span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">location</span><span class="p">());</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="s1">'INSERT INTO ...'</span><span class="p">,</span> <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">toState</span><span class="p">()]);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The goal of this piece of code is to add a marker to a <code class="language-plaintext highlighter-rouge">Map</code> object, no matter how the object is stored. Tests that cover this class should focus on business use cases instead of technical details. A solution would be to use a repository design pattern to hide the map storage logic. The class will better follow the <strong>S</strong>ingle <strong>R</strong>esponsable <strong>P</strong>rinciple because it will only handle the marker addition use case whereas the map repository will be in charge of storing data.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HandleMarkerAddition</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Maps</span> <span class="nv">$maps</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Maps</span> <span class="nv">$maps</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">maps</span> <span class="o">=</span> <span class="nv">$maps</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">AddMarkerToMap</span> <span class="nv">$command</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$map</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">maps</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">mapId</span><span class="p">());</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">name</span><span class="p">(),</span> <span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">location</span><span class="p">());</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">maps</span><span class="o">-&gt;</span><span class="nf">add</span><span class="p">(</span><span class="nv">$map</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>With this new design, it is easier to test this class. Thanks to the <code class="language-plaintext highlighter-rouge">Maps</code> interface , we are able to simply create test doubles for the map repository.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// `PostgreSQLMaps` is the implementation used by default on the production</span>\n<span class="nv">$maps</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">PostgreSQLMaps</span><span class="p">();</span>\n<span class="p">(</span><span class="k">new</span> <span class="nc">HandleMarkerAddition</span><span class="p">(</span><span class="nv">$postgreSQLMaps</span><span class="p">)(</span><span class="nv">$command</span><span class="p">);</span>\n\n<span class="c1">// `InMemoryMaps` is an implementation that keeps map objects in memory for testing </span>\n<span class="nv">$maps</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">InMemoryMaps</span><span class="p">();</span>\n<span class="p">(</span><span class="k">new</span> <span class="nc">HandleMarkerAddition</span><span class="p">(</span><span class="nv">$inMemoryMaps</span><span class="p">)(</span><span class="nv">$command</span><span class="p">);</span>\n\n<span class="c1">// In both cases we can retrieve the Map object from the repository to check the map has the new marker.</span>\n<span class="nv">$map</span> <span class="o">=</span> <span class="nv">$maps</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="nv">$command</span><span class="o">-&gt;</span><span class="nf">mapId</span><span class="p">());</span>\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">hasSameState</span><span class="p">(</span><span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best place'</span><span class="p">,</span> <span class="k">new</span> <span class="nc">Marker</span><span class="p">(</span><span class="cm">/* … */</span><span class="p">)))</span> <span class="c1">// should return true;</span>\n\n</code></pre></div></div>\n\n<h3 id="do-not-deal-with-randomness">Do not deal with randomness</h3>\n\n<p>Randomness makes your code unpredictable. To simply test a piece of code you should be able to predict its result. To ease unit testing your code should avoid using randomness as much as possible.</p>\n\n<p>The following example shows a piece of code that uses randomness.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HashedPassword</span>\n<span class="p">{</span>\n <span class="c1">// ... </span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$hash</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">hash</span> <span class="o">=</span> <span class="nv">$hash</span><span class="p">;</span>\n <span class="p">}</span>\n\n\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">fromString</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$hash</span> <span class="o">=</span> <span class="err">\\</span><span class="nb">password_hash</span><span class="p">(</span><span class="nv">$password</span><span class="p">,</span> <span class="no">PASSWORD_BCRYPT</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span><span class="nv">$hash</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="c1">// ...</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">HashedPasswordTest</span> <span class="kd">extends</span> <span class="nc">TestCase</span>\n<span class="p">{</span>\n <span class="cd">/** @test */</span>\n <span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">builds</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="n">password</span><span class="err"> </span><span class="n">from</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="nf">string</span><span class="p">()</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">assertEquals</span><span class="p">(</span>\n <span class="nv">$this</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="s1">'Password1'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">HashedPassword</span><span class="p">(</span><span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span><span class="p">)</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>When we run <code class="language-plaintext highlighter-rouge">HashedPasswordTest</code> we get an error because the <code class="language-plaintext highlighter-rouge">password_hash</code> generates a random salt to hash the password. The problem is that the <code class="language-plaintext highlighter-rouge">password_hash</code> function cannot return the same hash for a given password. Each time you call this function a different hash will be returned.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">-Password</span> Object &amp;000000006e7168e60000000023b11bb2 <span class="o">(</span>\n- <span class="s1">'hash'</span> <span class="o">=&gt;</span> <span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span>\n+Password Object &amp;000000006e7168210000000023b11bb2 <span class="o">(</span>\n+ <span class="s1">'hash'</span> <span class="o">=&gt;</span> <span class="s1">'$2y$10$b/9GX4grnt4gH5cm8FzzSuUNGGQUiA/w.5HdKNEsW3dHtSUeTMXgK'</span>\n</code></pre></div></div>\n\n<p>The simplest solution would be to hardcode the salt to make sure the <code class="language-plaintext highlighter-rouge">hash_password</code> returns the same hash every time but this is not a good design. This would weaken the password generation because we need to test it. Another way would be to extract the hash generation in another place.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">HashedPassword</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">fromString</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">,</span> <span class="kt">PasswordEncryptor</span> <span class="nv">$passwordEncryptor</span><span class="p">):</span> <span class="kt">self</span>\n <span class="p">{</span>\n <span class="nv">$hash</span> <span class="o">=</span> <span class="nv">$passwordEncryptor</span><span class="o">-&gt;</span><span class="nb">hash</span><span class="p">(</span><span class="nv">$password</span><span class="p">);</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span><span class="nv">$hash</span><span class="p">);</span>\n <span class="p">}</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">PasswordEncryptor</code> interface makes test doubles creation possible. Now, we just need to create a fake object to test this method.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">FakePasswordEncryptor</span> <span class="kd">implements</span> <span class="nc">PasswordEncryptor</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">hash</span><span class="p">():</span> <span class="kt">string</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span><span class="p">;</span>\n <span class="p">}</span>\n\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">HashedPasswordTest</span> <span class="kd">extends</span> <span class="nc">TestCase</span>\n<span class="p">{</span>\n <span class="cd">/** @test */</span>\n <span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">builds</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="n">password</span><span class="err"> </span><span class="n">from</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="nf">string</span><span class="p">()</span>\n <span class="p">{</span>\n <span class="nv">$fakePasswordEncryptor</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FakePasswordEncryptor</span><span class="p">();</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">assertEquals</span><span class="p">(</span>\n <span class="n">this</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="s1">'Password1'</span><span class="p">,</span> <span class="nv">$fakePasswordEncryptor</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">HashedPassword</span><span class="p">(</span><span class="s1">'$2y$10$JqfiXNdcuWErfiy5pAJ4O.wKsfic14RsVnVbP/rsdMJJyA9Hg9RCu'</span><span class="p">)</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h3 id="avoid-actual-datetimes">Avoid actual datetimes</h3>\n\n<p>With actual datetimes, we have the same problem as with randomness, neither can be predicted.</p>\n\n<p>The following example shows you that actual datetimes are not predictable like <code class="language-plaintext highlighter-rouge">hash_password</code> in the previous section.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="err">\\</span><span class="nc">DateTimeImmutable</span> <span class="nv">$markerAddedAt</span> <span class="o">=</span> <span class="kc">null</span><span class="p">,</span> <span class="nc">Marker</span> <span class="mf">...</span><span class="nv">$makers</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">addMarker</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$name</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$location</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markerAddedAt</span> <span class="o">=</span> <span class="k">new</span> <span class="err">\\</span><span class="nf">DateTimeImmutable</span><span class="p">(</span><span class="s1">'now'</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="kd">class</span> <span class="nc">MapTest</span> <span class="kd">extends</span> <span class="nc">TestCase</span>\n<span class="p">{</span>\n <span class="cd">/** @test */</span>\n <span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">adds</span><span class="err"> </span><span class="n">marker</span><span class="err"> </span><span class="n">to</span><span class="err"> </span><span class="n">the</span><span class="err"> </span><span class="nf">map</span><span class="p">()</span>\n <span class="p">{</span>\n <span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Map name'</span><span class="p">);</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">,</span> <span class="p">[</span><span class="mf">47.21725</span><span class="p">,</span> <span class="o">-</span><span class="mf">1.55336</span><span class="p">]);</span>\n \n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">assetTrue</span><span class="p">(</span>\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">hasSameState</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">Marker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">,</span> <span class="p">[</span><span class="mf">47.21725</span><span class="p">,</span> <span class="o">-</span><span class="mf">1.55336</span><span class="p">]),</span> \n <span class="k">new</span> <span class="err">\\</span><span class="nf">DateTimeImmutable</span><span class="p">(</span><span class="s1">'now'</span><span class="p">)</span>\n <span class="p">)</span>\n <span class="p">)</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>When we run <code class="language-plaintext highlighter-rouge">MapTest</code> we get an error because we can predict to the millisecond when the marker was added to the map.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">-Map</span> Object &amp;000000003acad975000000006b83e943 <span class="o">()</span>\n+Map Object &amp;000000003acad936000000006b83e943 <span class="o">(</span>\n+ <span class="s1">'markerAddedAt'</span> <span class="o">=&gt;</span> DateTimeImmutable Object &amp;000000003acad946000000006b83e943 <span class="o">(</span>\n+ <span class="s1">'date'</span> <span class="o">=&gt;</span> <span class="s1">'2021-04-18 17:36:02.919004'</span>\n+ <span class="s1">'timezone_type'</span> <span class="o">=&gt;</span> 3\n+ <span class="s1">'timezone'</span> <span class="o">=&gt;</span> <span class="s1">'UTC'</span>\n+ <span class="o">)</span>\n+<span class="o">)</span>\n</code></pre></div></div>\n\n<p>To prevent this kind of problem, a good idea is to abstract time by introducing an interface that is responsible for time management.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">addMarker</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$name</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$location</span><span class="p">,</span> <span class="kt">Clock</span> <span class="nv">$clock</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markerAddedAt</span> <span class="o">=</span> <span class="nv">$clock</span><span class="o">-&gt;</span><span class="nf">now</span><span class="p">();</span>\n <span class="p">}</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, thanks to the <code class="language-plaintext highlighter-rouge">Clock</code> interface we will be able to create test doubles and easily test this method.</p>\n\n<h2 id="coupling-might-be-your-worst-enemy">Coupling might be your worst enemy</h2>\n\n<blockquote>\n <p>Coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)">Wikipedia</a></p>\n</blockquote>\n\n<p>As you have seen in the previous sections, objects should depend on abstractions instead of concrete implementations. Abstractions (e.g. interfaces) ease testing because your code is more modular. You can use test doubles to reduce the complexity and facilitate testing. Their goal is to mimic the behavior of real objects to replace a subpart of an algorithm.</p>\n\n<p>The following example shows that hardcoding object dependencies won’t help to create test doubles.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MyClass</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">ConcreteImplementation</span> <span class="nv">$concreteImplementation</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="c1">// Here we can only use these concrete implementations, if they use IO for instance you won't be able to test it.</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">concreteImplementation</span> <span class="o">=</span> <span class="nv">$concreteImplementation</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">anotherConcreteImplementation</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">AnotherConcreteImplementation</span><span class="p">();</span>\n \n <span class="c1">// Singleton pattern does not help because it hides object dependencies and makes them hard coded.</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nc">Connection</span><span class="o">::</span><span class="nf">getInstance</span><span class="p">();</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The solution is to use the dependency inversion pattern to remove hard coded dependencies introducing abstractions as much as possible.</p>\n\n<blockquote>\n <p>High-level modules should not depend on low-level modules. Both should depend on abstractions (e.g., interfaces). Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.</p>\n\n <p><a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle">Wikipedia</a></p>\n</blockquote>\n\n<p>In the following example, all class dependencies are interchangeable. So, you can easily create test doubles like fake, stub, or mocks to make sure your objects meet business expectations.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">MyClass</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">ImplementationInterface</span> <span class="nv">$concreteImplementation</span><span class="p">,</span>\n <span class="kt">AnoherImplementationInterface</span> <span class="nv">$anotherConcreteImplementation</span><span class="p">,</span>\n <span class="kt">ConnectionInterface</span> <span class="nv">$connection</span>\n <span class="p">)</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">concreteImplementation</span> <span class="o">=</span> <span class="nv">$concreteImplementation</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">anotherConcreteImplementation</span> <span class="o">=</span> <span class="nv">$anotherConcreteImplementation</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nv">$connection</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Caution:</strong> That does not mean you should use interfaces everywhere! Knowing when to introduce new abstractions might be hard at the beginning, there is no magic recipe!</p>\n\n<p>Thanks to my proofreaders <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a> and <a href="https://twitter.com/jjanvier_">@jjanvier_</a>.</p>\n\n Mon, 03 May 2021 00:00:00 -0500\n https://arnolanglade.github.io/why-unit-testing-can-be-hard.html?s=feed\n https://arnolanglade.github.io/why-unit-testing-can-be-hard.html\n \n testing\n \n OOP\n \n \n \n \n \n Why you should not expose objects' state to test them\n <p>To introduce this topic, let’s have a look at the PHP documentation to understand how object comparison works using the comparison and identity operators.</p>\n\n<blockquote>\n <p>When using the comparison operator (==), object variables are compared in a simple manner, namely: Two object instances are equal if they have the same attributes and values (values are compared with ==), and are instances of the same class.</p>\n\n <p>When using the identity operator (===), object variables are identical if and only if they refer to the same instance of the same class.</p>\n\n <p><a href="https://www.php.net/manual/en/language.oop5.object-comparison.php">PHP documentation </a></p>\n</blockquote>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$object</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Object</span><span class="p">();</span>\n<span class="nv">$otherObject</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Object</span><span class="p">();</span>\n\n<span class="nv">$object</span> <span class="o">==</span> <span class="nv">$otherObject</span> <span class="c1">// true</span>\n<span class="nv">$object</span> <span class="o">===</span> <span class="nv">$otherObject</span> <span class="c1">// false </span>\n</code></pre></div></div>\n\n<p>I add an <code class="language-plaintext highlighter-rouge">equals</code> method to objects to handle object comparison. The purpose of this method is to compare an object state with another one. In the following example, I use the comparison operator (==) because I want to check if the objects have the same state no matter their references.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Email</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$email</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$email</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">email</span> <span class="o">=</span> <span class="nv">$email</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">equals</span><span class="p">(</span><span class="kt">Email</span> <span class="nv">$email</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span> <span class="o">==</span> <span class="nv">$email</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>There is another way to compare object state. Do you know that instances of the same class can access each other’s private members?</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Email</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">equals</span><span class="p">(</span><span class="kt">Email</span> <span class="nv">$email</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">email</span> <span class="o">===</span> <span class="nv">$email</span><span class="o">-&gt;</span><span class="n">email</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> This is really useful to compare Doctrine entities that have persistent collections. The error <code class="language-plaintext highlighter-rouge">Error: Nesting level too deep - recursive dependency?</code> is raised when we compare entities using the comparison operator (==). You should have a look at this <a href="https://www.richardlord.net/blog/php/php-nesting-level-too-deep-recursive-dependency.html">blog post</a> to understand why this error occured. Accessing private attributes let you use the identity operator (===) to prevent this error.</p>\n\n<p>By the way, entities are a bit special because an entity is an object that has an identity. It means that if we want to compare them we should compare their identities instead of their states.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">equals</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span><span class="o">-&gt;</span><span class="nf">equals</span><span class="p">(</span><span class="nv">$mapId</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>I add an extra method called <code class="language-plaintext highlighter-rouge">hasSameState</code> to entities to compare their states because entity state comparison remains really useful for testing.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">hasSameState</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">bool</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="nv">$this</span> <span class="o">==</span> <span class="nv">$map</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>For a long time, I used getters for testing purposes. I only knew this way to ensure objects had the right state.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Nantes'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">getName</span><span class="p">()</span><span class="o">-&gt;</span><span class="nf">shouldReturn</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">)</span> <span class="p">;</span>\n</code></pre></div></div>\n\n<p>It was a mistake because exposing objects’ state breaks data encapsulation. We should not know how objects work internally, we should only use their public API (public methods) to interact with them. But, if we need to build the <code class="language-plaintext highlighter-rouge">Map</code> object with something else than a string, this assertion will no longer be true. That will break all application tests and parts that use this getter! That’s not great! Object comparison I described previously helps to get rid of getters.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Nantes'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nb">rename</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">);</span>\n\n<span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">hasSameState</span><span class="p">(</span><span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">))</span><span class="o">-&gt;</span><span class="nf">shouldReturn</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>\n</code></pre></div></div>\n\n<p>Now, the <code class="language-plaintext highlighter-rouge">Map</code> object is better designed. Its state is not exposed anymore which improves data encapsulation. It follows the “Tell don’t ask” principle because I don’t need to extract its internal state to test it. I only need to use its public API to check if it meets the business exceptions.</p>\n\n<p><strong>Tip:</strong> If you don’t want or if you can’t add a method to your objects that handles comparison you can still compare their instances to avoid adding getters.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Assert</span><span class="o">::</span><span class="nf">equals</span><span class="p">(</span><span class="nv">$map</span><span class="p">,</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="s1">'Best places at Bordeaux'</span><span class="p">));</span>\n</code></pre></div></div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 13 Apr 2021 00:00:00 -0500\n https://arnolanglade.github.io/you-should-not-expose-objects-state-to-test-them.html?s=feed\n https://arnolanglade.github.io/you-should-not-expose-objects-state-to-test-them.html\n \n testing\n \n OOP\n \n \n \n \n \n How did I organize my last Symfony projects?\n <p>In this blog post, I will explain how I organized my last Symfony projects. They are mainly inspired by Hexagonal and CQRS architecture. Keep in mind that I did not try to implement these architectures by the book, I only took some concepts that helped me to have a simple and clear codebase organization.</p>\n\n<p>If we have a look at the project’s root, nothing special happens, I kept all folders and files created during Symfony installation.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree <span class="nb">.</span> <span class="nt">-L</span> 1 \n├── bin\n├── composer.json\n├── composer.lock\n├── config\n├── features\n├── public\n├── src\n├── symfony.lock\n├── tests\n├── translations\n├── var\n└── vendor\n</code></pre></div></div>\n\n<p>In the next sections, we are going to see how I organized the src folder.</p>\n\n<h2 id="hexagonal-architecture">Hexagonal architecture</h2>\n\n<p>The foundation of the hexagonal architecture is the explicit separation between the domain (inside) and the infrastructure (outside). All dependencies are going from Infrastructure to the Domain.</p>\n\n<p>The domain is the part of the application that contains your business logic. It must reflect as much as possible the problem your application has to solve. This part of the application must not use IO, the infrastructure contains them all. For instance, IO are side effects like network calls, database queries, filesystem operations, actual timestamps or randomness..</p>\n\n<p>Based on that information my first decision was to split src into two areas: <code class="language-plaintext highlighter-rouge">Domain</code> and <code class="language-plaintext highlighter-rouge">Infrastructure</code>.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/ <span class="nt">-L</span> 1\napi/src/Domain/\n├── Domain\n└── Infrastructure\n</code></pre></div></div>\n\n<p><strong>Coupling rules:</strong></p>\n<ul>\n <li>Domain must not depend on the Infrastructure.</li>\n <li>Domain must not use IO</li>\n</ul>\n\n<p>I am not a big fan of the onion architecture because I want to keep my projects as simple as possible. Having a lot of layers can be really hard to maintain because you need to align the whole team on the coupling rules. Agreeing with yourself is not easy, so getting several people to agree may be really hard. Here, we only have a single rule.</p>\n\n<p>Sometimes, I needed to write libraries because I could not find any open source libraries that match my expectations. To avoid coding in the vendor directory, I introduced a third area called <code class="language-plaintext highlighter-rouge">Libraries</code> (this new area is optional). Those libraries may be used in the domain and the infrastructure but their usage should not break the coupling rules that are defined for those areas.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/ <span class="nt">-L</span> 1\napi/src/Domain/\n├── Domain\n├── Infrastructure\n└── Librairies\n</code></pre></div></div>\n\n<p><strong>Coupling rules:</strong></p>\n<ul>\n <li>Libraries must not depend on Domain and Infrastructure</li>\n</ul>\n\n<p>Finally, I created a “sub” area called <code class="language-plaintext highlighter-rouge">Application</code> in the infrastructure that contains all pieces of code needed to have an application up and running: framework code (Symfony kernel, framework customizations), data fixtures, and migration.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Infrastructure/Application <span class="nt">-L</span> 1 \napi/src/Infrastructure/Application\n├── Exception \n├── Fixture\n├── Kernel.php\n├── Migrations\n├── Security\n└── Kernel\n</code></pre></div></div>\n<p>In this example, <code class="language-plaintext highlighter-rouge">Exception</code> and <code class="language-plaintext highlighter-rouge">Security</code> folders contain framework customizations.</p>\n\n<h2 id="business-first">Business first</h2>\n\n<p>A really important thing for me is to drive codebase organization by business concepts. I don’t want to name folders and classes with technical patterns like factory or repository for instance. Non-tech people should be able to understand what a class does thanks to its name.</p>\n\n<h3 id="domain">Domain</h3>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain <span class="nt">-L</span> 1\napi/src/Domain\n├── Cartographer\n└── Map\n</code></pre></div></div>\n\n<p>Because I did not use any technical words to name folders we can easily imagine the project is about making maps. Now, let’s have a look inside the <code class="language-plaintext highlighter-rouge">Map</code> directory:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/Map <span class="nt">-L</span> 1\n├── CartographersAllowedToEditMap.php // Value object\n├── Description.php // Value object\n├── MapCreated.php // Event \n├── MapId.php // Value object\n├── MapName.php // Value object\n├── Map.php // Root aggregate\n├── Maps.php // Repository interface\n├── Marker // All classes to design Marker entity\n├── MarkerAddedToMap.php // Event\n├── MarkerDeletedFromMap.php // Event\n├── MarkerEditedOnMap.php // Event\n├── UnknownMap.php // Exception\n└── UseCase // Use cases orchestration\n</code></pre></div></div>\n\n<p>In this folder, we have all the pieces of code needed to design the <code class="language-plaintext highlighter-rouge">Map</code> aggregate. As you can see, I did not organize it by design patterns like <code class="language-plaintext highlighter-rouge">ValueObject</code>, <code class="language-plaintext highlighter-rouge">Event</code> or <code class="language-plaintext highlighter-rouge">Exception</code>.</p>\n\n<p>As you might have understood the <code class="language-plaintext highlighter-rouge">Map</code> entity has a one-to-many relationship with the Marker entity. All classes needed to modelize this entity are in the Marker folder and they are organized the same way as the <code class="language-plaintext highlighter-rouge">Map</code> directory.</p>\n\n<p>The <code class="language-plaintext highlighter-rouge">UseCase</code> folder gathers all pieces of code needed to orchestrate use cases like command, their handler and business validation.</p>\n\n<p><strong>Tip:</strong> I don’t suffix repositories by ‘Repository’ but I try to use a business concept to name them like <code class="language-plaintext highlighter-rouge">ProductCatalog</code> for a <code class="language-plaintext highlighter-rouge">Product</code> aggregate. If I can find a business concept to name it I use the plural of the aggregate because a repository is a collection of objects.</p>\n\n<h3 id="infrastructure">Infrastructure</h3>\n\n<p>I organize the root of the <code class="language-plaintext highlighter-rouge">Infrastructure</code> folder the same way as the <code class="language-plaintext highlighter-rouge">Domain</code> one.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Infrastructure <span class="nt">-L</span> 1 \napi/src/Infrastructure\n├── Application\n├── Cartographer\n└── Map\n</code></pre></div></div>\n\n<p>Now, let’s have a look at the <code class="language-plaintext highlighter-rouge">Map</code> directory:</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Infrastructure/Map <span class="nt">-L</span> 1 \napi/src/Infrastructure/Map\n├── Storage\n└── UserInterface\n └── Web\n └── Cli\n</code></pre></div></div>\n\n<p>The <code class="language-plaintext highlighter-rouge">Storage</code> namespace gathers everything related to data storage like repositories, queries. The <code class="language-plaintext highlighter-rouge">UserInterface</code> namespace gathers everything related to ways to interact with the application like the WEB API (controllers) called by the front application or CLI (Symfony commands).</p>\n\n<h2 id="cqrs">CQRS</h2>\n\n<p>CQRS is the acronym for Command Query Responsibility Segregation. The main idea of CQRS is that you can use different models for writing (command) or reading (query) information. I like the idea of having two small and simple models dedicated to a precise purpose: reading or writing instead of having one big model. It can prevent your aggregate from becoming a god object because as things progress you can have many write and read use cases to handle.</p>\n\n<p>From this pattern, I decided to split the domain into two areas, the first one: <code class="language-plaintext highlighter-rouge">Command</code> and the second one: <code class="language-plaintext highlighter-rouge">Query</code>. It allows me to design a model with the same name for these reading or writing purposes.</p>\n\n<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tree src/Domain/ <span class="nt">-L</span> 2\napi/src/Domain/\n├── Command\n│ ├── Cartographer\n│ └── Map\n└── Query\n ├── Cartographer\n └── Map\n</code></pre></div></div>\n\n<p><strong>Coupling rule:</strong></p>\n<ul>\n <li><code class="language-plaintext highlighter-rouge">Command</code> area must not depend on the <code class="language-plaintext highlighter-rouge">Query</code> area and the other way around.</li>\n</ul>\n\n<p><strong>Note:</strong> I did not make major changes in the infrastructure, the only change I made is to split the storage into two areas like the domain.</p>\n\n<p><strong>Caution:</strong> For those projects, I did not make any projections because my database schema remained simple so I did not need them. I only decided to split my models because my codebase was simple and clearer this way.</p>\n\n<h2 id="last-word">Last word</h2>\n<p>I tried for the last few years to find the perfect architecture but it does not exist. I just tried to use some architectural concepts that make me and my teammates comfortable to work on a daily basis. This project organization has been used for two projects that are in production. One of these projects is a side project I made for fun to create maps without Google Maps. The second was a professional project, real people use it on a daily basis.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 30 Mar 2021 00:00:00 -0500\n https://arnolanglade.github.io/how-did-I-organize-my-last-symfony-project.html?s=feed\n https://arnolanglade.github.io/how-did-I-organize-my-last-symfony-project.html\n \n software-architecture\n \n symfony\n \n \n \n \n \n Persisting entities without ORM\n <p>Today, I will talk about persisting entities without ORM. First, I will introduce the repository pattern because it provides a good abstraction to manage object persistence. Then, we will see what are the impacts on the entity design.</p>\n\n<h2 id="repository-pattern">Repository pattern</h2>\n\n<p>The repository design pattern can be used to manage entity persistence and retrieval. It behaves like a collection of objects and hides the complexity of their storage. It ensures a clean separation between the domain model (the entity) and the data model (SQL tables). The following example shows a basic repository interface. Thanks to the <code class="language-plaintext highlighter-rouge">Maps</code> interface we will be able to add and retrieve Map entities, no matter their storage.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">interface</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n <span class="cd">/**\n * @throws \\LogicException\n * @throws UnknownMap\n */</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">get</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">Map</span><span class="p">;</span>\n\n <span class="cd">/**\n * @throws \\LogicException\n */</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">add</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">void</span><span class="p">;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Caution:</strong> All <code class="language-plaintext highlighter-rouge">Maps</code> implementations should be tested with the same test because we need to be sure they behave the same way. It ensures the application works no matter the chosen implementation.</p>\n\n<p>Let’s see how we can implement this interface with PostgreSQL for instance. The <code class="language-plaintext highlighter-rouge">get</code> method is only responsible to get information from the database to build the map entity whereas the <code class="language-plaintext highlighter-rouge">add</code> method extracts the entity information to store them in the database.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PostgreSqlMaps</span> <span class="kd">implements</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Connection</span> <span class="nv">$connection</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">connection</span> <span class="o">=</span> <span class="nv">$connection</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">get</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">Map</span>\n <span class="p">{</span>\n <span class="nv">$sql</span> <span class="o">=</span> <span class="sh">&lt;&lt;&lt;SQL\n SELECT map."mapId", map.name\n FROM map\n WHERE map."mapId" = :mapId\n SQL;</span>\n\n <span class="nv">$statement</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="nv">$sql</span><span class="p">,</span> <span class="p">[</span><span class="s1">'mapId'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="nv">$mapId</span><span class="p">]);</span>\n\n <span class="k">if</span> <span class="p">(</span><span class="kc">false</span> <span class="o">===</span> <span class="nv">$map</span> <span class="o">=</span> <span class="nv">$statement</span><span class="o">-&gt;</span><span class="nf">fetchAssociative</span><span class="p">())</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="nc">UnknownMap</span><span class="o">::</span><span class="nf">withId</span><span class="p">(</span><span class="nv">$mapId</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span><span class="nv">$map</span><span class="p">[</span><span class="s1">'mapId'</span><span class="p">],</span> <span class="nv">$map</span><span class="p">[</span><span class="s1">'name'</span><span class="p">]);</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">add</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$sql</span> <span class="o">=</span> <span class="sh">&lt;&lt;&lt;SQL\n INSERT INTO map ("mapId", name)\n VALUES (:mapId, :name)\n ON CONFLICT ("mapId")\n DO UPDATE SET name = :name;\n SQL;</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="nv">$sql</span><span class="p">,</span> <span class="p">[</span><span class="s1">'mapId'</span> <span class="o">=&gt;</span> <span class="nv">$map</span><span class="p">,</span> <span class="s1">'name'</span> <span class="o">=&gt;</span> <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">name</span><span class="p">()]);</span>\n <span class="p">}</span>\n\n <span class="k">private</span> <span class="k">function</span> <span class="n">executeQuery</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$sql</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$data</span><span class="p">):</span> <span class="kt">Result</span>\n <span class="p">{</span>\n <span class="c1">// Execute query or throw logic exceptions if something goes wrong.</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> Thanks to the clause <a href="https://www.postgresql.org/docs/9.5/sql-insert.html">ON CONFLICT</a> we can easily insert or update data with a single query.</p>\n\n<h2 id="entity-design-impacts">Entity design impacts</h2>\n\n<p>Now we are able to persist and retrieve our map entity. Let’s study the impact on entity design.</p>\n\n<p>Let’s start with persistence. In the previous example, I used getters to get its properties but I am not a fan of the getter to be honest! Getters break data encapsulation because they expose object implementation details. They don’t follow the <a href="https://www.martinfowler.com/bliki/TellDontAsk.html">Tell don’t ask</a> principle because we should not ask about the object state to do something, we should tell the object to do something for us. I like adding a <code class="language-plaintext highlighter-rouge">toState</code> method that is responsible to turn the entity into an associative array.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">toState</span><span class="p">():</span> <span class="kt">array</span>\n <span class="p">{</span>\n <span class="k">return</span> <span class="p">[</span>\n <span class="s1">'mapId'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span><span class="p">,</span>\n <span class="s1">'name'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">string</span><span class="p">)</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">,</span>\n <span class="p">];</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>So I just need to call the <code class="language-plaintext highlighter-rouge">toState</code> method instead of getters, this method returns data expected by the <code class="language-plaintext highlighter-rouge">executeQuery</code> method.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PostgreSqlMaps</span> <span class="kd">implements</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="k">public</span> <span class="k">function</span> <span class="n">add</span><span class="p">(</span><span class="kt">Map</span> <span class="nv">$map</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">executeQuery</span><span class="p">(</span><span class="nv">$sql</span><span class="p">,</span> <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">toState</span><span class="p">());</span>\n <span class="p">}</span>\n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Let’s continue with retrieval. If we have a look at the <code class="language-plaintext highlighter-rouge">Map</code>constructor method we can see that a <code class="language-plaintext highlighter-rouge">MapInitialized</code> event is recorded there. Houston, we have a problem! When we build an entity from its state (data stored somewhere) we don’t want to record any event because nothing happens. So, we need to find a solution to avoid recording those events.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">,</span>\n <span class="kt">MapName</span> <span class="nv">$name</span>\n<span class="p">)</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">mapId</span> <span class="o">=</span> <span class="nv">$mapId</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">recordEvent</span><span class="p">(</span><span class="k">new</span> <span class="nc">MapInitialized</span><span class="p">(</span>\n <span class="nv">$mapId</span><span class="p">,</span>\n <span class="nv">$name</span>\n <span class="p">));</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>I like adding a named constructor called <code class="language-plaintext highlighter-rouge">fromState</code> to the entity. This constructor is responsible for building the aggregate from the state. Moreover, named constructors are explicit and give developers information about when to use them. In the following example, after calling the <a href="https://arnolanglade.github.io/build-object-using-php.html">primary constructor</a> we call the <code class="language-plaintext highlighter-rouge">eraseRecordedEvents</code> method to reset events before returning the object in the right state.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">fromState</span><span class="p">(</span><span class="kt">array</span> <span class="nv">$state</span><span class="p">):</span> <span class="kt">self</span>\n<span class="p">{</span>\n <span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapId</span><span class="p">(</span><span class="nv">$state</span><span class="p">[</span><span class="s1">'mapId'</span><span class="p">]),</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$state</span><span class="p">[</span><span class="s1">'name'</span><span class="p">])</span>\n <span class="p">);</span>\n\n <span class="nv">$map</span><span class="o">-&gt;</span><span class="nf">eraseRecordedEvents</span><span class="p">();</span>\n\n <span class="k">return</span> <span class="nv">$map</span><span class="p">;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>So, the only change in the repository is to build the <code class="language-plaintext highlighter-rouge">Map</code> entity from the named constructor.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">PostgreSqlMaps</span> <span class="kd">implements</span> <span class="nc">Maps</span>\n<span class="p">{</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">get</span><span class="p">(</span><span class="kt">MapId</span> <span class="nv">$mapId</span><span class="p">):</span> <span class="kt">Map</span>\n <span class="p">{</span>\n <span class="c1">// ...</span>\n\n <span class="k">return</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">fromState</span><span class="p">(</span><span class="nv">$map</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<h2 id="last-word">Last word</h2>\n\n<p>I did a presentation about the repository design pattern at the Forum PHP in 2018. A video is only available in French <a href="https://www.youtube.com/watch?v=cYFKkhtIr8w&amp;ab_channel=AFUPPHP">here</a> but the slides are in English <a href="https://arnolanglade.gitlab.io/bad-or-good-repository/">here</a> (press “s” to display English notes). Even if this presentation was made for Doctrine ORM it gives a lot of information about the pattern.</p>\n\n<p><strong>Note:</strong> In this talk I spoke about generating the entity identity by the repository. To be honest, I stopped doing that because generating it from controllers is easier and makes the repository design simpler.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Tue, 23 Mar 2021 00:00:00 -0500\n https://arnolanglade.github.io/persisting-entities-without-orm.html?s=feed\n https://arnolanglade.github.io/persisting-entities-without-orm.html\n \n OOP\n \n design-patterns\n \n \n \n \n \n OOP: how to build an object\n <p>In this new blog post, I want to talk about object building more specifically about primary and secondary constructors. The primary constructor is the default way to build an object with all its dependencies. The secondary constructors provide other ways to build objects depending on use cases.</p>\n\n<p><strong>Note:</strong> I did not work on a PHP8 project yet so that is why I won’t talk about named arguments feature.</p>\n\n<h2 id="primary-constructor">Primary constructor</h2>\n\n<p>The PHP language provides a single way to build an object thanks to the <code class="language-plaintext highlighter-rouge">__construct()</code> method. I use this method to define the primary constructor of my classes to encapsulate all their dependencies.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">MapName</span> <span class="nv">$name</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">CartographersAllowedToEditMap</span> <span class="nv">$cartographersAllowedToEditMap</span><span class="p">;</span>\n <span class="cd">/** @var Marker[] */</span>\n <span class="k">private</span> <span class="kt">array</span> <span class="nv">$markers</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">MapName</span> <span class="nv">$name</span><span class="p">,</span>\n <span class="kt">CartographersAllowedToEditMap</span> <span class="nv">$cartographersAllowedToEditMap</span><span class="p">,</span>\n <span class="kt">Marker</span> <span class="mf">...</span><span class="nv">$markers</span>\n <span class="p">)</span> <span class="p">{</span> \n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">cartographersAllowedToEditMap</span> <span class="o">=</span> <span class="nv">$cartographersAllowedToEditMap</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">markers</span> <span class="o">=</span> <span class="nv">$markers</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> If your objects encapsulate a collection of a specific type (like the <code class="language-plaintext highlighter-rouge">Marker</code> in this example), you can use variadic arguments to automatically validate each item of this collection. Here, we don’t need to iterate the collection to check the type of its items, the language does it for us.</p>\n\n<h2 id="secondary-constructor">Secondary constructor</h2>\n\n<p>The PHP language does not ease the data encapsulation because it only provides a single way to build objects but we should be able to define several constructors depending on all our use cases. How to solve this problem? Named constructors! Named constructors are static factories, in other words static methods that build the object itself.\nLet’s take an example with the map object. How to initialize a map without any marker?</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Map</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">initialize</span><span class="p">(</span>\n <span class="kt">string</span> <span class="nv">$name</span><span class="p">,</span>\n <span class="kt">array</span> <span class="nv">$cartographerAllowedToEditMap</span>\n <span class="p">):</span> <span class="kt">self</span> <span class="p">{</span>\n <span class="k">return</span> <span class="k">new</span> <span class="nc">self</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="nv">$name</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">CartographersAllowedToEditMap</span><span class="p">(</span><span class="nv">$cartographerAllowedToEditMap</span><span class="p">),</span>\n <span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Here, we added a named constructor called <code class="language-plaintext highlighter-rouge">initialize</code> to the <code class="language-plaintext highlighter-rouge">Map</code> class. It uses the primary constructor to build the map object with an empty collection of Marker objects.</p>\n\n<p><strong>Tip:</strong> Some developers change the visibility of the primary constructor method to private but I am not a big fan of that. I use object comparison to test objects to avoid the usage of getters. I like keeping my primary constructor public because it allows me to build objects in any state to compare them to other ones.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> <span class="n">it</span><span class="err"> </span><span class="n">adds</span><span class="err"> </span><span class="n">a</span><span class="err"> </span><span class="n">marker</span><span class="err"> </span><span class="n">on</span><span class="err"> </span><span class="n">the</span><span class="err"> </span><span class="nf">map</span><span class="p">()</span>\n<span class="p">{</span>\n <span class="nv">$actualMap</span> <span class="o">=</span> <span class="nc">Map</span><span class="o">::</span><span class="nf">initialize</span><span class="p">(</span>\n <span class="s1">'Bons plans sur Nantes'</span><span class="p">,</span>\n <span class="p">[</span><span class="s1">'Arnaud'</span><span class="p">]</span>\n <span class="p">);</span>\n\n <span class="nv">$actualMap</span><span class="o">-&gt;</span><span class="nf">addMarker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">);</span>\n\n <span class="nv">$expectedMap</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Map</span><span class="p">(</span>\n <span class="k">new</span> <span class="nc">MapName</span><span class="p">(</span><span class="s1">'Bons plans sur Nantes'</span><span class="p">),</span>\n <span class="k">new</span> <span class="nc">CartographersAllowedToEditMap</span><span class="p">([</span><span class="s1">'Arnaud'</span><span class="p">]),</span>\n <span class="k">new</span> <span class="nc">Marker</span><span class="p">(</span><span class="s1">'Bubar'</span><span class="p">)</span>\n <span class="p">);</span>\n \n <span class="nf">assertSame</span><span class="p">(</span><span class="nv">$actualMap</span><span class="p">,</span> <span class="nv">$expectedMap</span><span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Wed, 10 Mar 2021 00:00:00 -0600\n https://arnolanglade.github.io/oop-how-to-build-an-object.html?s=feed\n https://arnolanglade.github.io/oop-how-to-build-an-object.html\n \n OOP\n \n design-patterns\n \n \n \n \n \n How to validate a command?\n <p>In my previous <a href="http://arnolanglade.github.io/command-handler-patterns.html">blog post</a>, I talked about command and command handler design patterns. I got several questions about data validation and how to give feedback to users. We are going to talk about several kinds of data validation in this blog post. We will start with domain validation, this validation ensures we can build our domain objects in a good state depending on business rules. Then, we will talk about command validation and how we can use it to give feedback to users when they submit data to the application.</p>\n\n<p>Let’s take the same example I used in my previous blog post: an account creation. To create an account, my business expert expects that I provide a username and a password. The username should have at least three characters and should be unique. The password should have at least eight characters, an uppercase letter, a lowercase letter, and a number.</p>\n\n<h2 id="domain-validation">Domain validation</h2>\n\n<p>How to make sure the domain objects follow the business rules? Value object will help us to achieve that. I <strong>strongly recommend you</strong> to wrap all primitives into value objects. It is a good way to introduce new types in your codebase, make it clearer and business-focused. And don’t forget, value objects <strong>cannot</strong> be built in a wrong state.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Username</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$username</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span><span class="err">\\</span><span class="nb">strlen</span><span class="p">(</span><span class="nv">$username</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="err">\\</span><span class="nf">InvalidArgumentException</span><span class="p">(</span><span class="s1">'The username is too short, it should contain at least 3 characters'</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">Password</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span><span class="mi">1</span> <span class="o">!==</span> <span class="err">\\</span><span class="nb">preg_match</span><span class="p">(</span><span class="s1">'#(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,}#'</span><span class="p">,</span> <span class="nv">$password</span><span class="p">))</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="err">\\</span><span class="nf">InvalidArgumentException</span><span class="p">(</span>\n <span class="s1">'The password must contain at least 8 characters, an uppercase letter, lowercase letter and a number'</span>\n <span class="p">);</span>\n <span class="p">}</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then we are able to modelize the <code class="language-plaintext highlighter-rouge">Account</code> aggregate using the <code class="language-plaintext highlighter-rouge">Username</code> and <code class="language-plaintext highlighter-rouge">Password</code> value objects.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">Account</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Username</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="k">private</span> <span class="kt">Password</span> <span class="nv">$password</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span>\n <span class="kt">Username</span> <span class="nv">$username</span><span class="p">,</span>\n <span class="kt">Password</span> <span class="nv">$password</span>\n <span class="p">)</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Now, we are sure that as developers we cannot instantiate the <code class="language-plaintext highlighter-rouge">Account</code> aggregate in a wrong state. In the next section, we are going to see how to use the domain objects to give users feedback about their data.</p>\n\n<h2 id="command-validation">Command validation</h2>\n\n<p>As I explained in my previous <a href="http://arnolanglade.github.io/command-handler-patterns.html">blog post</a>, an account creation is represented by a <code class="language-plaintext highlighter-rouge">CreateAnAccount</code> command with two properties: the username and the password. We need to validate them to create the account aggregate without any errors and tell users if they provided valid data to perform this action. The command validation will be done by the Symfony validator. Don’t hesitate to have a look at the <a href="https://symfony.com/doc/current/validation.html">validator documentation</a> if you are not familiar with it.</p>\n\n<p>First, we will use the callback constraint to make sure the username and password follow the patterns given by the business expert. Thanks to annotation we will configure the validator to call a static method to validate command properties. I will call them “static validators“ in this blog post.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="cd">/** @Assert\\Callback({"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\UsernameShouldBeValid", "validate"}) */</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="cd">/** @Assert\\Callback({"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\PasswordShouldBeValid", "validate"}) */</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">;</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Then, it is time to create those static validators. We just need to instantiate our value objects and check if they throw exceptions to catch them and turn them into violations.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">UsernameShouldBeValid</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">ExecutionContextInterface</span> <span class="nv">$context</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="k">try</span> <span class="p">{</span>\n <span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$username</span><span class="p">);</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="err">\\</span><span class="nc">InvalidArgumentException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>\n <span class="nv">$context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'account.usernameShouldBeValid'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">PasswordShouldBeValid</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$password</span><span class="p">,</span> <span class="kt">ExecutionContextInterface</span> <span class="nv">$context</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="k">try</span> <span class="p">{</span>\n <span class="k">new</span> <span class="nc">Password</span><span class="p">(</span><span class="nv">$password</span><span class="p">);</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="err">\\</span><span class="nc">InvalidArgumentException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>\n <span class="nv">$context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'account.passwordShouldBeValid'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>For more complex use cases you can call any methods on value objects, but you need to keep in mind that you cannot inject services into those static validators.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="kt">BookFlightTicket</span> <span class="nv">$flightTicket</span><span class="p">,</span> <span class="kt">ExecutionContextInterface</span> <span class="nv">$context</span><span class="p">):</span> <span class="kt">void</span>\n<span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span>\n <span class="o">!</span><span class="nc">Date</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="nv">$flightTicket</span><span class="o">&gt;</span><span class="n">departureDate</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">laterThan</span><span class="p">(</span>\n <span class="nc">Date</span><span class="o">::</span><span class="nf">fromString</span><span class="p">(</span><span class="nv">$flightTicket</span><span class="o">&gt;</span><span class="n">arrivalDate</span><span class="p">)</span>\n <span class="p">)</span>\n <span class="p">)</span> <span class="p">{</span>\n <span class="nv">$context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'flightTicket.dateShouldBeValid'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>The first step is done! Thanks to those static validators, we apply domain validation on command properties to ensure we can instantiate domain objects. But, domain validation only works with a single account because the account aggregate only represents the account of a single user. For instance, an account cannot validate if a username is unique because it needs to be aware of the rest of the created account.</p>\n\n<p>To check if a username is used by another user we will need to ask the repository if an account already exists with the given username. That’s why we will need to create a custom validation constraint because those constraints are declared as services, and they can depend on other application services.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cd">/** @Annotation */</span>\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">UsernameShouldBeUnique</span> <span class="kd">extends</span> <span class="nc">Constraint</span>\n<span class="p">{</span>\n<span class="p">}</span>\n\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">UsernameShouldBeUniqueValidator</span> <span class="kd">extends</span> <span class="nc">ConstraintValidator</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span> <span class="o">=</span> <span class="nv">$accounts</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">validate</span><span class="p">(</span><span class="nv">$username</span><span class="p">,</span> <span class="kt">Constraint</span> <span class="nv">$constraint</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nv">$constraint</span> <span class="k">instanceof</span> <span class="nc">UsernameShouldBeUnique</span><span class="p">)</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">UnexpectedTypeException</span><span class="p">(</span><span class="nv">$constraint</span><span class="p">,</span> <span class="nc">UsernameShouldBeUnique</span><span class="o">::</span><span class="n">class</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">try</span> <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span><span class="o">-&gt;</span><span class="nf">getByUsername</span><span class="p">(</span><span class="k">new</span> <span class="nc">Username</span><span class="p">(</span><span class="nv">$username</span><span class="p">));</span>\n\n <span class="c1">// an exception is thrown if an account does not exist so we don’t add violation</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">context</span><span class="o">-&gt;</span><span class="nf">buildViolation</span><span class="p">(</span><span class="s1">'account.usernameShouldBeUnique'</span><span class="p">)</span>\n <span class="o">-&gt;</span><span class="nf">addViolation</span><span class="p">();</span>\n <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">UnknownAccount</span> <span class="nv">$exception</span><span class="p">)</span> <span class="p">{</span>\n <span class="p">}</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Finally, we need to configure the validator to apply this new constraint to the username property.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cd">/**\n * @Assert\\GroupSequence({"CreateAnAccount", "Business"})\n */</span>\n<span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="cd">/** \n * @Assert\\Callback({"Domain\\Account\\UseCase\\ValidationRule\\Superficial\\UsernameShouldBeValid", "validate"})\n * @Domain\\Account\\UseCase\\ValidationRule\\UsernameShouldBeUnique(groups={"Business"})\n */</span>\n <span class="k">private</span> <span class="kt">string</span> <span class="nv">$username</span><span class="p">;</span>\n \n <span class="c1">// ...</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Caution:</strong> we need to apply static validators before applying custom constraints because we need to be sure we can instantiate all domain objects without raising any error. For instance, the instantiation of <code class="language-plaintext highlighter-rouge">Username</code> in <code class="language-plaintext highlighter-rouge">UsernameShouldBeUniqueValidator</code> must not raise any error because the goal of this constraint is not to check if the username contains at least three characters but if the username is already used. It can be done with <a href="https://symfony.com/doc/current/validation/sequence_provider.html">GroupSequence</a>. This validator feature allows adding groups to constraints and defining the validation constraint execution order.</p>\n\n<p>Now, this is the end of the story! If commands are invalid, we just need to serialize violations, give them to your front application, and print errors to users.</p>\n\n<h2 id="last-word">Last word</h2>\n\n<p>This might not be the only way to validate data but it worked on my previous project. Even if I use a service to validate my command I try to use as many domain objects as possible to avoid reinventing the wheel. I hope it answers Baptiste Langlade’s <a href="https://twitter.com/Baptouuuu/status/1364945053236494336">question</a> on Twitter. If you wonder, Baptiste is not my brother ;).</p>\n\n<p>Thanks to my proofreaders <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a> and <a href="https://twitter.com/jjanvier_">@jjanvier_</a>.</p>\n\n Thu, 04 Mar 2021 00:00:00 -0600\n https://arnolanglade.github.io/how-to-validate-a-command.html?s=feed\n https://arnolanglade.github.io/how-to-validate-a-command.html\n \n command-bus\n \n design-patterns\n \n \n \n \n \n Command and command handler design pattern\n <p>This pattern is really interesting; it can help you handle use cases. A command represents the user’s intent, while the command handler performs the actions needed to achieve the use case. Let’s dig a bit into these two concepts.</p>\n\n<h2 id="what-is-a-command">What is a command?</h2>\n\n<p>A command is an object used to encapsulate all the information needed to perform an action. This design pattern is used to represent user intents, and the command is given to a command handler.</p>\n\n<p>A command is often designed as a Data Transfer Object (DTO), which is an object without any behavior (a data structure). The most important design rule to consider is that a command should be easily serializable. This way, it can be sent to a queue such as RabbitMQ or pub-sub to be handled asynchronously.</p>\n\n<h2 id="what-is-a-command-handler">What is a command handler?</h2>\n\n<p>A command handler is just a callable that executes all the actions needed to fulfill a user’s intent. As you may understand, this design pattern is perfect for managing your business use cases.</p>\n\n<h2 id="how-does-it-work">How does it work?</h2>\n\n<p><img src="images/posts/command-handler/explain-command-handler.svg" alt="Command handler design pattern" /></p>\n\n<p>This pattern has some rules. The first one is that a command can be handled by a single command handler because there is only a single way to handle a use case. The second rule is that a command handler should receive a valid command. Validating the command ensures that the user provides the correct data to prevent the handling from failing. It also helps to provide early feedback to the user about the data they provided.</p>\n\n<p>The command is only a DTO that carries data while the command handler is responsible to handle use cases.</p>\n\n<h2 id="how-to-use-it">How to use it?</h2>\n\n<p>Let’s consider a simple example: creating an account. Our business expert expects users to provide an email and a password to create an account for login purposes. We will create a command named <code class="language-plaintext highlighter-rouge">CreateAnAccount</code> and its handler, <code class="language-plaintext highlighter-rouge">CreateAnAccountHandler</code>.\nFirst, we need to create a command named <code class="language-plaintext highlighter-rouge">CreateAnAccount</code> to represent the user’s intent.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="k">public</span> <span class="kt">readonly</span> <span class="n">string</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="k">public</span> <span class="kt">readonly</span> <span class="n">string</span> <span class="nv">$password</span><span class="p">;</span>\n \n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">string</span> <span class="nv">$username</span><span class="p">,</span> <span class="kt">string</span> <span class="nv">$password</span><span class="p">)</span> \n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">username</span> <span class="o">=</span> <span class="nv">$username</span><span class="p">;</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">password</span> <span class="o">=</span> <span class="nv">$password</span><span class="p">;</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Next, we need to create a command handler to manage this use case. The command handler can be a function or an invocable object. It should return nothing (void) to be handled asynchronously as we don’t know when it will be processed and can’t expect an instant result. Using the command data, we perform all actions needed to handle the use case. In our example, we create an account aggregate and pass it to the account repository.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccountHandler</span>\n<span class="p">{</span>\n <span class="k">private</span> <span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">;</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">Accounts</span> <span class="nv">$accounts</span><span class="p">)</span>\n <span class="p">{</span>\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span> <span class="o">=</span> <span class="nv">$accounts</span><span class="p">;</span>\n <span class="p">}</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">CreateAnAccount</span> <span class="nv">$createAnAccount</span><span class="p">):</span> <span class="kt">void</span>\n <span class="p">{</span>\n <span class="nv">$account</span> <span class="o">=</span> <span class="nc">Account</span><span class="o">::</span><span class="nf">create</span><span class="p">(</span>\n <span class="nv">$createAnAccount</span><span class="o">-&gt;</span><span class="nf">username</span><span class="p">(),</span>\n <span class="nv">$createAnAccount</span><span class="o">-&gt;</span><span class="nf">password</span><span class="p">()</span>\n <span class="p">);</span>\n\n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">accounts</span><span class="o">-&gt;</span><span class="nf">add</span><span class="p">(</span><span class="nv">$account</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Finally, let’s stick those pieces of code together in a controller (this example is made with a Symfony Framework). This controller receives JSON-encoded data to create a command, which is then validated and passed to the handler</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">final</span> <span class="kd">class</span> <span class="nc">CreateAnAccount</span>\n<span class="p">{</span>\n <span class="c1">// ...</span>\n \n <span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">Request</span> <span class="nv">$request</span><span class="p">):</span> <span class="kt">Response</span>\n <span class="p">{</span>\n <span class="nv">$command</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">serializer</span><span class="o">-&gt;</span><span class="nf">deserialize</span><span class="p">(</span>\n <span class="nv">$request</span><span class="o">-&gt;</span><span class="nf">getContent</span><span class="p">(),</span>\n <span class="nc">CreateAnAccount</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>\n <span class="s1">'json'</span>\n <span class="p">);</span>\n \n <span class="nv">$violations</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">validator</span><span class="o">-&gt;</span><span class="nf">validate</span><span class="p">(</span><span class="nv">$command</span><span class="p">);</span>\n \n <span class="k">if</span> <span class="p">(</span><span class="mi">0</span> <span class="o">&lt;</span> <span class="nv">$violations</span><span class="o">-&gt;</span><span class="nb">count</span><span class="p">())</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">BadRequestHttpException</span><span class="p">(</span><span class="cm">/*json encoded violation*/</span><span class="p">);</span>\n <span class="p">}</span>\n \n <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="n">createAnAccountHandler</span><span class="p">)(</span><span class="nv">$command</span><span class="p">);</span>\n \n <span class="k">return</span> <span class="k">new</span> <span class="nc">JsonResponse</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nc">Response</span><span class="o">::</span><span class="no">HTTP_CREATED</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n\n</code></pre></div></div>\n<p><strong>Tip:</strong> : To simplify command creation, you can use libraries such as the Symfony Serializer component. It eases object creation from a set of data (e.g., JSON), making the process easier and faster.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$createAccount</span> <span class="o">=</span> <span class="nv">$serializer</span><span class="o">-&gt;</span><span class="nf">deserialize</span><span class="p">(</span>\n <span class="s1">'{“username”:”arnaud”, “password”:“password”}'</span><span class="p">,</span>\n <span class="nc">CreateAnAccount</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>\n <span class="s1">'json'</span>\n<span class="p">);</span>\n</code></pre></div></div>\n\n<p>Tip: To avoid reinventing the wheel, you can leverage libraries like the Symfony Validator component to validate the command.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$violation</span> <span class="o">=</span> <span class="nv">$validator</span><span class="o">-&gt;</span><span class="nf">validate</span><span class="p">(</span><span class="nv">$createAccount</span><span class="p">);</span>\n</code></pre></div></div>\n\n<p>I’ve written a dedicated blog post explaining how to validate a command:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/how-to-validate-a-command.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/data-validation.webp" alt="How to validate a command?" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">How to validate a command?</span>\n </span>\n </a>\n</div>\n\n<h2 id="how-to-simplify-that">How to simplify that?</h2>\n\n<p>To simplify this controller, consider using a command bus, which is responsible for finding the right handler for a given command. For more information about this pattern, I’ve written a dedicated blog post explaining how it works:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/command-bus-design-pattern.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/command-bus/command-bus.svg" alt="The command bus design pattern" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">The command bus design pattern</span>\n </span>\n </a>\n</div>\n\n<p>The following example is built with <a href="https://symfony.com/doc/current/components/messenger.html">Symfony Messenger</a>.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">function</span> <span class="n">__invoke</span><span class="p">(</span><span class="kt">Request</span> <span class="nv">$request</span><span class="p">):</span> <span class="kt">Response</span>\n<span class="p">{</span>\n <span class="nv">$command</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">serializer</span><span class="o">-&gt;</span><span class="nf">deserialize</span><span class="p">(</span>\n <span class="nv">$request</span><span class="o">-&gt;</span><span class="nf">getContent</span><span class="p">(),</span>\n <span class="nc">CreateAnAccount</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>\n <span class="s1">'json'</span>\n <span class="p">);</span>\n \n <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">commandBus</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nv">$command</span><span class="p">);</span>\n \n <span class="k">return</span> <span class="k">new</span> <span class="nc">JsonResponse</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="nc">Response</span><span class="o">::</span><span class="no">HTTP_CREATED</span><span class="p">);</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p>Where is the command validation in this example? Command buses are often built with middleware, making them highly configurable. To ensure that all commands are valid before passing them to a command handler, we need to add middleware to the command bus for command validation.</p>\n\n<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">ValidationMiddleware</span> <span class="kd">implements</span> <span class="nc">MiddlewareInterface</span>\n<span class="p">{</span>\n <span class="c1">// …</span>\n\n <span class="k">public</span> <span class="k">function</span> <span class="n">handle</span><span class="p">(</span><span class="kt">Envelope</span> <span class="nv">$envelope</span><span class="p">,</span> <span class="kt">StackInterface</span> <span class="nv">$stack</span><span class="p">):</span> <span class="kt">Envelope</span>\n <span class="p">{</span>\n <span class="nv">$message</span> <span class="o">=</span> <span class="nv">$envelope</span><span class="o">-&gt;</span><span class="nf">getMessage</span><span class="p">();</span> \n <span class="nv">$violations</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">validator</span><span class="o">-&gt;</span><span class="nf">validate</span><span class="p">(</span><span class="nv">$message</span><span class="p">,</span> <span class="kc">null</span><span class="p">,</span> <span class="nv">$groups</span><span class="p">);</span>\n <span class="k">if</span> <span class="p">(</span><span class="err">\\</span><span class="nb">count</span><span class="p">(</span><span class="nv">$violations</span><span class="p">))</span> <span class="p">{</span>\n <span class="k">throw</span> <span class="k">new</span> <span class="nc">ValidationFailedException</span><span class="p">(</span><span class="nv">$message</span><span class="p">,</span> <span class="nv">$violations</span><span class="p">);</span>\n <span class="p">}</span>\n\n <span class="k">return</span> <span class="nv">$stack</span><span class="o">-&gt;</span><span class="nb">next</span><span class="p">()</span><span class="o">-&gt;</span><span class="nf">handle</span><span class="p">(</span><span class="nv">$envelope</span><span class="p">,</span> <span class="nv">$stack</span><span class="p">);</span>\n <span class="p">}</span>\n<span class="p">}</span>\n</code></pre></div></div>\n\n<p><strong>Tip:</strong> Take a look at this blog post if you need to manage user permissions. Adding a middleware to the command bus can enhance the security of your application:</p>\n\n<div class="post__navigation blog-post-link">\n <a class="post__prev" href="/how-to-handle-user-permissions-through-command-bus-middleware.html">\n <span class="prev__image">\n <img loading="lazy" src="/images/posts/how-to-handle-permissions-through-command-bus-middleware.webp" alt="How to handle user permissions through command bus middleware" />\n </span>\n <span class="prev__box">\n <span class="post__nav__title">How to handle user permissions through command bus middleware</span>\n </span>\n </a>\n</div>\n\n<h2 id="my-last-thoughts">My last thoughts</h2>\n\n<p>In many applications,I have seen a lot of classes named managers or services (e.g., AccountService, AccountManager) that gather all use case management into a single class. While this approach might be effective initially as development progresses, these classes tend to grow larger and larger, and become a “god object.” This makes maintenance challenging, reduces readability, and can quickly turn into a dump. I believe this pattern can address these issues.</p>\n\n<p>Thanks to my proofreader <a href="https://www.linkedin.com/in/laurebrosseau">@LaureBrosseau</a>.</p>\n\n Thu, 25 Feb 2021 00:00:00 -0600\n https://arnolanglade.github.io/command-handler-patterns.html?s=feed\n https://arnolanglade.github.io/command-handler-patterns.html\n \n command-bus\n \n design-patterns\n \n \n \n \n \n\n","url":"/feed.xml","relative_path":"_pages/feed.xml"},{"draft":false,"categories":[],"layout":"default","permalink":"/","title":"Home","content_blocks":[{"_bookshop_name":"hero","title":"Hi there, I am Arnaud!","description_html":"

\n I am a software architect, and technical coach. I focus on understanding business needs to find the best solution. I love everything that ends with *DD such as DDD, BDD and TDD. These tools and all eXtreme Programming values help me to build robust and maintainable software. Last but not least, teamwork is essential: «alone we go faster, together we go further».\n

","image":"/images/me-home.webp","image_alt":"Arnaud Langlade's picture","cta_button":"Contact me","cta_button_link":"/contact/","works_button":"About me","works_button_link":"/about"},{"_bookshop_name":"services-section"},{"_bookshop_name":"testimonials-section","link_url":"/experiences"},{"_bookshop_name":"blog-section","link_url":"/blog"},{"_bookshop_name":"talks-section","link_url":"/talks"}],"slug":"index","ext":".html","tags":[],"excerpt":"","date":"2024-01-08 08:11:03 -0600","content":"","url":"/","relative_path":"_pages/index.html"},{"draft":false,"categories":[],"layout":"default","title":"The mikadoApp","content_blocks":[{"_bookshop_name":"page-heading","title":"The mikadoApp"},{"_bookshop_name":"content","content":"## The mikado method\n\nThe Mikado method takes its name from the Mikado game, where the goal is to remove one stick without disturbing the others. The Mikado method has the same philosophy. It aims to make small incremental improvements to a project without breaking the existing codebase.\n\nOla Ellnestam and Daniel Brolund developed the Mikado Method based on their experience in resolving technical debt in complex legacy systems. They published a book called [The Mikado Method](https://www.manning.com/books/the-mikado-method)\n\nThis method simplifies refactoring. You can continuously improve your codebase instead of stacking a lot of changes which can’t be merged because the test suites are broken. It’s better to regularly merge small changes that improve your codebase quality. This method is ideal for brownfield development. It enables you to add new features or alter existing ones without breaking the rest of the application. Moreover, it facilitates the improvement of the application's architecture while allowing the delivery of new features concurrently.\n\nFor more information, have a look at my blog post on the [Mikado Method](/mikado-method.html)\n\n## Try the MikadoApp\nTry the Mikado App online. For now, I am only using the Vercel free plan, meaning the application may be slow.\n\n
\n \n \n \n \n Try the MikadoApp\n \n
\n\n\nThis project is open source, so don’t hesitate to contribute to the application to improve it! Submit an issue for bugs and share your ideas to enhance the application. Pull requests are very welcome too. The source code is available on\nGitHub.\n\n
\n \n \n Sources on GitHub\n \n
\n\n## How to use the MikadoApp\nLet’s take an example: MySQL doesn’t match the project's needs; you want to migrate your application to PostgreSQL.\nOn the homepage of the Mikado App, enter your objective. Explain what you want to do and click on the “Start” button to begin working.\n\n![describe objective](/images/mikado-app/describe-objective.webp)\n\nThen you arrive on the mikado graph page. You can split your objective into small steps called prerequisites. To achieve the database migration, we first need to install the database and update the repositories due to the usage of SQL queries specific to MySQL.\n\nClick on the 'Add a prerequisite' button to open the prerequisite addition form. Then, describe the actions required to complete the prerequisite. Finally, click on the 'Add' button to add the prerequisite to the Mikado Graph:\n\n![add prerequisite](/images/mikado-app/add-prerequisite.webp)\n\nYou can create as many prerequisites as you want. Don’t forget that small steps are easier to take! As you can see in the following screenshot, the prerequisite bubble has an orange background, indicating indicating the prerequisites have the status ‘To do’:\n\n![prerequisite list](/images/mikado-app/prerequisite-list.webp)\n\nAfter adding prerequisites, select one from the list and click on the “Start exploring” button to start experimenting with things to solve it. The background color of the prerequisite changes to blue, indicating that the prerequisite status is now “Experimenting,” meaning you are actively working on it.\n\nNow, you have two choices: the first one is to click on the “Add a prerequisite” button to split the prerequisite into smaller steps.\n\n![prequisite buble](/images/mikado-app/prequisite-buble.webp)\n\nThe second option is to click on 'Commit your changes' when you finish it and proceed to the next one on the list.\n\n![prerequisite completed](/images/mikado-app/prerequisite-completed.webp)\n\nContinue resolving all prerequisites until the end. When all prerequisites are done, your objective is completed!\n\n![objective completed](/images/mikado-app/objective-completed.webp)\n"},{"_bookshop_name":"blog-section","link_url":"/blog"},{"_bookshop_name":"newsletter"}],"slug":"mikado-app","ext":".html","tags":[],"excerpt":"","date":"2024-01-08 08:11:03 -0600","content":"","url":"/mikado-app/","relative_path":"_pages/mikado-app.html","permalink":null},{"draft":false,"categories":[],"layout":"default","title":"Anaud Langlade's newsletter","content_blocks":[{"_bookshop_name":"page-heading","title":""},{"_bookshop_name":"newsletter"},{"_bookshop_name":"blog-section"}],"slug":"newsletter","ext":".html","tags":[],"excerpt":"","date":"2024-01-08 08:11:03 -0600","content":"","url":"/newsletter/","relative_path":"_pages/newsletter.html","permalink":null},{"draft":false,"categories":[],"layout":"default","title":"Subscription Confirmed - Arnaud Langlade","content_blocks":[{"_bookshop_name":"page-heading","title":"Subscription Confirmed","description":"

\n Your subscription to the newsletter has been confirmed.\n

\n Thank you for subscribing!\n

"},{"_bookshop_name":"blog-section","title":"Recent Posts","link_url":"/blog","show_posts":true}],"slug":"subscription-confirmed","ext":".html","tags":[],"excerpt":"","date":"2024-01-08 08:11:03 -0600","content":"","url":"/subscription-confirmed/","relative_path":"_pages/subscription-confirmed.html","permalink":null},{"draft":false,"categories":[],"layout":"default","title":"Arnaud Langlade's talks","description":"Here are my talks. I love sharing my knowledge about software engineering such as architectural design patterns, software testing, methodologies and so on.","content_blocks":[{"_bookshop_name":"page-heading","title":"My talks"},{"_bookshop_name":"talks-list","show_talks":true},{"_bookshop_name":"blog-section","link_url":"/blog"},{"_bookshop_name":"newsletter"}],"slug":"talks","ext":".html","tags":[],"excerpt":"","date":"2024-01-08 08:11:03 -0600","content":"","url":"/talks/","relative_path":"_pages/talks.html","permalink":null}],"talks":[{"draft":false,"categories":[],"layout":"talk","title":"Programmation STUPID vs SOLID","conference":"Bordeaux PHP Meetup","image":"meetup-php.png","permalink":"/talks/:title:output_ext","date":"2014-01-01 00:00:00 -0600","slug":"meetup-php","ext":".md","tags":[],"excerpt":"

Slides

\n","content":"

Slides

\n\n\n","url":"/talks/meetup-php.html","relative_path":"_talks/2014-01-01-meetup-php.md"},{"draft":false,"categories":[],"layout":"talk","title":"Développer avec le sylius resourcebundle","conference":"Symfony live Paris 2015","conference_link":"https://live.symfony.com/2015-paris","image":"symfony-live.jpg","permalink":"/talks/:title:output_ext","description":"The resource bundle easy CRUD and persistence for Symfony applications.","keyword":"sylius,resource bundle,crud,symfony,rad","date":"2015-03-01 00:00:00 -0600","slug":"symfony-live-2015","ext":".md","tags":[],"excerpt":"

The resource bundle easy CRUD and persistence for Symfony applications.

\n","content":"

The resource bundle easy CRUD and persistence for Symfony applications.

\n\n

During our work on Sylius, the core team noticed a lot of duplicated code across all controllers. The core team started looking for good solution of the problem. The core team is not big fans of administration generators (they’re cool, but not for our usecase!) - the core team wanted something simpler and more flexible.

\n\n

Another idea was to not limit ourselves to one persistence backend. Initial implementation included custom manager classes, which was quite of overhead, so the core team decided to simply stick with Doctrine Common Persistence interfaces. If you are using Doctrine ORM or any of the ODM’s, you’re already familiar with those concepts. Resource bundle relies mainly on ObjectManager and ObjectRepository interfaces.

\n\n

The last annoying problem this bundle is trying to solve, is having separate “backend” and “frontend” controllers, or any other duplication for displaying the same resource, with different presentation (view). The core team also wanted an easy way to filter some resources from list, sort them or display by id, slug or any other criteria - without having to defining another super simple action for that purpose.

\n\n

Videos

\n\n\n\n

Slides

\n\n\n\n

Resources

\n\n

\n Bundle documentation

\n\n

\n Github repository

\n\n

\n Sylius website

\n","url":"/talks/symfony-live-2015.html","relative_path":"_talks/2015-03-01-symfony-live-2015.md"},{"draft":false,"categories":[],"layout":"talk","title":"Php trollons, mais trollons bien!","conference":"Bdx.io 2015","conference_link":"https://www.bdxio.fr","image":"bdxio.jpg","permalink":"/talks/:title:output_ext","date":"2015-10-01 00:00:00 -0500","slug":"bdxio-2015","ext":".md","tags":[],"excerpt":"

Slides

\n","content":"

Slides

\n\n\n","url":"/talks/bdxio-2015.html","relative_path":"_talks/2015-10-01-bdxio-2015.md"},{"draft":false,"categories":[],"layout":"talk","title":"Code me a HR!","conference":"PHPtour 2017","conference_link":"https://event.afup.org/phptournantes2017","homepage":false,"image":"afup-day.png","permalink":"/talks/:title:output_ext","description":"I explain how to refactor an application that uses anaemic models to rich models. I introduce some design patterns like the repository, handling use cases with a command handler and the basics of CQRS.","keywords":"rich model,anemic model,ddd,cqrs,aggregate,command bus,command,command handler","date":"2017-01-01 00:00:00 -0600","slug":"php-tour-2017","ext":".md","tags":[],"excerpt":"

I explain how to refactor an application that uses anaemic models to rich models. I introduce some design patterns like the repository, handling use cases with a command handler and the basics of CQRS.

\n","content":"

I explain how to refactor an application that uses anaemic models to rich models. I introduce some design patterns like the repository, handling use cases with a command handler and the basics of CQRS.

\n\n

Videos

\n\n\n\n

Slides

\n\n\n\n

Resources

\n\n

\n Code example

\n","url":"/talks/php-tour-2017.html","relative_path":"_talks/2017-01-01-php-tour-2017.md"},{"draft":false,"categories":[],"layout":"talk","title":"What is the difference between a good and a bad repository?","conference":"Forum PHP 2018","conference_link":"https://event.afup.org/forumphp2018","homepage":true,"image":"forum-php.png","permalink":"/talks/:title:output_ext","description":"I explain what is the repository pattern and how to design it thanks to Doctrine. I gave some tips to query data without struggling with the ORM.","keywords":"doctrine, repository, design pattern, query function, cqrs, forum php","date":"2018-10-01 00:00:00 -0500","slug":"forum-php-2018","ext":".md","tags":[],"excerpt":"

I explain what is the repository pattern and how to design it thanks to Doctrine. I gave some tips to query data without struggling with the ORM.

\n","content":"

I explain what is the repository pattern and how to design it thanks to Doctrine. I gave some tips to query data without struggling with the ORM.

\n\n

Videos

\n\n\n\n

Slides

\n\n\n\n

Resources

\n\n

\n Code example

\n\n

\n Speaker interview

\n","url":"/talks/forum-php-2018.html","relative_path":"_talks/2018-10-01-forum-php-2018.md"},{"draft":false,"categories":[],"layout":"talk","title":"Example Mapping: ease business knowledge sharing with your team","conference":"Agile Adour #2","conference_link":"https://lameleeadour.com/evenements/agile-adour-2/","image":"agile-adour.png","permalink":"/talks/:title:output_ext","keywords":"agile adour,example mapping,bdd,behavior driven development,agile adour,no estimate,team collaboration,sticky note,small story,domain problem","description":"I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team's understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.","date":"2022-12-01 00:00:00 -0600","slug":"agile-adour-2","ext":".md","tags":[],"excerpt":"

I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team’s understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.

\n","content":"

I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team’s understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.

\n\n

Slides

\n\n\n","url":"/talks/agile-adour-2.html","relative_path":"_talks/2022-12-01-agile-adour-2.md"},{"draft":false,"categories":[],"layout":"talk","title":"Example Mapping: ease business knowledge sharing with your team","conference":"Agile tour Rennes 2022","conference_link":"https://agiletour.agilerennes.org/","homepage":true,"image":"agile-tour-rennes.jpg","keywords":"agile tour rennes,example mapping,bdd,behavior driven development,agile tour rennes,no estimate,team collaboration,sticky note,small story,domain problem","description":"I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team's understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.","date":"2022-12-16 00:00:00 -0600","slug":"agile-tour-rennes-2022","ext":".md","tags":[],"excerpt":"

I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team’s understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.

\n","content":"

I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team’s understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.

\n\n

Slides

\n\n\n","url":"/talks/agile-tour-rennes-2022.html","relative_path":"_talks/2022-12-16-agile-tour-rennes-2022.md","permalink":null},{"draft":false,"categories":[],"layout":"talk","title":"Unit testing: essential and complicated at the same time","conference":"Alpes Craft 2023","conference_link":"https://www.alpescraft.fr","homepage":true,"image":"alpes-craft.png","keywords":"test,unit,unit test,dependency inversion,encapsulation,tdd,srp,composition,coupling","description":"When I started coding I could develop for hours without executing my code. Then, I needed to debug it for hours. It wasn't funny! I discovered what was testing and I understood its benefits. However, it wasn't easy to write my first tests. We can make many mistakes that make tests hard to write and maintain. I would like to present to you what I have learned over the last few years to help you write tests.","date":"2023-06-01 00:00:00 -0500","slug":"alpes-craft-2023","ext":".md","tags":[],"excerpt":"

When I started coding I could develop for hours without executing my code. Then, I needed to debug it for hours. It wasn’t funny! I discovered what was testing and I understood its benefits. However, it wasn’t easy to write my first tests. We can make many mistakes that make tests hard to write and maintain. I would like to present to you what I have learned over the last few years to help you write tests.

\n","content":"

When I started coding I could develop for hours without executing my code. Then, I needed to debug it for hours. It wasn’t funny! I discovered what was testing and I understood its benefits. However, it wasn’t easy to write my first tests. We can make many mistakes that make tests hard to write and maintain. I would like to present to you what I have learned over the last few years to help you write tests.

\n\n

Slides

\n\n\n","url":"/talks/alpes-craft-2023.html","relative_path":"_talks/2023-06-01-alpes-craft-2023.md","permalink":null},{"draft":false,"categories":[],"layout":"talk","title":"Example Mapping: ease business knowledge sharing with your team","conference":"Sunny tech 2023","conference_link":"https://sunny-tech.io/","homepage":false,"image":"sunny-tech.webp","keywords":"sunny tech,example mapping,bdd,behavior driven development,no estimate,team collaboration,sticky note,small story,domain problem","description":"I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team's understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.","date":"2023-06-30 00:00:00 -0500","slug":"sunny-tech-2023","ext":".md","tags":[],"excerpt":"

I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team’s understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.

\n","content":"

I explain and share tips about how to run an example mapping. Example mapping is a good way to align the team’s understanding of domain problems and help your team to better collaborate. Last but not least, it eases to refine your stories and improve your backlog prioritization.

\n\n

Videos

\n\n\n\n

Slides

\n\n\n","url":"/talks/sunny-tech-2023.html","relative_path":"_talks/2023-06-30-sunny-tech-2023.md","permalink":null},{"draft":false,"categories":[],"layout":"talk","title":"Unit testing: essential and complicated at the same time","conference":"Agile Tour Bordeaux 2023","conference_link":"https://agiletourbordeaux.fr","homepage":false,"image":"agile-tour-bordeaux.webp","keywords":"test,unit,unit test,dependency inversion,encapsulation,tdd,srp,composition,coupling","description":"When I started coding I could develop for hours without executing my code. Then, I needed to debug it for hours. It wasn't funny! I discovered what was testing and I understood its benefits. However, it wasn't easy to write my first tests. We can make many mistakes that make tests hard to write and maintain. I would like to present to you what I have learned over the last few years to help you write tests.","date":"2023-09-27 00:00:00 -0500","slug":"agile-tour-bordeaux","ext":".md","tags":[],"excerpt":"

When I started coding I could develop for hours without executing my code. Then, I needed to debug it for hours. It wasn’t funny! I discovered what was testing and I understood its benefits. However, it wasn’t easy to write my first tests. We can make many mistakes that make tests hard to write and maintain. I would like to present to you what I have learned over the last few years to help you write tests.

\n","content":"

When I started coding I could develop for hours without executing my code. Then, I needed to debug it for hours. It wasn’t funny! I discovered what was testing and I understood its benefits. However, it wasn’t easy to write my first tests. We can make many mistakes that make tests hard to write and maintain. I would like to present to you what I have learned over the last few years to help you write tests.

\n\n

Videos

\n\n\n\n

Slides

\n\n\n","url":"/talks/agile-tour-bordeaux.html","relative_path":"_talks/2023-09-27-agile-tour-bordeaux.md","permalink":null}],"testimonials":[{"draft":false,"categories":[],"layout":"default","name":"Arnaud LEMAIRE","position":"VP/Chief Architect at Sunday","homepage":true,"social_media_link":"https://www.linkedin.com/in/lilobase/","blurb":"Arnaud est un développeur exceptionnel, dont l'autonomie et l'initiative ont marqué son passage dans nos équipes. Sa capacité à prendre en charge des projets de A à Z ainsi que son esprit d'analyse et de synthèse en font un très bon leader technique. Si vous avez la chance d'avoir Arnaud dans votre équipe, vous verrez rapidement son impact positif. Je recommande Arnaud avec enthousiasme.","title":"40 Sunday","slug":"40-sunday","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/testimonials/40-sunday.html","relative_path":"_testimonials/40-sunday.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Denis Migot","position":"Engineer Manager at Sunday","homepage":false,"social_media_link":"https://www.linkedin.com/in/denis-migot","blurb":"J'ai eu la chance de travailler avec Arnaud pendant plusieurs mois au sein de Sunday. Je dis bien 'chance' car j'ai appris beaucoup à ses côtés, que ce soit sur l'exercice de son métier que sur l'environnement nécessaire au bon exercice de son métier. Je recommande donc chaudement Arnaud qui, au-delà de ses connaissances multiples et de son expertise profonde, est un collègue très agréable avec qui travailler !","title":"50 Sunday","slug":"50-sunday","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/testimonials/50-sunday.html","relative_path":"_testimonials/50-sunday.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Laurent Verdier","position":"Web developer at Palo IT","homepage":false,"social_media_link":"https://www.linkedin.com/in/lverdier/","blurb":"It was my pleasure to work in pair-programming with Arnaud for 3 months. His mastery of TDD and his ability to guide his teammates into it made the whole experience extremely profitable and allowed to produce a very well-decoupled, expressive code. We could rely a lot on his ability to split a big feature into smaller steps, without being confused by the general complexity of the task at hand. Finally, his constant focus on building iteratively things that work and bring value make him a 5* asset in a software development team.","title":"55 Laurent","slug":"55-laurent","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/testimonials/55-laurent.html","relative_path":"_testimonials/55-laurent.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Arnaud Faissolle","position":"Engineer Manager at Akeneo","social_media_link":"https://www.linkedin.com/in/arnaud-faissolle-249315","blurb":"Arnaud is a very talentuous senior software engineer with robust and proven experience. Arnaud, as leader of a development squad, has successfully delivered a SaaS native platform from first steps of product ideation all the way to the SaaS platform in production. Thanks to Arnaud broad technical expertise and smart human touch, he has been able to lead, coach and grow multiple members of the squad (product manager, software engineer, DevOps). While being very demanding for himself, Arnaud is very pleasant toward his team members and fun to work with.","title":"60 Akeneo Shared Catalog","slug":"60-akeneo-shared-catalog","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/testimonials/60-akeneo-shared-catalog.html","relative_path":"_testimonials/60-akeneo-shared-catalog.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Nicolas Dupont","position":"Co-founder at Akeneo","homepage":true,"social_media_link":"https://www.linkedin.com/in/nicolasdupontakeneo","blurb":"Arnaud is a great software engineer. He led the design and delivery of valuable features and capabilities in our product offer. He introduced, advocated, and embodied many excellent practices like domain-driven design, event storming, and more. His passion for clean architecture and quality positively influenced our entire product development team..","title":"70 Akeneo Pim","slug":"70-akeneo-pim","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/testimonials/70-akeneo-pim.html","relative_path":"_testimonials/70-akeneo-pim.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Paweł Jędrzejewski","position":"Founder at Sylius","social_media_link":"https://www.linkedin.com/in/pjedrzejewski","blurb":"Arnaud has been a great Open Source collaborator and developer in the early days of Sylius. Skilled with BDD tools and modern development techniques. Highly recommended!","title":"80 Sylius","slug":"80-sylius","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/testimonials/80-sylius.html","relative_path":"_testimonials/80-sylius.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Boris Schapira","position":"Project manager","social_media_link":"https://www.linkedin.com/in/borisschapira","blurb":"J'ai travaillé pendant plusieurs années chez Clever Age en même temps qu'Arnaud. Nous avons souvent évolué sur des projets différents, mais avons eu quelques occasions de travailler ensemble, notamment sur des démarrages de projets Symfony où l'expertise d'Arnaud était très appréciée, puisqu'il était capable de comprendre les problématiques métiers que nous rencontrions et de nous proposer la juste couche d'abstraction pour y répondre, afin de partir sur une architecture logicielle dont la complexité était adaptée. Si l'occasion venait à ne présenter, je travaillerais à nouveau avec Arnaud avec plaisir, et confiance.","title":"90 Clever Age","slug":"90-clever-age","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/testimonials/90-clever-age.html","relative_path":"_testimonials/90-clever-age.md","permalink":null}],"services":[{"draft":false,"categories":[],"layout":"default","name":"Software architect","image":"build","blurb":"I can help your company to build solid software foundations and organize your teams to keep shipping more features faster. I like understanding business problems thanks to event storming or example mapping to find the right solution.","title":"01 Architect","slug":"01-architect","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/services/01-architect.html","relative_path":"_services/01-architect.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Technical coach","image":"contact","blurb":"I can join your team as a technical coach to help you grow your teams. I will mentor them on software crafting practices, focusing on high code quality, software testing, pair/ensemble programming, etc.","title":"02 Technical Coach","slug":"02-technical-coach","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/services/02-technical-coach.html","relative_path":"_services/02-technical-coach.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Lead software engineer","image":"desktop","blurb":"I can lead your team as a lead software engineer to craft robust and sustainable software: implement quality processes, design the application's architectural foundations, and guide the team to produce high-quality, tested code that met business requirements.","title":"03 Software Engineer","slug":"03-software-engineer","ext":".md","tags":[],"excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/services/03-software-engineer.html","relative_path":"_services/03-software-engineer.md","permalink":null}],"experiences":[{"draft":false,"categories":[],"layout":"default","name":"Input Output (IOHK)","position":"Senior Software engineer","image":"/images/experiences/iogk.webp","tags":["Node","React"],"homepage":true,"link":"https://iohk.io/","blurb":"OHK is one of the world's foremost research and engineering companies in the field of blockchain infrastructure. IOHK is the company entrusted by the Cardano Foundation for the development of the Cardano blockchain.","title":"20 Iogk","slug":"20-iogk","ext":".md","excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/experiences/20-iogk.html","relative_path":"_experiences/20-iogk.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Sunday","position":"Senior Software engineer","image":"/images/experiences/sunday.webp","tags":["Java","Node","React"],"homepage":true,"link":"https://sundayapp.com","blurb":"Sunday is a payment system designed for restaurants, enabling millions of people to save time at the end of their meals through a QR code that can be scanned to settle the bill.","title":"30 Sunday","slug":"30-sunday","ext":".md","excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/experiences/30-sunday.html","relative_path":"_experiences/30-sunday.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Akeneo","position":"(Lead|Staff) Software engineer","image":"/images/experiences/akeneo.webp","tags":["PHP"],"homepage":true,"link":"https://www.akeneo.com","blurb":"Akeneo, a global leader in Product Experience Management (PXM), empowers businesses to enhance their growth opportunities through a consistent and compelling product experience across all sales channels.","title":"50 Akeneo Pim","slug":"50-akeneo-pim","ext":".md","excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/experiences/50-akeneo-pim.html","relative_path":"_experiences/50-akeneo-pim.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Groupe Sud Ouest Interactive","position":"Software engineer at Clever Age","image":"/images/experiences/sud-ouest.webp","tags":["PHP"],"homepage":true,"link":"https://www.groupesudouest.com/","blurb":"The Sud Ouest Group is an independent group specialized in information, communication, and services, whose media brands Sud Ouest, Charente libre and La république des Pyrénées are closely tied to their respective regions.\"","title":"60 Sud Ouest","slug":"60-sud-ouest","ext":".md","excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/experiences/60-sud-ouest.html","relative_path":"_experiences/60-sud-ouest.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Sylius","position":"Core team member","image":"/images/experiences/sylius.webp","tags":["PHP","Javascript"],"homepage":true,"link":"https://sylius.com","blurb":"As a member of the Sylius core team, I was involved in the development of Sylius. Sylius is an open-source e-commerce framework that simplifies the creation of online stores.","title":"70 Sylius","slug":"70-sylius","ext":".md","excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/experiences/70-sylius.html","relative_path":"_experiences/70-sylius.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Royal Canin - EasyPack","position":"Lead software engineer at Galilée","image":"/images/experiences/royal-canin.webp","tags":["PHP","Javascript"],"link":"https://www.royalcanin.com","blurb":"Easypack is the tool that enables the Packaging department to automate the packaging production process for the entire brand's product line. Based on a marketing production workflow management software (Dalim ES) Easypack is deployed worldwide for all stakeholders connected to Royal Canin","title":"80 Royal Canin","slug":"80-royal-canin","ext":".md","excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/experiences/80-royal-canin.html","relative_path":"_experiences/80-royal-canin.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Prisma media - CMonOeuvre.com","position":"Software engineer at Galilée","image":"/images/experiences/prisma-media.webp","tags":["PHP","Javascript"],"link":"https://www.prismamedia.com","blurb":"CmonOeuvre is a web-to-print store that enables online creation of canvases, postcards, and other formats using high-quality professional photos provided by magazines such as GEO, RMN, and National Geographic, which are part of the Prisma Media Group.","title":"90 Prisma Presse","slug":"90-prisma-presse","ext":".md","excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/experiences/90-prisma-presse.html","relative_path":"_experiences/90-prisma-presse.md","permalink":null},{"draft":false,"categories":[],"layout":"default","name":"Télécoms sans frontières","position":"Telecommunication technician","image":"/images/experiences/tsf.webp","tags":["PHP","Javascript"],"homepage":true,"link":"https://www.tsfi.org","blurb":"Télécoms Sans Frontières (TSF) is the leading emergency telecommunications NGO. During humanitarian crises, TSF enables affected individuals to reconnect with their loved ones. The organization also sets up emergency communication centers to assist local and international humanitarian actors.","title":"99 Tsf","slug":"99-tsf","ext":".md","excerpt":"\n","date":"2024-01-08 08:11:03 -0600","content":"\n","url":"/experiences/99-tsf.html","relative_path":"_experiences/99-tsf.md","permalink":null}],"data":{"newsletter":{"newsletter_title":"Newsletter: Be the first to know!","newsletter_description":"Subscribe to my newsletter for updates on my latest blog posts, tech releases, and exclusive content. Stay ahead in the coding game!","newsletter_identifier":"https://gmail.us13.list-manage.com/subscribe/post","newsletter_button":"Subscribe"},"social_links":{"social":[{"icon":"twitter","link":"https://twitter.com/arnolanglade","alt":"twitter"},{"icon":"linkedin","link":"https://www.linkedin.com/in/arnolanglade","alt":"linkedin"},{"icon":"bluesky","link":"https://bsky.app/profile/arnolanglade.bsky.social","alt":"bluesky"},{"icon":"mastodon","link":"https://mastodon.social/@arnolanglade","alt":"mastodon"},{"icon":"github","link":"https://github.com/arnolanglade","alt":"github"},{"icon":"youtube","link":"https://www.youtube.com/@arnolanglade","alt":"youtube"},{"icon":"rss","link":"/feed.xml","alt":"rss"}]},"navigation":{"menu__settings":{"menu__items":[{"title":"Home","url":"/"},{"title":"About me","submenu":[{"title":"About me","url":"/about/"},{"title":"My experiences","url":"/experiences/"},{"title":"My talks","url":"/talks/"}]},{"title":"Blog","url":"/blog/"},{"title":"MikadoApp","url":"/mikado-app/"},{"title":"Contact","url":"/contact/"}]}},"general_settings":{"name":"Langlade Arnaud","title":"Arnaud Langlade - Senior software engineer, software architect, and technical coach","description":"Arnaud Langlade - I am a software architect, and technical coach. I focus on understanding business needs to find the best solution. I love everything that ends with *DD such as DDD, BDD and TDD. These tools and all eXtreme Programming values help me to build robust and maintainable software. Last but not least, teamwork is essential: «alone we go faster, together we go further».","keywords":"arnaud langlade,langlade,freelancer,software engineer,architect,technical coach,software,oop,blog,talk,tdd,bdd,ddd,event storming,example mapping,arnolanglade","social_media_share_image":"/images/me-home.webp","disqus-identifier":"arnaudlanglade"},"footer":{"footer_menu__settings":{"menu__items":[{"title":"Home","url":"/"},{"title":"About me","url":"/about/"},{"title":"My experiences","url":"/experiences/"},{"title":"My talks","url":"/talks/"},{"title":"Blog","url":"/blog/"},{"title":"MikadoApp","url":"/mikado-app/"},{"title":"Contact","url":"/contact/"}]},"copyright_text_html":"

2021 © Langlade Arnaud. Template by CloudCannon.

"}},"baseurl":null,"title":"Arnaud Langlade"}} \ No newline at end of file diff --git a/feed.xml b/feed.xml index 99fecfc1..c2c1679f 100644 --- a/feed.xml +++ b/feed.xml @@ -5,8 +5,8 @@ https://arnolanglade.github.io/ - Tue, 02 Jan 2024 05:30:02 -0600 - Tue, 02 Jan 2024 05:30:02 -0600 + Mon, 08 Jan 2024 08:11:03 -0600 + Mon, 08 Jan 2024 08:11:03 -0600 Jekyll v4.2.1 @@ -1362,7 +1362,7 @@ k</p> <blockquote> <p>Starting with CQRS, CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).</p> - <p><a href="https://web.archive.org/web/20190211113420/http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-sourcing-agh/">Greg young</a></p> + <p><a href="https://web.archive.org/web/20190211113420/http://codebetter.com/gregyoung/2010/02/16/cqrs-task-based-uis-event-sourcing-agh/">Greg Young</a></p> </blockquote> <p><strong>Note:</strong> Greg Young’s blog does not exist anymore but his blog posts are still available thanks to archived.org.</p> @@ -1382,19 +1382,31 @@ k</p> a command and query bus, an event sourcing architecture or multiple databases. Greg Young published this blog post in 2012 to explain what CQRS was not about.</p> <blockquote> - <p>CQRS is not a silver bullet -CQRS is not a top level architecture -CQRS is not new -CQRS is not shiny -CQRS will not make your jump shot any better -CQRS is not intrinsically linked to DDD -CQRS is not Event Sourcing -CQRS does not require a message bus -CQRS is not a guiding principle / CQS is -CQRS is not a good wife -CQRS is learnable in 5 minutes -CQRS is a small tactical pattern -CQRS can open many doors.</p> + <p>CQRS is not a silver bullet</p> + + <p>CQRS is not a top level architecture</p> + + <p>CQRS is not new</p> + + <p>CQRS is not shiny</p> + + <p>CQRS will not make your jump shot any better</p> + + <p>CQRS is not intrinsically linked to DDD</p> + + <p>CQRS is not Event Sourcing</p> + + <p>CQRS does not require a message bus</p> + + <p>CQRS is not a guiding principle / CQS is</p> + + <p>CQRS is not a good wife</p> + + <p>CQRS is learnable in 5 minutes</p> + + <p>CQRS is a small tactical pattern</p> + + <p>CQRS can open many doors.</p> </blockquote> <p><strong>Note:</strong> This blog does not exist anymore but it has been archived by archived.org. The post is available <a href="https://web.archive.org/web/20160729165044/https://goodenoughsoftware.net/2012/03/02/cqrs/">here</a></p> diff --git a/sitemap.xml b/sitemap.xml index 686b3ac9..01149993 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -2,43 +2,43 @@ https://arnolanglade.github.io/about/ -2024-01-02T05:30:02-06:00 +2024-01-08T08:11:03-06:00 https://arnolanglade.github.io/blog/ -2024-01-02T05:30:02-06:00 +2024-01-08T08:11:03-06:00 https://arnolanglade.github.io/contact/ -2024-01-02T05:30:02-06:00 +2024-01-08T08:11:03-06:00 https://arnolanglade.github.io/experiences/ -2024-01-02T05:30:02-06:00 +2024-01-08T08:11:03-06:00 https://arnolanglade.github.io/feed.xml -2024-01-02T05:30:02-06:00 +2024-01-08T08:11:03-06:00 https://arnolanglade.github.io/ -2024-01-02T05:30:02-06:00 +2024-01-08T08:11:03-06:00 https://arnolanglade.github.io/mikado-app/ -2024-01-02T05:30:02-06:00 +2024-01-08T08:11:03-06:00 https://arnolanglade.github.io/newsletter/ -2024-01-02T05:30:02-06:00 +2024-01-08T08:11:03-06:00 https://arnolanglade.github.io/subscription-confirmed/ -2024-01-02T05:30:02-06:00 +2024-01-08T08:11:03-06:00 https://arnolanglade.github.io/talks/ -2024-01-02T05:30:02-06:00 +2024-01-08T08:11:03-06:00 https://arnolanglade.github.io/command-handler-patterns.html @@ -225,26 +225,26 @@ https://arnolanglade.github.io/blog.html -2024-01-02T05:29:25-06:00 +2024-01-08T08:10:33-06:00 https://arnolanglade.github.io/slides/agile-adour-example-mapping.html -2024-01-02T05:29:25-06:00 +2024-01-08T08:10:33-06:00 https://arnolanglade.github.io/slides/agile-tour-bordeaux.html -2024-01-02T05:29:25-06:00 +2024-01-08T08:10:33-06:00 https://arnolanglade.github.io/slides/agile-tour-rennes-example-mapping.html -2024-01-02T05:29:25-06:00 +2024-01-08T08:10:33-06:00 https://arnolanglade.github.io/slides/alpes-craft-unit-tests.html -2024-01-02T05:29:25-06:00 +2024-01-08T08:10:33-06:00 https://arnolanglade.github.io/slides/sunny-tech-example-mapping.html -2024-01-02T05:29:25-06:00 +2024-01-08T08:10:33-06:00 diff --git a/what-is-the-difference-between-cqs-and-cqrs-patterns.html b/what-is-the-difference-between-cqs-and-cqrs-patterns.html index 8a90e992..2cc8ce43 100644 --- a/what-is-the-difference-between-cqs-and-cqrs-patterns.html +++ b/what-is-the-difference-between-cqs-and-cqrs-patterns.html @@ -287,7 +287,7 @@

What is Command Q

Starting with CQRS, CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).

-

Greg young

+

Greg Young

Note: Greg Young’s blog does not exist anymore but his blog posts are still available thanks to archived.org.

@@ -307,19 +307,31 @@

What is Command Q a command and query bus, an event sourcing architecture or multiple databases. Greg Young published this blog post in 2012 to explain what CQRS was not about.

-

CQRS is not a silver bullet -CQRS is not a top level architecture -CQRS is not new -CQRS is not shiny -CQRS will not make your jump shot any better -CQRS is not intrinsically linked to DDD -CQRS is not Event Sourcing -CQRS does not require a message bus -CQRS is not a guiding principle / CQS is -CQRS is not a good wife -CQRS is learnable in 5 minutes -CQRS is a small tactical pattern -CQRS can open many doors.

+

CQRS is not a silver bullet

+ +

CQRS is not a top level architecture

+ +

CQRS is not new

+ +

CQRS is not shiny

+ +

CQRS will not make your jump shot any better

+ +

CQRS is not intrinsically linked to DDD

+ +

CQRS is not Event Sourcing

+ +

CQRS does not require a message bus

+ +

CQRS is not a guiding principle / CQS is

+ +

CQRS is not a good wife

+ +

CQRS is learnable in 5 minutes

+ +

CQRS is a small tactical pattern

+ +

CQRS can open many doors.

Note: This blog does not exist anymore but it has been archived by archived.org. The post is available here