

DCI and Decoupling Business Logic from Ruby on Rails Part 1 - rubyskills
http://lancecarlson.github.com/2012/05/15/dci-and-decoupling-business-logic-from-ruby-on-rails.html

======
lucisferre
I've been applying DCI with my team for the past few months and have found it
allows for much greater flexibility in design. We can keep our classes small
and cohesive and in turn we find the code easier to understand in a lot of
ways. Specifically, the fact that design can be driven by scenarios centered
around the contexts gives a clear flow of logic from the controller to the
domain.

In a lot of ways DCI will almost seem a bit like having a meta-MVC within your
MVC application. I like to think of it as a MVC-like pattern for the domain,
decoupling your domain from the infrastructure of the web-tier.

If you are unfamiliar with DCI, I'd recommend checking out the Oredev videos
where it was first introduced:

<http://vimeo.com/8235574>

<http://vimeo.com/8235394>

Also Jim Gray is currently working on a book (I've pre-ordered and get the
chapters as they are being written) <http://clean-ruby.com/>

~~~
rubyskills
I'm not sure I can consider it a meta MVC pattern however. They way I use it
is a completely separate pattern in a completely different application.

By decoupling the business layer from the delivery mechanism (the web), I can
use DCI as a pattern the effectively organizes my business application and use
MVC specifically for my display/web application. Although, the MVC pattern
sort of breaks down when you abstract out your business layer and your
infrastructure layers. It turns into something more like VC where your
controllers interact with your interactors and push the data to the views
depending on the interactor logic.

------
typicalrunt
This is an interesting approach.

One change I would make is in the testing of the lib directory. I've found it
best to separate the testing of the lib directory contents from the unit and
functional tests that are baked into Rails. It requires a bit of custom setup,
but it's easy to reuse in other applications.

1\. Create a test/lib directory

2\. Create a lib/tasks/test_libs.rake file

3\. Put the following into the Rake file[1]:

    
    
        namespace :test do
          desc "Test libraries"
          Rake::TestTask.new(:libs) do |t|
            t.libs << "test"
            t.pattern = 'test/lib/**/*_test.rb'
            t.verbose = false
          end
        end
    
        lib_task = Rake::Task["test:libs"]
        test_task = Rake::Task[:test]
        test_task.enhance { lib_task.invoke }
    

4\. Run `rake test:libs` to test just your lib directory.

[1] Credit goes to <http://stackoverflow.com/a/1588496> for this Rake task.

~~~
rubyskills
Just to be clear, the code inside of the lib and test directories is not
actually inside of our rails application. They're inside of a different git
repository and are packed as a separate gem. It makes more sense to me once
you've isolated the code this way that you would then write "use case tests"
and then role tests (which I haven't gotten into yet.. next post :))

------
dgregd
Does anybody else see similarity between this

    
    
      authenticate = SApp::AuthenticateUser.authenticate(...
      action = authenticate.action
      if action != :login_error
        redirect_to "/#{action}"
      ...
      def find_account
        @account = SApp::FindAccount.find(@account_subdomain)
      end
    

and this <http://en.wikipedia.org/wiki/Inner-platform_effect>
<http://thedailywtf.com/Articles/Soft_Coding.aspx>

~~~
rubyskills
Do you have any better way of approaching this?

I mainly posted code examples to show the general idea of what I'm trying to
describe. My actual code base has a lot of logic locked behind the
authentication and which action to take after the user is authenticated (there
are about 4 different places they could land).

4 other use cases are then discovered in the underlying app depending on which
action they are taken to.

~~~
dgregd
> Do you have any better way of approaching this?

No, but frankly speaking I don't get the idea from the keynote speech.

2012 and there are no example apps of that concept. I don't get it.

