Posted on by & filed under Content - Highlights and Reviews, Programming & Development.

A guest post by Ben Keeping, a freelance developer based in the UK, specializing in applications written in .NET and Ruby, using lean and agile techniques. He can be contacted @benkeeping.

As the popularity of Ruby and Ruby on Rails increases, many developers are crossing over from languages such as C#. This post will look at some of the challenges and benefits of crossing over, and some examples of how working with Ruby may influence how you code in C#.

One of the biggest changes when learning Ruby from a C# background is code architecture – or lack of it in Ruby applications. That’s not to say that Ruby code doesn’t have any thought or care to its development, or that its all tightly coupled spaghetti code. It means that you tend to be able to write more with less in Ruby.

A Comparison Between Model-View-Controller Frameworks

One of the most common frameworks in C# is ASP.NET MVC (referred to as ‘MVC’ from here), so we’ll compare a common architectural pattern of an MVC website with a Ruby on Rails website. Bear in mind that MVC was strongly influenced by Rails, which was one of the original Model-View-Controller web frameworks, so they are good candidates for a comparison.

As an example, imagine a website that lists products that are available to order from Acme Ltd.

C# developers that adhere to design principles such as SOLID, separation of concerns, and finite layers may often end up with an architecture such as this:

This is a common pattern for MVC applications.

The controller is responsible for receiving input from the web page’s view, and then hands off control to a service layer, which in turn hands control to the data access layer, which then performs the actual load of the domain model’s products.

By the time you’ve introduced all of the corresponding interfaces that are often introduced (IProductService, IProductRepository) you’re looking at 6 or 7 classes/interfaces.

In contrast, the architecture in a Rails application is similar in theory, but the implementation is often simpler:

Rails websites don’t usually have service layers, nor do they have explicit data access layers in the form that you see in C#, such as the repository pattern. The controllers tend to interact directly with the model, and without interfaces. Note that I mean interfaces here as the C# interface keyword that ensures a contract through type safety.

Application Layers Can Lead to Overly Abstracted Code

There’s lots of reasons why Rails tends to have less code than MVC sites, but I think the main reason is that Rail’s use of the active record patten, which is built into the models by the framework, tends to push domain logic into the models rather than in the repository or service layer, which is often where you see it in C#.

As an example, the below code is fairly common for C#. It searches for orders previously made by a user in the last 6 months:

So a lot of logic is going on in the service and repository layers, and not much on the domain – which is probably looking a bit like a data transfer object.

In contrast, the code in Rails would look more like:

The Rails code has less layers, and the controller works more directly with the model, which manages the domain logic. Because of this, the approach that Rails takes could be considered easier to understand and maintain. The Rails code embraces the idea of Model-View-Controller, rather than attempting to abstract away the business logic into a layered architecture.

Abstraction isn’t Always a Good Thing

One thing that C# developers may feel uncomfortable with is that Rails ties you to a clear data access pattern, by mixing the persistence knowledge into the models via active record.

The use of scopes, and has_many directives means that your models understand about how they are persisted. C# developers have long been told to make sure your domain layer is decoupled from your data access / persistence layer – which I think is why on the whole, C# developers tend to use the repository pattern over the active record pattern.

The thinking behind that is you could swap out you’re data access layer without affecting your domain model. Or maybe move from NHibernate to the Entity Framework (EF) without affecting your domain.

I’m not sure these concerns really matter that much anymore. If you think about it, when was the last time you moved your codebase from using one database technology to another (i.e., move from SQL Server to Mongo)? Or stopped using NHibernate and started using EF?

When was the last time you used your domain model except in the website/services that it was written to support?

If you did move from a SQL based solution to a NoSQL solution, would your domain hold up anyway? When you think about it – your domain is probably pretty geared up to be used by Object-Relational Mappings (ORM)s and relational databases, rather than document based NoSQL solutions – if that was how it was originally intended.

Application Boundaries Don’t Need Typed Interfaces

Another issue that may make C# developers uncomfortable is the lack of interfaces (in the manner of how C# uses an interface to ensure type safety at compilation). A lot of C# code relies on enforcing behavioral boundaries by coding to these typed interfaces. Again, for years we’ve been told that this is the best way to ensure our applications are loosely coupled.

I think by using Ruby, and realizing that you can’t use interfaces in the way you would in C#, you realize that a codebase can be loosely coupled and cohesive without a specific language  tool (i.e., the typed interface in C#). Note that in Ruby, as a dynamic language, an application’s interface is typically enforced using tests and specifications rather than a compiler.

This ensures that the application’s behavior is correct, rather than the assumption that it compiles correctly.

In my experience, most typed interfaces in C# applications tend to have single implementations. That’s not loose coupling, that’s just more code than you need, and I’d rather have tests around interface behavior, rather than typed interfaces.

Summary

Crossing over from C# to Ruby has altered how I think about C#. Do I really need a typed interface here? Is my domain model anaemic? Do I even need a service layer at all? That’s the great thing about polyglot programming though – experimenting with different languages tends to widen your perspective about programming in general.

For more details about C# and Ruby, see the ebooks referenced below.

Not a subscriber? Sign up for a free trial.

Safari Books Online has the content you need

Practical Object-Oriented Design in Ruby: An Agile Primer will guide you to superior outcomes, whatever your previous Ruby experience. Novice Ruby programmers will find specific rules to live by; intermediate Ruby programmers will find valuable principles they can flexibly interpret and apply; and advanced Ruby programmers will find a common language they can use to lead development and guide their colleagues.
Eloquent Ruby starts small, answering tactical questions focused on a single statement, method, test, or bug. You’ll learn how to write code that actually looks like Ruby (not Java); why Ruby has so many control structures; how to use strings, expressions, and symbols; and what dynamic typing is really good for.
Fluent C# is a true tutorial that helps you build effective working models for understanding a large and complex subject: developing .NET Framework applications with C#. Unlike so-called “tutorials” that merely describe the material briefly, and offer an “exercise” that merely requires typing in already-provided source code, this book’s carefully paced exercises closely align with the brain’s natural learning processes. You will discover the material yourself- and absorb it more rapidly and effectively.
Essential C# 5.0 is a well-organized, no-fluff guide to the latest versions of C# for programmers at all levels of C# experience. Fully updated to reflect new features and programming patterns introduced with C# 5.0 and .NET 4.5, this guide shows you how to write C# code that is simple, powerful, robust, secure, and maintainable. Microsoft MVP Mark Michaelis and C# principal developer Eric Lippert provide comprehensive coverage of the entire language, offering a complete foundation for effective software development.

About the author

Ben Keeping is a freelance developer based in the UK. He currently specializes in applications written in .NET and Ruby, using lean and agile techniques. He can be contacted @benkeeping.

Tags: ASP.NET MVC, C#, EF, Entity Framework, Mongo, MVC, NHibernate, NoSQL, Rails, Ruby, SQL Server,

Comments are closed.