00:00:05.279
So, you want to build a majestic monolith. However, what you often end up with is a big ball of mud. Perhaps you have recently started a new job and inherited a big ball of mud. If you want to transition from this chaotic state to a more organized structure, one effective approach is to modularize your application.
00:00:14.480
There are various strategies and best practices regarding how to modularize your application. However, that won't be the focus of this talk. Instead, we will explore two tools that can help you effectively implement modules and ensure you do not unintentionally break your module boundaries. The important aspect of these tools is that they allow for incremental changes, enabling you to apply them step by step at your own pace, especially if you are working with an existing codebase.
00:00:38.719
The tools we will examine are `private_constant` and `Packwerk`. Let's start with `private_constant`. This is a built-in feature of Ruby and part of the language itself. To illustrate this, let’s consider an example. Imagine you have a module called `Taxes` consisting of two classes: `TaxDetails`, which contains logic for calculating taxes; and `Apply`, which acts as the service object.
00:01:09.759
Clients of your module are expected to use the `Apply` class if they want to calculate something. In the example provided, we successfully shipped this setup. However, later on, someone might write a view that directly uses the `TaxDetails` class, which is intended to be internal. This is not desired, as it couples the view to `TaxDetails`. If changes occur within the `Taxes` module, it may break the view, necessitating additional fixes.
00:01:32.799
To resolve this issue, we can return to our `Taxes` module and introduce the `private_constant` statement, thereby making the `TaxDetails` class private to the module. Now, if a programmer attempts to access it from the view, they would encounter an exception. This indicates they will need to revisit the `Taxes` module to comprehend the intended usage. The `private_constant` feature can be utilized right away, helping you define your module's API by clearly indicating which parts are public.
00:02:31.560
By having a well-defined API, you can also enhance your code documentation, ensuring that anyone who needs to use or understand the module can easily find the relevant information.
00:03:01.360
Now let's transition to Packwerk. Packwerk is a gem that allows you to define which parts of your module are meant to be used by others. Furthermore, you can specify who these others are. For example, you might dictate that your tax use case is permitted to interact with the `Tax` module, but disallow the support use case to prevent unwanted coupling.
00:03:10.560
Packwerk also enables you to structure your application into layers. You can specify that only upper layers are allowed to communicate with lower layers, or that outer layers may interact with inner layers. Once you've defined these rules, Packwerk can verify compliance. This verification can also occur within your continuous integration (CI) setup.
00:03:36.720
Packwerk, developed by Shopify, is well-maintained. It offers a to-do list feature similar to RuboCop, allowing you to define rules, analyze your code, and generate a checklist of items. Known rule violations will be ignored by the checker, allowing you to continue your work. Should you introduce new violations, your checker will alert you. Additionally, you can address issues at your own pace, enabling a gradual improvement process.
00:04:22.880
There is much more to discover with Packwerk, including tools like visualizers that can generate diagrams of your application's module structure. Today, we have reviewed two tools: `private_constant`, a Ruby built-in that can be implemented immediately, and Packwerk, which requires more setup but offers greater capabilities.
00:04:45.240
Here are my contact details. We have a booth in the back where you can join us for a chat and say hi. Have fun building modularized monoliths!