- Display logic only goes in the view layer
- Never modify the DOM in View API
- App logic only goes in the controller layer
- Limit custom code in the controller
- Domain logic only goes in the model layer
- Server calls belong to the model layer
- Only cross layers going up (V -> C -> M)
- Never observe across layers
Blog
Tuesday, January 3, 2012
Some rules to remember when writing Ember.js code
Saturday, December 24, 2011
Your Rails Application is Missing a Domain Controller
The mantra of Skinny Controller, Fat Model reminds us to keep our business logic in our models, not in Rails Action Controllers. We know Action Controllers, sub-classes of ActionController::Base, are only responsible for delegating service requests to the domain layer. These models, which encapsulate this business logic, forming the domain layer, represent entities such as a person, place, event or thing. They are often, but not always, mapped directly to database tables through the inheritance of ActiveRecord::Base. When we develop our domain layer for our complex Rails application, purely with models representing entities, we encounter two problems:
Incoherent domain API
When Action Controllers interact with model entities directly, the API to the domain layer becomes clouded. It is unclear what services the domain layer offers and how the UI should request those services. Rail’s ActiveRecord exasperates the issue, for example, there are several ways to create and update model entities and their associations.
Bloated domain models
Business logic that is workflow-oriented involving multiple entities is assigned to a single entity, bloating it’s responsibilities. It becomes difficult to differentiate the entities in the domainrepresenting what the system is, from the use cases or workflow representing what the system does1.
The solution is a Domain Controller. A Domain Controller is responsible for co-ordinating service requests from your Rails Action Controllers. A Domain Controller can come in two flavours, a facade or a use case.
A clarification on terminology: Throughout this blog post I will refer to the typical Rails model as a Model Entity, meaning a model that represents a person, place, event or thing.
Facade Controller
A Facade Controller represents the overall system that encapsulates the domain layer. For example a Catalog object can act as facade for the domain layer containing taxonomies, taxons, product groups, products and variants.
Without the Facade Controller, our service requests to the domain typically look like this:
Product.active Taxon.active.find(1) Product.create(:name => 'Ruby Meta-Programming')
With a Facade Controller instance, in this case, a catalog object, service requests appear as the following, delegating to the appropriate Model Entities:
catalog.fetch_products catalog.fetch_taxon(1) catalog.create_product(:name => 'Ruby Meta-Programming')
The Facade Controller provides a clear, explicit interface into the catalog domain layer that a programmer can grok within seconds.
Use Case Controller
A Use Case Controller is useful for more complex workflows. They are also helpful when a Facade becomes bloated and you wish to split the incoming service requests across multiple Domain Controllers. It’s important to note, you can use more than one Domain Controller for your application.
Let’s look at an example. The code below represents the processing of a Payroll2. Often this type of workflow logic gets placed in a Model Entity that it doesn’t belong to or worst, left in a Rails Action Controller.
date = Date.today
employees = Employee.active
employees.each do |e|
if e.pay_date?(date)
pc = PayCheck.new(e.calculate_pay(date))
e.send_pay(pc)
end
end
So what object is responsible for this workflow logic? We know a Rails Action Controller isn’t a candidate. Its responsibility is to handle HTTP requests and delegate to the domain layer. Neither the models Employee or PayCheck are valid candidates. They represents the entities in our domain layer. Therefore we, require a new object PayDayService to encapsulate the logic, a Use Case Controller.
class PayDayService
def initialize(date=Date.now)
@date = date
end
def call
Employee.active.each do |e|
if e.pay_date?(@date)
pc = PayCheck.new(e.calculate_pay(@date))
e.send_pay(pc)
end
end
end
end
The benefit of this approach is that we have encapsulated this workflow logic without bloating existing Model Entities and allows the reuse of this logic in different contexts.
Domain Controllers in a Rails Application
When an application has multiple Domain Controllers I place them in a dedicated directory under app called services to keep them separate from the Model entities in app/models. This helps communicate that Rails Action Controllers should delegate to the Domain Controllers, not directly to Model Entities. The Domain Controllers and Model Entities together, represent the domain layer of the system. I have also discussed extracting the entire domain layer from the Rails framework, but that’s another discussion. Let’s keep this blog post civil for now!
I hope the Domain Controller pattern provides you with another tool for modelling your domain, reduces the coupling with the UI, and provides a clean API to your application logic.
Further Reading
If you are interested in learning more about Domain Controllers and Services, check out the following resources:
- Applying UML and Patterns by Craig Larman. Craig includes the Controller pattern as one of the General Responsibility Assignment Software Patterns or Principles (Grasp).
- Architecture the Lost Years a presentation by Robert Martin discusses modelling your application using Interactors and Entities. Interactors_ (which I have used the name Domain Controller) contain application specific logic, and Entities (which I have use the term Model Entities) contains application independent logic. Martin choses to use the term Interactors over Controllers to avoid confusing with Model-View-Controller (MVC). I prefer to use Domain Controller or Service to differentiate from Rails Action Controllers as I just can’t get my head around the term Interactors.
- Object-Oriented Software Engineering—A Use Case Driven Approach by Ivar Jacobson introduced the concept of interface, entity (Model Entity) and control (Domain Controller) objects over two decades ago. Robert Martin often refers to Ivar Jacobson when discussing application architecture.
- Patterns of Enterprise Application Architecture by Martin Flower discusses the concept of a “Service Layer” to give the domain layer an explicit API.
- Domain Driven Design by Eric Evans. Evans discusses the concept of Services for when “some concepts from the domain aren’t natural to model as objects”.
Footnotes:
- “What-the-system-is” and “What-the-system-does” terminology is from the book Lean Architecture by James O. Coplien and Gertrud Bjørnvig.
- Logic based on the Payroll case study in Robert Martin’s Agile Software Development.
Wednesday, December 21, 2011
An Example using RSpec double, mock, and stub
This is a follow-up post for RSpec double, mock, and stub from earlier this year. A reader asked for an example code to illustrate the various double aliases in RSpec.
For this example we will spec a Transfer class that encapsulates the use case of transferring an amount between two accounts, the source account and destination account. The Transfer is the subject of our examples, while the source and destination accounts are the collaborators.
In the spec below, the first example "should decrease source amount by 10", specifies the interaction for the source account, hence the use of the mock to generate the test double. In this example, the destination account is treated as a secondary collaborator, as we are focusing on the role of the source account. Any object can play the role of the source account, as long as it responds to the #decrease method.
In the second example "should increase destination account by 10", the destination account is the primary collaborator. The use of mock to generate the source account communicates this intent.
describe Transfer do
context "transfer with amount of 10" do
it "should decrease source account by 10" do
source_account = mock('source account')
destination_account = stub('destination_account').as_null_object
source_account.should_receive('decrease').with(10)
transfer = Transfer.new(source_account, destination_account, 10)
transfer.call
end
it "should increase destination account by 10" do
source_account = stub('source account').as_null_object
destination_account = mock('destination_account')
destination_account.should_receive('increase').with(10)
transfer = Transfer.new(source_account, destination_account, 10)
transfer.call
end
end
end
However, there is some duplication in this spec which can be eliminated by moving the test doubles to let blocks. It's appropriate to use double here to generate the source and destination accounts as both play primary and secondary collaborators in the following examples. Below we stub the methods for each collaborator, then set expectations on those methods for the appropriate examples.
describe Transfer do
context "transfer with amount of 10" do
let(:source_account) { double('source account', :decrease => nil) }
let(:destination_account) { double('destination_account', :increase => nil) }
it "should decrease source account by 10" do
source_account.should_receive('decrease').with(10)
transfer = Transfer.new(source_account, destination_account, 10)
transfer.call
end
it "should increase destination account by 10" do
destination_account.should_receive('increase').with(10)
transfer = Transfer.new(source_account, destination_account, 10)
transfer.call
end
end
end
Update: Radoslav Stankov provides a cleaner refactoring of the spec.
The implementation of the transfer class may look something like this:
class Transfer
def initialize(source_account, destination_account, amount)
@source_account = source_account
@destination_account = destination_account
@amount = amount
end
def call
# In a complete implementation, it would make sense to have the following
# lines wrapped in a transaction, but I wanted to keep this example simple
#
@source_account.decrease(amount)
@destination_account.increase(amount)
end
end
It's important to remember that double, mock, and stub all return an instance of RSpec::Mocks::Mock. While the concepts of mocking, (i.e. setting a method expectation), and stubbing are "method-level concepts"[1], the use of mock and stub can communicate which collaborator you are specifying the behaviour for.
[1] For a more complete discussion on this, checkout The RSpec Book.
Recent Launch: Yellow Bird Project Redesign
Earlier this year, I upgraded the Yellow Bird Project, a Spree store, from a forked version pre v0.90.0 to v0.50.x. For for my final project of the year, I upgraded Yellow Bird Project to v0.70.x, along with the implementation of a UI redesign. Jenna Holcombe (Dynamo) did a great job moving the YBP look to a grid-based design, which Daniel Wright (Dynamo) implemented this in Sass/Compass.
Since the redesign initiative included an upgrade to the latest version of Spree, I decided to upgrade the existing site and deploy that to production, before launching the redesign. This allowed me to upgrade our custom extensions to work with 0.70.x and iron out any kinks in the new version. While this was a smoother process than the upgrade earlier this year, it was the first time I had deployed to Heroku's Cedar stack using Rails 3.1 and the asset pipeline. I'm a big advocate of breaking down a project, separating major changes, and getting changes pushed to production early, even it there is a little duplication in work. The separate pushes to production for the upgrade and the redesign reduced the risk of something really going haywire with pushing both of these at once.
The redesign benefited the application from a platform, merchandising, and coding perspectives:
- Platform: While this initiative did not include a mobile version, the new grid-based design will allow us to cleanly develop a responsive design for mobile platforms in the future using media queries. Replacing hacks like Cufon with more modern technologies like web fonts just makes the UI code cleaner and performance snappier.
- Merchandising: The store now fully utilizes Spree's powerful Taxonomy and Product Group features. This allows YBP to respond to different marketing initiates such as seasonal events, for example Warm Winter Wear.
- Code: One of the cool things with this upgrade was the chance to refactor the code base. Shifting from ERB to Haml and plain CSS to Sass/Compass was a definitely a plus, however implementing a data model that capitalized Spree's catalog management was the biggest win. I was able to remove unnecessary extensions which simplified managing the products. YBP's Matthew Stotland is a code-savvy lad and appreciated the clean implementation. It's great to work on a project where the client appreciates the front-end as much as the code that drives it.
You can checkout the new design below, but better yet, visit the Yellow Bird Project and support a great cause.


Thursday, November 17, 2011
Software Craftsmanship Goes Beyond Code
Often the discussion of Software Craftsmanship is focused on code and tests. But don't forget about the other components that support your project:
- Make sure your source control repository is organized. Don't leave dead branches lying around, left for another developer to work out if they have been merged or not; if they should be merged or not. Add a reference to your branch with the issue or story id from your tracker so a developer can read more about the intention of the branch.
- And don't write commit messages that suck.
- Keep your tracker up-to-date and lean. Don't mark stories as started when they haven't been. In reality, there should only be one story marked as started per developer on the project. Don't drag stories into the backlog just because you think they are a good idea. Keep the backlog lean, you only need a couple of weeks worth of stories to keep you going. Keep the rest in the icebox. Priorities are going to change.
- Make sure it's easy for a developer to get started with your project. Have a README that guides a developer to get the dependencies and database setup, and remind them a test suite exists and how to run it. Obviously the more automated things are the better.
Caring needs to go beyond the code, it needs to include all the supporting components of your project. Of course there are other facets of professionalism we can list, but these are some practical details I have experienced recently. What components of a project, beyond code, that you wish developers would give more care to? Let me know in the comments.
Saturday, November 12, 2011
Recent Launch: Mr. B's Gentlemen's Boutique for ALDO
Back in September, I had the pleasure working with Alex Nemroff (Interactive Designer) and Daniel Wright (Front-end Developer) at Dynamo on Mr. B's Gentlemen's Boutique, a new product line for ALDO Shoes. A tribute to Aldo Bensadoun, this project is dear to everybody's hearts at ALDO and I think we have made them proud. I was responsible for the setup and customizations to Refinery CMS, including the development of an extension to manage the catalog.
I always have a great timing working on projects Alex leads. He always gets us involved in all aspects of the project and the end result really does feel like a team effort. My favourite times throughout the project is sitting down together at the end of an iteration, reviewing what we have done, and what we can do to improve it in the next iteration. And it doesn't hurt to have a power house like Daniel on the front-end. He really knows his stuff.
Below is a video of the post-mortem at Dynamo, where Alex and myself talk about lessons learned throughout project. Unfortunately, we didn't capture the screen when recording this session (whoops, working on that), but I think you will find the discussion insightful. Please checkout the screenshots below, better yet, visit the site and checkout some beautiful shoes.
Post-Mortem at Dynamo
Screenshots


Saturday, October 22, 2011
Rails is Not Your Application
Background: The Beginnings of My Obsession with Application Architecture and Domain Modelling
Last year I was involved in my most complex Ruby on Rails application to date that is now 23K lines of model code, 14K lines of controller code, and 4.5K lines of lib code. You get the point, let's now worry about the view code. It was during this project that I observed the pain of working within the bounds of how we typically build Rails applications. Did I mention it was slow to develop and test? During that contract and ever since, I have been obsessing about application architecture and domain modelling.
Establish an Application Interface with a Service Layer
During the time I was working on said application, I introduced the concept of Services (in the early stages I called them managers). Although a lot of domain logic was pushed into the models, there was too much application logic in the controllers. Services, co-ordinating domain models, allowed me to extract that application logic to really keep the controllers thin. I'm not sure exactly sure what prompted me to start using Service objects, but after the fact I found references to them in Martin Fowler's Patterns of Enterprise Application Architecture (P of EAA). Other frameworks such as Grails also use Services, it even has a generator for them. Services resolves the discussion (started here) on where to trigger email notifications. Add them to your Services.
In P of EAA, Randy Stafford defines the Service Layer as:
"Defines an application's boundary with a layer of services that establishes a set of available operations and coordinates the application's response in each operation."
And in a way, this definition helped me recognize another frustration I was having with how I (and most of the Rails community) was developing with Rails. There was no explicit application. Or rather, it was hard to define what the application was and hard to know how to interact with it. The application had no interface. My application was a ball of ActiveRecord objects.
Lots of Activity in the Rails Community Regarding Domain Modelling
I haven't been the only one thinking about application architecture and domain modelling. I'm not a unique snowflake. Others in our community have too: Mike Dietz from ThoughtWorks introduce me to DCI at RailsConf 2011, Andrzej Krzywda has been blogging about it before that, and Jim Gay has recently been blogging about it on this side of the pond. On another tact, Corey Haines has been been selling fast tests over the last few months. Hidden in that sales pitch of course, is a way to extract domain logic. Talking of extracting domain logic, Steve Klabnick has illustrated some practical examples.
These guys have kept me busy! I've been quietly researching this topic for over a year now. You can check out some of my tags on Delicious:
Extracting the Application from the Framework
Ok, time to finish up this post. All of the efforts describe above have been with the purpose of managing the application and domain logic in the software we build. It benefits us with faster tests and code that clearly communicates it's intent. And although the Service Layer was helping me define an interface to my application, I was only using them when my controllers methods/actions were getting heavy with application logic. Then last night, I watched the latest release of Clean Code from Uncle Bob that highlights the need to extract your application from the framework you use (he's been teasing me for a while on this topic). With my previous experience with Services, and my interest in DCI, Uncle Bob's guidance was the piece I was missing.
After taking his example pseudo code, and turning it into some Ruby/Rails example (more like snippet) I gleefully tweeted:
"Rails is not your application. It might be your views and data source, but it's not your application. Put your app in a Gem or under lib/."
I really like this approach a lot, the ability to test your application outside of the Rails stack is huge, and viewing Rails as a method to deliver my application will change the way I write code. Anyway here is the code that triggered the Tweet (see below). It's not polished, it doesn't execute, it's not 100% right, but boy it's got me thinking. It uses Services to represent Use Cases of the application, and roles containing domain logic that is mixed in contextually, extracted into a Gem, delivered via Rails. If you not a fan of the Gem idea, keep it name spaced under your lib directory.
Update: A clarification on putting your application in lib. I certainly don't mean to put it directly in lib. Name space it, lib/your_application; e.g. lib/pay_roll.
Now that I have let the code out of the bag, expect some more posts on this topic in the future where I work through and describe this code (and related ideas) in more detail.