{"pageProps":{"topic":{"name":"Clean Architecture","description":null,"guide":"software-development","slug":"clean-architecture","path":"/dist/src/content/articles/topics/clean-architecture.json"},"thoughts":[{"title":{"html":"

Ways of approaching Clean Architecture

","plain":"Ways of approaching Clean Architecture"},"excerpt":{"html":"

In which I ask questions about the ways that a team might approach Clean Architecture in a way you can still benefit from the productivity of a framework.

","plain":"In which I ask questions about the ways that a team might approach Clean Architecture in a way you can still benefit from the productivity of a framework."},"slug":"ways-of-approaching-clean-architecture","tags":["Clean Architecture"],"publishedAt":{"pretty":"20th December 2019","iso":"2019-12-20T00:00:00.000+00:00"},"content":{"html":"

In which I ask questions about the ways that a team might approach Clean Architecture in a way you can still benefit from the productivity of a framework.

\n

Many approach Clean Architecture as an all or nothing approach. You are either architecting your system(s) that way, or you aren't. I agree up to a certain point in that you can quickly stop benefitting from Clean Architecture if you ignore it's boundaries which can particularly be an issue in dynamic languages like Ruby.

\n

Where I disagree is in the opposite direction when Clean Architecture can push your domain so far from the delivery mechanism, say the Ruby on Rails framework, to the point you can no longer benefit from the Rails ecosystem. Worse still I see teams starting without a framework altogether, taking a HTTP routing library such as Sinatra, and then over time end up adding framework features into it like ActiveRecord but gain none of the benefits of Rails development speed and gem ecosystem.

\n

Throwing the framework out with the bath water

\n

An example I see in the wild is where you can no longer benefit from Rails view helpers like form_with because you either used Sinatra, or you've hidden your ActiveRecord or database DAOs so far away from your controllers you can't inject them into your views to use with form_with.

\n

There are bigger examples too, such as losing the ability use gems such as Devise for authentication in your application, and not being able to use Paperclip or these days ActiveStorage, and creating your own queuing drivers rather than using ActiveJob. The list goes on, and it drives me crazy because folks don't know what they're missing in productivity! More experienced with Clean Architecture and generalist programmer practices we miss the community-specific learnings and wisdom that may exist within a particular ecosystem like Rails.

\n

To quote myself or maybe Danny Dyer, "it does my absolute nut in" to see such learnings from a community overlooked. It's no ones fault of course, empathy for all, but it seems like institutional memory loss in my mind. What a waste.

\n

A middle way

\n

I believe there is a path that sits between the all or nothing approaches of both pure framework versus pure Clean Architecture. There has to be. I ask myself a lot of questions around this, I certainly don't have all the answers.

\n

How might you approach Clean Architecture progressively where you use it in particularly complex areas of your application? Should ATDD start directly in your lib/ far away from your app/ in a Rails application? Or could it start with a feature test, and then a request test, and then dive into a use case unit test? How fragile would your application be in that scenario?

\n

How might you adopt Clean Architecture in a way that you can benefit from Devise, ActiveStorage and ActiveJob?

\n

Discipline required

\n

How do you maintain a discipline to know when you move from Rails CRUD into Clean Architecture? Or more still, how do you even know when to use one or the other?

\n

These are ongoing questions I ask myself, and our team at Made Tech. Our Rails Working Group is actively looking at how we can bridge the gap, engaging Clean Architecture with joy as Rails developers, and engaging with Rails community wisdom as generalist XP professionals.

\n

Stay tuned for more! I also recently wrote about why you might want to adopt Clean Architecture in a Rails application.

","plain":"In which I ask questions about the ways that a team might approach Clean Architecture in a way you can still benefit from the productivity of a framework.\nMany approach Clean Architecture as an all or nothing approach. You are either architecting your system(s) that way, or you aren't. I agree up to a certain point in that you can quickly stop benefitting from Clean Architecture if you ignore it's boundaries which can particularly be an issue in dynamic languages like Ruby.\nWhere I disagree is in the opposite direction when Clean Architecture can push your domain so far from the delivery mechanism, say the Ruby on Rails framework, to the point you can no longer benefit from the Rails ecosystem. Worse still I see teams starting without a framework altogether, taking a HTTP routing library such as Sinatra, and then over time end up adding framework features into it like ActiveRecord but gain none of the benefits of Rails development speed and gem ecosystem.\nThrowing the framework out with the bath water\nAn example I see in the wild is where you can no longer benefit from Rails view helpers like form_with because you either used Sinatra, or you've hidden your ActiveRecord or database DAOs so far away from your controllers you can't inject them into your views to use with form_with.\nThere are bigger examples too, such as losing the ability use gems such as Devise for authentication in your application, and not being able to use Paperclip or these days ActiveStorage, and creating your own queuing drivers rather than using ActiveJob. The list goes on, and it drives me crazy because folks don't know what they're missing in productivity! More experienced with Clean Architecture and generalist programmer practices we miss the community-specific learnings and wisdom that may exist within a particular ecosystem like Rails.\nTo quote myself or maybe Danny Dyer, "it does my absolute nut in" to see such learnings from a community overlooked. It's no ones fault of course, empathy for all, but it seems like institutional memory loss in my mind. What a waste.\nA middle way\nI believe there is a path that sits between the all or nothing approaches of both pure framework versus pure Clean Architecture. There has to be. I ask myself a lot of questions around this, I certainly don't have all the answers.\nHow might you approach Clean Architecture progressively where you use it in particularly complex areas of your application? Should ATDD start directly in your lib/ far away from your app/ in a Rails application? Or could it start with a feature test, and then a request test, and then dive into a use case unit test? How fragile would your application be in that scenario?\nHow might you adopt Clean Architecture in a way that you can benefit from Devise, ActiveStorage and ActiveJob?\nDiscipline required\nHow do you maintain a discipline to know when you move from Rails CRUD into Clean Architecture? Or more still, how do you even know when to use one or the other?\nThese are ongoing questions I ask myself, and our team at Made Tech. Our Rails Working Group is actively looking at how we can bridge the gap, engaging Clean Architecture with joy as Rails developers, and engaging with Rails community wisdom as generalist XP professionals.\nStay tuned for more! I also recently wrote about why you might want to adopt Clean Architecture in a Rails application."}},{"title":{"html":"

Why take a Clean Architecture approach to Rails?

","plain":"Why take a Clean Architecture approach to Rails?"},"excerpt":{"html":"

On the reasoning why and how you might use a Clean Architecture approach in Rails applications. Warning: it's nuanced and full of compromise.

","plain":"On the reasoning why and how you might use a Clean Architecture approach in Rails applications. Warning: it's nuanced and full of compromise."},"slug":"why-take-a-clean-architecture-approach-to-rails","tags":["Clean Architecture","Ruby on Rails"],"publishedAt":{"pretty":"18th December 2019","iso":"2019-12-18T00:00:00.000+00:00"},"content":{"html":"

On the reasoning why and how you might use a Clean Architecture approach in Rails applications. Warning: it's nuanced and full of compromise.

\n

A few years ago I was introduced to the concept of Clean Architecture. When I saw it something clicked in my brain. Before Clean Architecture I chose to remove logic from controllers and models of applications I built into Plain Old Ruby Objects (POROs). While I maintained some consistency across projects, my approach to architecting and testing these POROs varied more often than not and it often felt like I was reinventing the wheel.

\n

Before Clean Architecture: Services

\n

The POROs were usually placed into a directory like app/services and called Service Objects or just Services. The Service Object pattern involves the creation classes that represent business logic or behaviour that would otherwise sit too close to the the database in an ActiveRecord model or in the controller.

\n

After having a little google I found references going as far back as 2012 including a blog post on "the service layer [that] lies between controllers and models" and a RailsCasts video on using Service Objects in Rails.

\n

This pattern is probably the most common Rails pattern for keeping controllers and models skinny though it remains decidedly non-standard by Rails creator DHH.

\n
\n

It's like we have a J2EE renaissance fair going on at the moment. Digging up every discredited pattern of complexity to do a reunion tour.

\n
\n

Haha, I laughed at that one. He was still hurting from his time as a Java developer when he tweeted that I suspect.

\n
\n

It's given birth to some truly horrendous monstrosities of architecture. A dense jungle of service objects, command patterns, and worse.

\n
\n

Yup, that is the author of Rails' view of service objects. He don't like 'em much does he? He also doesn't like TDD. YMMV.

\n

I think it's okay for the Rails author to not support a common idiom within the community, his mileage did vary. We have to have empathy for differing views in a complex world.

\n

DHH was right about one thing though: lumping the Service Object and Command pattern together. You'll find the most commonly touted approach to services in Rails is to name them as verbs and have a common public method like #run, #call, #execute or #exec. This isn't the Service Object pattern in reality – it's the Command pattern as mentioned by Martin Fowler.

\n

Introducing Clean Architecture: Even further from pure-Rails

\n

Okay so how about Clean Architecture? I've certainly seen "by the book" Clean Architecture applied to Rails applications. Some teams love it! In this pure adoption you will usually find application and enterprise business rules in the lib/ directory of a Rails app rather than app/. You will also find directories named domain/ or entities/, interactions/ or use_cases/, and gateways/ or adapters/ in lib/.

\n

I've also seen teams of Ruby on Rails developers completely reject Clean Architecture. They already have their idioms for this problem! Something didn't click in their brains like it did in mine. This was clearly a stretch too far from the Rails way.

\n

Again, empathy for all, everyone can have view that differ. For me I found the concept of breaking down business rules into entities, use cases and adapters a fairer split of labour than simply lifting and shifting controller code into a single service object. That said, in many cases where an application is made up of (mostly) simple CRUD, this extra layer of complexity wasn't needed at all.

\n

The world isn't as simple as always using one pattern or another. Sure it's easier to teach one way, rather than the nuances of many, but knowing and being able to argue the tradeoffs with yourself is the real wisdom.

\n

Introducing Clean Architecture: Services (and other friends)

\n

This world of nuance has led me to take a more compromising view on the adoption of Clean Architecture in the Rails world – when it makes sense to use Clean Architecture at all.

\n

A more friendly approach for Rails developers is to use more Rails idioms. There are plenty of idioms that match up with the entity, use case and gateway classes from Clean Architecture.

\n

The Services convention in Rails clearly matches that of use case classes that represent actions a user can make on a system. This especially rings true for me when taking the Command pattern approach to Services which is the same convention I see used in Clean Architecture use cases. Just put your use cases in app/services!

\n

Entities are use to represent enterprise-level business rules. Code that will likely be shared across use cases and business functions. These need only introducing when you want to share behaviour between use cases, or when you want to abstract your use cases from the database and the ActiveRecord pattern. There are plenty of libraries including ActiveModel that provide helpers to make the definition of these classes easier. You may need to debate with your team whether these can sit beside database representations in app/models or whether you split them out into app/domains.

\n

Adapters are already known to Rails developers as the Adapter pattern is rife there too. Plenty of applications have adapters for connecting to external APIs or databases. These can go in app/adapters.

\n

So you see, Clean Architecture isn't actually a million miles away from being idiomatic to Rails developers. Sure it's full of compromise, and is probably only worth it when your application is complex enough. We have to learn these nuances and know when to compromise to deliver value for our users and organisations.

","plain":"On the reasoning why and how you might use a Clean Architecture approach in Rails applications. Warning: it's nuanced and full of compromise.\nA few years ago I was introduced to the concept of Clean Architecture. When I saw it something clicked in my brain. Before Clean Architecture I chose to remove logic from controllers and models of applications I built into Plain Old Ruby Objects (POROs). While I maintained some consistency across projects, my approach to architecting and testing these POROs varied more often than not and it often felt like I was reinventing the wheel.\nBefore Clean Architecture: Services\nThe POROs were usually placed into a directory like app/services and called Service Objects or just Services. The Service Object pattern involves the creation classes that represent business logic or behaviour that would otherwise sit too close to the the database in an ActiveRecord model or in the controller.\nAfter having a little google I found references going as far back as 2012 including a blog post on "the service layer [that] lies between controllers and models" and a RailsCasts video on using Service Objects in Rails.\nThis pattern is probably the most common Rails pattern for keeping controllers and models skinny though it remains decidedly non-standard by Rails creator DHH.\n\nIt's like we have a J2EE renaissance fair going on at the moment. Digging up every discredited pattern of complexity to do a reunion tour.\n\nHaha, I laughed at that one. He was still hurting from his time as a Java developer when he tweeted that I suspect.\n\nIt's given birth to some truly horrendous monstrosities of architecture. A dense jungle of service objects, command patterns, and worse.\n\nYup, that is the author of Rails' view of service objects. He don't like 'em much does he? He also doesn't like TDD. YMMV.\nI think it's okay for the Rails author to not support a common idiom within the community, his mileage did vary. We have to have empathy for differing views in a complex world.\nDHH was right about one thing though: lumping the Service Object and Command pattern together. You'll find the most commonly touted approach to services in Rails is to name them as verbs and have a common public method like #run, #call, #execute or #exec. This isn't the Service Object pattern in reality – it's the Command pattern as mentioned by Martin Fowler.\nIntroducing Clean Architecture: Even further from pure-Rails\nOkay so how about Clean Architecture? I've certainly seen "by the book" Clean Architecture applied to Rails applications. Some teams love it! In this pure adoption you will usually find application and enterprise business rules in the lib/ directory of a Rails app rather than app/. You will also find directories named domain/ or entities/, interactions/ or use_cases/, and gateways/ or adapters/ in lib/.\nI've also seen teams of Ruby on Rails developers completely reject Clean Architecture. They already have their idioms for this problem! Something didn't click in their brains like it did in mine. This was clearly a stretch too far from the Rails way.\nAgain, empathy for all, everyone can have view that differ. For me I found the concept of breaking down business rules into entities, use cases and adapters a fairer split of labour than simply lifting and shifting controller code into a single service object. That said, in many cases where an application is made up of (mostly) simple CRUD, this extra layer of complexity wasn't needed at all.\nThe world isn't as simple as always using one pattern or another. Sure it's easier to teach one way, rather than the nuances of many, but knowing and being able to argue the tradeoffs with yourself is the real wisdom.\nIntroducing Clean Architecture: Services (and other friends)\nThis world of nuance has led me to take a more compromising view on the adoption of Clean Architecture in the Rails world – when it makes sense to use Clean Architecture at all.\nA more friendly approach for Rails developers is to use more Rails idioms. There are plenty of idioms that match up with the entity, use case and gateway classes from Clean Architecture.\nThe Services convention in Rails clearly matches that of use case classes that represent actions a user can make on a system. This especially rings true for me when taking the Command pattern approach to Services which is the same convention I see used in Clean Architecture use cases. Just put your use cases in app/services!\nEntities are use to represent enterprise-level business rules. Code that will likely be shared across use cases and business functions. These need only introducing when you want to share behaviour between use cases, or when you want to abstract your use cases from the database and the ActiveRecord pattern. There are plenty of libraries including ActiveModel that provide helpers to make the definition of these classes easier. You may need to debate with your team whether these can sit beside database representations in app/models or whether you split them out into app/domains.\nAdapters are already known to Rails developers as the Adapter pattern is rife there too. Plenty of applications have adapters for connecting to external APIs or databases. These can go in app/adapters.\nSo you see, Clean Architecture isn't actually a million miles away from being idiomatic to Rails developers. Sure it's full of compromise, and is probably only worth it when your application is complex enough. We have to learn these nuances and know when to compromise to deliver value for our users and organisations."}},{"title":{"html":"

Nuances in Clean Architecture

","plain":"Nuances in Clean Architecture"},"excerpt":{"html":"

In which I try to untangle the differences in Clean Architecture implementations.

","plain":"In which I try to untangle the differences in Clean Architecture implementations."},"slug":"nuances-in-clean-architecture","tags":["Clean Architecture"],"publishedAt":{"pretty":"14th December 2019","iso":"2019-12-14T00:00:00.000+00:00"},"content":{"html":"

In which I try to untangle the differences in Clean Architecture implementations.

\n

Clean Architecture has seen some popularity as an approach to architecting complex code bases but inevitably has been interpreted in many and often conflicting ways. I wanted to get my head around this particularly as I've been refreshing my Java recently and have come across a number of differences in Clean Architecture implementations. This article is my attempt to list a number of differences I've spotted in the wild.

\n

These differences aren't in any particular order and certainly aren't numbered. What? Did you think this was a listicle?

\n

Presenters versus returned values

\n

So if you learned Clean Architecture from it's creator then you will likely be familiar with the idea of presenters in the overall control flow. The idea being while a framework controller will construct a use case request model to inject into a use case, it does not receive the use case response model at all. Instead, a presenter already injected into the use case is given a response model, at a time the use case determines.

\n

In this directors-cut interpretation of Clean Architecture, the controller is ignorant of the shape of a response model and is never tempted to even peak into it. The controller simply makes a request and then takes it easy.

\n

\"\"

\n

When researching this I came across a brilliant question and response on StackExchange that summarises the "official" stance on why injected presenters should be used over returning response model.

\n

In response to the question author's suggestion that it's more favourable for the controller to marry the use case and a presenter, rather than the use case knowing about the presenter directly, the responder quickly asserts:

\n
\n

That's certainly not Clean, Onion, or Hexagonal Architecture.

\n
\n

I like the passion for defending a canonical interpretation but I'm not really sure how it's helpful to someone trying to make sense of it all.

\n

The responder then goes onto suggesting one should read up on the Dependency Inversion Principle and Command Query Responsibility Segregation without offering any real explanation of their importance.

\n
\n

The problem here is now whatever knows how to ask for the data has to also be the thing that accepts the data.

\n
\n

And why is that a problem I asked myself?

\n
\n

Yes! Telling, not asking, will help keep this object oriented rather than procedural.

\n
\n

And why is OO better than procedural?

\n
\n

The point of making sure the inner layers don't know about the outer layers is that we can remove, replace, or refactor the outer layers confident that doing so wont break anything in the inner layers. What they don't know about won't hurt them. If we can do that we can change the outer ones to whatever we want.

\n
\n

This made the most sense to me, "what they don't know about won't hurt them". I suppose the argument is the controller only cares about firing off the request and never handles the response, it does one job and is therefore simpler and easier to maintain.

\n

My introduction to Clean Architecture was not from reading a book or an "official" blog post. A colleague of mine ran a showcase and later coached me on their interpretation. This interpretation completely missed the idea of presenters altogether, or at least if they did talk about presenters, I didn't retain that information.

\n

It seems many others have also overlooked this detail, blissfully unaware of the unorthodoxy of their approach. I suppose "what they don't know about won't hurt them" too?

\n

In a C# introduction of Clean Architecture the author happily introduces their readers to the concept of a use case receiving a request and returning a response. What filth. Their example also included a presenter, however it was quite separate from the use case, they passed the response from the use case into the presenter within the console runner. Scandal!

\n

To be honest, going back to the StackExchange response on this topic, I like the summary at the end of the lengthy answer:

\n
\n

Anything that works is viable. But I wouldn't say that the second option you presented faithfully follows Clean Architecture. It might be something that works. But it's not what Clean Architecture asks for.

\n
\n

What works, works, right?

\n

Use of request and response models

\n

Request and response models are the layers of abstraction that separate your business logic from the outside world. They translate a request from a delivery mechanism or framework into language a use case understands and then a response is constructed and interpreted by a presentation layer. At no point, is a domain entity exposed.

\n

I asked myself a question early on in my exposure to Clean Architecture. If my response looks like my domain entity why am I mapping the domain into a response? It's unnecessary complexity and indirection right? I'm not the only one, a questioner on StackOverflow asked why could the domain entity not be used as the request? Clever, I like the way your brain works internet person!

\n

Sadly, enforcers of the one true clean way responded crushing the questioners spirit and mine in one fell swoop suggesting Clean Architecture could never be so fragile:

\n
\n

How could Clean Architecture possibly force rigidity and fragility? Defining an architecture is all about: how to take care widely of fundamental OOP principles such as SOLID and others…

\n
\n

Aight. You're entitled to strongly held beliefs I suppose. The responder then bashes more wikipedia links on the question authors head, this time to the Law of Demeter. Enforcers sure do like to call upon theory.

\n

Luckily, we weren't the only ones. A recent article introducing an approach to Clean Architecture for Java 11 described use cases directly returning domain objects.

\n

What do I really think? By doing this you are certainly introducing fragility to your code base if you let your use cases expose domain entities to the wider world. Is that a problem? It depends on your context. I suppose it also depends on your willingness and discipline to add new layers of indirection when your application calls for it.

\n

I can certainly see an argument for just following the rulebook, it's simpler to teach and simpler to be consistent. That said, it's clearly a tradeoff for simpler contexts.

\n

Use of the command pattern

\n

The command pattern states that you expose a method that does stuff. Usually you will find the method called execute(), exec() or run(). This means that you can describe your application in a series of commands, all of which are called in the same way but each doing something different under the hood.

\n

You can see why the command pattern translates quite well to the use case pattern, particularly if you're making sure your use cases do one thing.

\n

That said, I've found no orthodox view on the use of the command pattern. In fact I've found a good mix of examples where use cases do more than one thing.

\n

In the Slalom post previously mentioned, the example has multiple public methods in the FindUser use case, both findById() and findAllUsers() rather than a single execute().

\n

In another example, this time in golang, I found the use cases provided a number of public methods that interact on the concept of a user object. For me, this means you end up defining use cases around nouns rather than verbs, which means they can end up doing too much. The issue with use cases doing too much is that they are harder to maintain because they are harder to understand. It also means that your directory of use cases no longer describe the things a user can do with the application, which for me was one of the selling points of Clean Architecture over MVC.

\n

You certainly do find the command pattern in use for use cases though. The C# article uses a Response Handle(Request) method.

\n

At Made Tech we certainly recommend the command pattern and you can see it in use in many of our public sector work streams.

\n

I like the idea of a use case being linked to a single action. I like the way it forces you to decompose your application into small enough chunks and your directory structure describes what your application does. Your mileage may vary however.

\n

Directory structure and packages

\n

Talking of directory structures there are many interpretations and also how far you go to separate your delivery mechanism or framework from your domain and use cases.

\n

The pattern we most often use at Made Tech is making sure we have separated our Clean Architecture code from our delivery mechanism. A common case for us is making sure Rails and our Clean Architecture are separated by keeping our Rails code in app/ and our use cases, domains and gateways in lib/. The GovWifi project is a clear example of this.

\n

I've noticed elsewhere, particularly in languages that like to structure code as packages like Java and C#, you find domain, use cases, adapters and frameworks all in separate packages. The Slalom post certainly favoured this approach.

\n

You then find everything in between. I can see the advantage of using enforceable package boundaries particularly with tools like Jigsaw in Java that allow you to keep implementation details hidden from the various layers of your application. This is much harder in Ruby and other dynamic languages where you have a vague idea of namespacing but everything ultimately runs in a global space. At this point the directory structure is your only defence which is why you see the separation of code into app/ and lib/ in Rails applications.

\n

The naming of things

\n

As I've been writing this article I've noticed all kinds of interchangeable language. Instead of discussing the naming of things, as the old adage suggests its one of our hardest problems as coders, I'll provide a few lists of synonyms instead and I'll let you interpret them as you will.

\n

\"\"

\n

Frameworks and drivers

\n

Frameworks and drivers represent the outside world. They are the outer layer.

\n

Types of frameworks and drivers: Delivery Mechanism, Framework, Database, UI, Web, Program, Console Runner

\n

Interface Adapters

\n

The implementation detail of connecting your business rules with the outside world.

\n

Types of Interface Adapters: Gateways, Repositories, Presenters, Controllers

\n

Application Business Rules

\n

The code that describes what your application does.

\n

Types of Application Business Rules: Use Cases, Interactors, Actions

\n

This layer also provides Ports, also know as Input/Ouputs Ports or Request/Response Models. These are the inputs and outputs of use cases.

\n

Enterprise Business Rules

\n

The code that represents the nouns of your organisation.

\n

Types of Enterprise Business Rules: Entities, Domains, Models, Records

\n

What to make of these nuances?

\n

I'm not sure what to make of it all. Clearly there are different strokes for different folks. People will interpret however they will. The best way you can equip yourself for such a non-uniform universe is to understand the variations in the use of Clean Architecture and begin to reason when certain approaches may work over others.

\n

You'll never 100% get it. People will disagree with you. That's okay, haters gonna hate. Just make sure you are empathetic to others and be open minded.

","plain":"In which I try to untangle the differences in Clean Architecture implementations.\nClean Architecture has seen some popularity as an approach to architecting complex code bases but inevitably has been interpreted in many and often conflicting ways. I wanted to get my head around this particularly as I've been refreshing my Java recently and have come across a number of differences in Clean Architecture implementations. This article is my attempt to list a number of differences I've spotted in the wild.\nThese differences aren't in any particular order and certainly aren't numbered. What? Did you think this was a listicle?\nPresenters versus returned values\nSo if you learned Clean Architecture from it's creator then you will likely be familiar with the idea of presenters in the overall control flow. The idea being while a framework controller will construct a use case request model to inject into a use case, it does not receive the use case response model at all. Instead, a presenter already injected into the use case is given a response model, at a time the use case determines.\nIn this directors-cut interpretation of Clean Architecture, the controller is ignorant of the shape of a response model and is never tempted to even peak into it. The controller simply makes a request and then takes it easy.\n\nWhen researching this I came across a brilliant question and response on StackExchange that summarises the "official" stance on why injected presenters should be used over returning response model.\nIn response to the question author's suggestion that it's more favourable for the controller to marry the use case and a presenter, rather than the use case knowing about the presenter directly, the responder quickly asserts:\n\nThat's certainly not Clean, Onion, or Hexagonal Architecture.\n\nI like the passion for defending a canonical interpretation but I'm not really sure how it's helpful to someone trying to make sense of it all.\nThe responder then goes onto suggesting one should read up on the Dependency Inversion Principle and Command Query Responsibility Segregation without offering any real explanation of their importance.\n\nThe problem here is now whatever knows how to ask for the data has to also be the thing that accepts the data.\n\nAnd why is that a problem I asked myself?\n\nYes! Telling, not asking, will help keep this object oriented rather than procedural.\n\nAnd why is OO better than procedural?\n\nThe point of making sure the inner layers don't know about the outer layers is that we can remove, replace, or refactor the outer layers confident that doing so wont break anything in the inner layers. What they don't know about won't hurt them. If we can do that we can change the outer ones to whatever we want.\n\nThis made the most sense to me, "what they don't know about won't hurt them". I suppose the argument is the controller only cares about firing off the request and never handles the response, it does one job and is therefore simpler and easier to maintain.\nMy introduction to Clean Architecture was not from reading a book or an "official" blog post. A colleague of mine ran a showcase and later coached me on their interpretation. This interpretation completely missed the idea of presenters altogether, or at least if they did talk about presenters, I didn't retain that information.\nIt seems many others have also overlooked this detail, blissfully unaware of the unorthodoxy of their approach. I suppose "what they don't know about won't hurt them" too?\nIn a C# introduction of Clean Architecture the author happily introduces their readers to the concept of a use case receiving a request and returning a response. What filth. Their example also included a presenter, however it was quite separate from the use case, they passed the response from the use case into the presenter within the console runner. Scandal!\nTo be honest, going back to the StackExchange response on this topic, I like the summary at the end of the lengthy answer:\n\nAnything that works is viable. But I wouldn't say that the second option you presented faithfully follows Clean Architecture. It might be something that works. But it's not what Clean Architecture asks for.\n\nWhat works, works, right?\nUse of request and response models\nRequest and response models are the layers of abstraction that separate your business logic from the outside world. They translate a request from a delivery mechanism or framework into language a use case understands and then a response is constructed and interpreted by a presentation layer. At no point, is a domain entity exposed.\nI asked myself a question early on in my exposure to Clean Architecture. If my response looks like my domain entity why am I mapping the domain into a response? It's unnecessary complexity and indirection right? I'm not the only one, a questioner on StackOverflow asked why could the domain entity not be used as the request? Clever, I like the way your brain works internet person!\nSadly, enforcers of the one true clean way responded crushing the questioners spirit and mine in one fell swoop suggesting Clean Architecture could never be so fragile:\n\nHow could Clean Architecture possibly force rigidity and fragility? Defining an architecture is all about: how to take care widely of fundamental OOP principles such as SOLID and others…\n\nAight. You're entitled to strongly held beliefs I suppose. The responder then bashes more wikipedia links on the question authors head, this time to the Law of Demeter. Enforcers sure do like to call upon theory.\nLuckily, we weren't the only ones. A recent article introducing an approach to Clean Architecture for Java 11 described use cases directly returning domain objects.\nWhat do I really think? By doing this you are certainly introducing fragility to your code base if you let your use cases expose domain entities to the wider world. Is that a problem? It depends on your context. I suppose it also depends on your willingness and discipline to add new layers of indirection when your application calls for it.\nI can certainly see an argument for just following the rulebook, it's simpler to teach and simpler to be consistent. That said, it's clearly a tradeoff for simpler contexts.\nUse of the command pattern\nThe command pattern states that you expose a method that does stuff. Usually you will find the method called execute(), exec() or run(). This means that you can describe your application in a series of commands, all of which are called in the same way but each doing something different under the hood.\nYou can see why the command pattern translates quite well to the use case pattern, particularly if you're making sure your use cases do one thing.\nThat said, I've found no orthodox view on the use of the command pattern. In fact I've found a good mix of examples where use cases do more than one thing.\nIn the Slalom post previously mentioned, the example has multiple public methods in the FindUser use case, both findById() and findAllUsers() rather than a single execute().\nIn another example, this time in golang, I found the use cases provided a number of public methods that interact on the concept of a user object. For me, this means you end up defining use cases around nouns rather than verbs, which means they can end up doing too much. The issue with use cases doing too much is that they are harder to maintain because they are harder to understand. It also means that your directory of use cases no longer describe the things a user can do with the application, which for me was one of the selling points of Clean Architecture over MVC.\nYou certainly do find the command pattern in use for use cases though. The C# article uses a Response Handle(Request) method.\nAt Made Tech we certainly recommend the command pattern and you can see it in use in many of our public sector work streams.\nI like the idea of a use case being linked to a single action. I like the way it forces you to decompose your application into small enough chunks and your directory structure describes what your application does. Your mileage may vary however.\nDirectory structure and packages\nTalking of directory structures there are many interpretations and also how far you go to separate your delivery mechanism or framework from your domain and use cases.\nThe pattern we most often use at Made Tech is making sure we have separated our Clean Architecture code from our delivery mechanism. A common case for us is making sure Rails and our Clean Architecture are separated by keeping our Rails code in app/ and our use cases, domains and gateways in lib/. The GovWifi project is a clear example of this.\nI've noticed elsewhere, particularly in languages that like to structure code as packages like Java and C#, you find domain, use cases, adapters and frameworks all in separate packages. The Slalom post certainly favoured this approach.\nYou then find everything in between. I can see the advantage of using enforceable package boundaries particularly with tools like Jigsaw in Java that allow you to keep implementation details hidden from the various layers of your application. This is much harder in Ruby and other dynamic languages where you have a vague idea of namespacing but everything ultimately runs in a global space. At this point the directory structure is your only defence which is why you see the separation of code into app/ and lib/ in Rails applications.\nThe naming of things\nAs I've been writing this article I've noticed all kinds of interchangeable language. Instead of discussing the naming of things, as the old adage suggests its one of our hardest problems as coders, I'll provide a few lists of synonyms instead and I'll let you interpret them as you will.\n\nFrameworks and drivers\nFrameworks and drivers represent the outside world. They are the outer layer.\nTypes of frameworks and drivers: Delivery Mechanism, Framework, Database, UI, Web, Program, Console Runner\nInterface Adapters\nThe implementation detail of connecting your business rules with the outside world.\nTypes of Interface Adapters: Gateways, Repositories, Presenters, Controllers\nApplication Business Rules\nThe code that describes what your application does.\nTypes of Application Business Rules: Use Cases, Interactors, Actions\nThis layer also provides Ports, also know as Input/Ouputs Ports or Request/Response Models. These are the inputs and outputs of use cases.\nEnterprise Business Rules\nThe code that represents the nouns of your organisation.\nTypes of Enterprise Business Rules: Entities, Domains, Models, Records\nWhat to make of these nuances?\nI'm not sure what to make of it all. Clearly there are different strokes for different folks. People will interpret however they will. The best way you can equip yourself for such a non-uniform universe is to understand the variations in the use of Clean Architecture and begin to reason when certain approaches may work over others.\nYou'll never 100% get it. People will disagree with you. That's okay, haters gonna hate. Just make sure you are empathetic to others and be open minded."}},{"title":{"html":"

Decoupling the delivery mechanism

","plain":"Decoupling the delivery mechanism"},"excerpt":{"html":"

On the trouble you can encounter when trying to separate your domain logic from a framework like Rails.

","plain":"On the trouble you can encounter when trying to separate your domain logic from a framework like Rails."},"slug":"decoupling-the-delivery-mechanism","tags":["Clean Architecture","Ruby on Rails"],"publishedAt":{"pretty":"11th August 2018","iso":"2018-08-11T00:00:00.000+00:00"},"content":{"html":"

On the trouble you can encounter when trying to separate your domain logic from a framework like Rails.

\n

If you work with Rails and haven't heard of Clean Architecture you may have heard of Hexagonal Architecture and most probably have heard of the Service Object pattern. These patterns seek to keep your controllers and models skinny by using Plain Old Ruby Objects (POROs) to model domain problems. If you do not know these patterns, I suggest you read up a little to understand the context in which this article is written.

\n

\"Clean

\n

When exploring concepts like Clean Architecture in a Rails context it's often tempting to cut corners. Perhaps rather than using test doubles for Rails dependencies inside your library code you decide to depend on them directly.

\n\n\n

In the example above we now have a direct dependency on the Rails model Ship and also on the database itself. This means slower tests as they hit the DB and also means the system is harder to change as if you change your model you'll need to change this test too.

\n

Or maybe you decided to use your model as a gateway rather than create a PORO adapter class to encapsulate the model.

\n\n\n

Here we have another direct dependency on Rails and the database. Again slower tests and your library needs to change when your application changes.

\n

Or you thought you could return models from your gateways and treat it like a domain object.

\n\n\n

Finally in this example we return an ActiveRecord model from the gateway and therefore expose a large interface to the wider application. The problem here is that method calls to the Ship model could trigger SQL queries meaning control of database performance is spread through the codebase rather than solely managed by gateways. This again makes the system harder to reason about and harder to change.

\n

The problem with doing any of this is that you no longer have a library that represents your business logic independent of Rails, that is easy to test and easy to change. Instead you a left with a contrived and non-standard Rails setup that is harder to test and difficult to change. It would have been better to stay omakase.

\n

Your library should not depend on Rails

\n

If running rspec spec/unit/lib requires you to load rails_helper.rb you've already fallen fowl of coupling your library to Rails. Allow me to apologise for the lack of information out there that might have helped you avoid this situation. At this point you have one of two options:

\n
    \n
  1. Find a way not to depend on rails_helper.rb
  2. \n
  3. Move your library code back into the app/ directory and keep to a more standard omakase approach
  4. \n
\n

There's a more general rule here too that goes beyond Clean Architecture and Rails. Your library code should not depend on any delivery mechanism, database, or API. There should be no need to depend on database fixtures, factories or depend on framework or database classes being defined. This rule exists to make change cheap in the future.

\n

Of course, you will likely have acceptance and feature tests that will depend on rails_helper.rb and that's okay. You want to test when delivering your library via Rails that everything works in harmony. This will only be a certain percentage of your tests. Remember the testing pyramid?

\n

\"The

\n

As a rule the unit tests for your library, usually found in spec/unit/lib, should not need to depend on Rails.

\n

Mocking out ActiveRecord in your gateway unit tests

\n

In example one we saw the gateway specs relying on Rails for setting up database state. We can avoid this by using RSpec's class_double and instance_double.

\n\n\n

The test remains largely the same except that there is no direct dependency on Rails this time. We add another test, 'retrieves ship from model', to ensure that we call the mock as expected, this replaces the need to rely on the state of the database.

\n

Mocking out gateways in your use case unit tests

\n

In example two we saw a use case using an ActiveRecord model directly as a gateway. Not only this but the spec directly depended on the model and database state via FactoryBot.

\n\n\n

Instead of using ActiveRecord as the gateway we instead rely on an adapter gateway Space::Flight::ShipGateway. We go even further by not directly depending on the gateway and instead use instance_double to mock it out. This approach decouples the use case from ActiveRecord resulting in a spec that doesn't touch the database.

\n

Avoid returning ActiveRecord models from your gateways

\n

In example three Space::Flight::ShipGateway returns an ActiveRecord model from it's #find_by_id method. We really should have the discipline to return a domain object from the gateway instead.

\n\n\n

Here we define Space::Flight::Ship a domain object that exposes a limited amount a functions compared to an ActiveRecord model. Our gateway constructs this domain object and returns it.

\n

Discipline as a software engineer

\n

It takes discipline as a software engineer to keep interfaces clean between the various layers of your application. This is especially true in Ruby where interfaces do not exist as part of it's OOP implementation.

\n

Discipline and experience leads to good architecture.

\n
\n

Good architecture makes the system easy to understand, easy to develop, easy to maintain, and easy to deploy.\nClean Architecture by Robert C. Martin

\n
","plain":"On the trouble you can encounter when trying to separate your domain logic from a framework like Rails.\nIf you work with Rails and haven't heard of Clean Architecture you may have heard of Hexagonal Architecture and most probably have heard of the Service Object pattern. These patterns seek to keep your controllers and models skinny by using Plain Old Ruby Objects (POROs) to model domain problems. If you do not know these patterns, I suggest you read up a little to understand the context in which this article is written.\n\nWhen exploring concepts like Clean Architecture in a Rails context it's often tempting to cut corners. Perhaps rather than using test doubles for Rails dependencies inside your library code you decide to depend on them directly.\n\n\nIn the example above we now have a direct dependency on the Rails model Ship and also on the database itself. This means slower tests as they hit the DB and also means the system is harder to change as if you change your model you'll need to change this test too.\nOr maybe you decided to use your model as a gateway rather than create a PORO adapter class to encapsulate the model.\n\n\nHere we have another direct dependency on Rails and the database. Again slower tests and your library needs to change when your application changes.\nOr you thought you could return models from your gateways and treat it like a domain object.\n\n\nFinally in this example we return an ActiveRecord model from the gateway and therefore expose a large interface to the wider application. The problem here is that method calls to the Ship model could trigger SQL queries meaning control of database performance is spread through the codebase rather than solely managed by gateways. This again makes the system harder to reason about and harder to change.\nThe problem with doing any of this is that you no longer have a library that represents your business logic independent of Rails, that is easy to test and easy to change. Instead you a left with a contrived and non-standard Rails setup that is harder to test and difficult to change. It would have been better to stay omakase.\nYour library should not depend on Rails\nIf running rspec spec/unit/lib requires you to load rails_helper.rb you've already fallen fowl of coupling your library to Rails. Allow me to apologise for the lack of information out there that might have helped you avoid this situation. At this point you have one of two options:\n\nFind a way not to depend on rails_helper.rb\nMove your library code back into the app/ directory and keep to a more standard omakase approach\n\nThere's a more general rule here too that goes beyond Clean Architecture and Rails. Your library code should not depend on any delivery mechanism, database, or API. There should be no need to depend on database fixtures, factories or depend on framework or database classes being defined. This rule exists to make change cheap in the future.\nOf course, you will likely have acceptance and feature tests that will depend on rails_helper.rb and that's okay. You want to test when delivering your library via Rails that everything works in harmony. This will only be a certain percentage of your tests. Remember the testing pyramid?\n\nAs a rule the unit tests for your library, usually found in spec/unit/lib, should not need to depend on Rails.\nMocking out ActiveRecord in your gateway unit tests\nIn example one we saw the gateway specs relying on Rails for setting up database state. We can avoid this by using RSpec's class_double and instance_double.\n\n\nThe test remains largely the same except that there is no direct dependency on Rails this time. We add another test, 'retrieves ship from model', to ensure that we call the mock as expected, this replaces the need to rely on the state of the database.\nMocking out gateways in your use case unit tests\nIn example two we saw a use case using an ActiveRecord model directly as a gateway. Not only this but the spec directly depended on the model and database state via FactoryBot.\n\n\nInstead of using ActiveRecord as the gateway we instead rely on an adapter gateway Space::Flight::ShipGateway. We go even further by not directly depending on the gateway and instead use instance_double to mock it out. This approach decouples the use case from ActiveRecord resulting in a spec that doesn't touch the database.\nAvoid returning ActiveRecord models from your gateways\nIn example three Space::Flight::ShipGateway returns an ActiveRecord model from it's #find_by_id method. We really should have the discipline to return a domain object from the gateway instead.\n\n\nHere we define Space::Flight::Ship a domain object that exposes a limited amount a functions compared to an ActiveRecord model. Our gateway constructs this domain object and returns it.\nDiscipline as a software engineer\nIt takes discipline as a software engineer to keep interfaces clean between the various layers of your application. This is especially true in Ruby where interfaces do not exist as part of it's OOP implementation.\nDiscipline and experience leads to good architecture.\n\nGood architecture makes the system easy to understand, easy to develop, easy to maintain, and easy to deploy.\nClean Architecture by Robert C. Martin\n"}}]},"__N_SSG":true}