Ruby Hero Awards. Why Ruby Class Methods Resist Refactoring. One of the most common questions I received following my 7 Patterns to Refactor Fat ActiveRecord Models post was “Why are you using instances where class methods will do?”.
I’d like to address that. Simply put: I prefer object instances to class methods because class methods resist refactoring. To illustrate, let’s look at an example background job for syncing data to a third-party analytics service: The job iterates over each user sending a hash of attributes as an HTTP POST. The SyncToAnalyticsService.perform method is pretty complex. One solution would be to apply Extract Method a few times.
Design Patterns in the Wild: Null Object. I knocked out a pretty decent refactoring of some of the internals of Factory Girl this past weekend.
In one of my commits, I used the Null Object pattern to simplify some conditional logic that was spread across a class. What's the Null Object Pattern? The Null Object pattern describes the use of an object to define the concept of "null" behavior. Design for test vs. design for API – The Real Adam. How many design considerations are there in an almost trivial method?
Let’s look at two of them. Consider this code: def publish! Self.update_attributes(created_at: Time.now) end If you’ve been studying OO design and the SOLID principles, using TDD as a practice to guide you towards those ideas, there’s a missing piece here. Def publish! I suspect a lot of TDDers would instinctively write the above first, skipping the first version by force of habit. The strength of the second version is that it is designed for test. Dependency injection is not a virtue in Ruby (DHH) In languages less open than Ruby, hard-coded class references can make testing tough.
If your Java code has Date date = new Date(); buried in its guts, how do you set it to a known value you can then compare against in your tests? Well, you don't. So what you do instead is pass in the date as part of the parameters to your method. You inject the dependency on Date. What Dependency Injection Really Is - Naildrivin' ❺ Both DHH and Tim Bray make great points about “dependency injection” and its issues regarding Ruby and testing.
My colleague Adam Keys makes a similar point, though doesn’t call his anti-pattern “dependency injection”. The scare quotes are because neither DHH nor Tim are accurately representing the purpose of dependency injection. Dependency Injection is not about a framework, XML, factories, or testing. Single Responsibility Principle on Rails Explained. A few weeks back we had a small drama about SRP.
There were some smart comments, some stupid ones and a few funny jokes even, like that for example: If I remember correctly it all started with this post. Single Responsibility Principle and Rails - Naildrivin' ❺ Was reading the slides from Aaron Patterson’s Magma Rails talk and noticed some pretty innocuous Rails code that, upon further reflection is the beginning of disaster for a growing application.
As many other Rubyists are beginning to realize, spreading your application logic across only models and controllers leads to a mess. Let’s look at the code, understand why it’s bad, and create a better version. Here’s the code to create a new user and email them a welcome note: Simple enough, so what’s the problem? Tidy views and beyond with Decorators. The problem Here's a view serving monkeys#show.
What's wrong with it? <% if @monkey.eating? Decorators compared to Strategies, Composites, and Presenters. We've been paying closer attention lately to how we use design patterns in our Ruby on Rails work.
Decorators have emerged as one pattern that's helped us keep code ready for change. We've chosen our spots carefully, but it's proven useful quite often. Evaluating alternative Decorator implementations in Ruby. Recently, decorators have become a big part of my Ruby on Rails life.
We used them heavily in a recent client project, Harold Giménez wrote a great post about them, Avdi Grimm is writing about them in Objects on Rails, and Jeff Casimir has a great presentation about them. Until recently, I still had some questions, however, such as: Should I roll my own decorators? Composition over Mixins. This is not the first post cautioning the use of modules on our blog. However, while I do mostly agree with the points raised in Josh's blog, this is a different set of common mistakes I see when using modules. The use of include SomeModule leads to obfuscated code. Rather than being explicit with the boundaries between your behavior, you are creating "misdirection masquerading as abstraction. Modules called, they want their integrity back. Rather than including modules and hooking into .included, write a method that adds the behaviour (even if the method just includes and extends).
Introducing the pattern It's common practice in Ruby these days to use modules for all kinds of crazy. module IWishIWasAClass def self.included(klass) klass.send :include, InstanceMethods klass.extend ClassMethods end # ...end Here is the most eye-widening example I've seen. You might think you're getting one thing, but you're not, you're getting all the things.
Andrzej on Software: DCI and Rails, lessons learnt. I first learnt about DCI almost one year ago. After some research and experiments, we decided to try it in production projects. James Coplien - The DCI Architecture: Supporting the Agile Agenda. Benchmarking DCI in Ruby. I've recently become quite intrigued with the concepts behind DCI (Data Context and Interaction). I won't go too in depth about what DCI is or why you might use it, that's been discussed many times elsewhere. In short, DCI is an architecture which allows us to delineate our domain objects from the actual functions they perform. DCI: The King of the Open/Closed Principle. The open/closed principle (OCP) is a fundamental "run of thumb" in object-oriented languages. It has hands in proper inheritance, polymorphism, and encapsulation amongst other core properties of object-oriented programming. The open/closed principle says that we should refine classes to the point at which we eliminate churn.
In other words, the less times we need to open a file for modification, the better. With DCI, we can compose objects while still following OCP. Extension is Inheritance. Andrzej on Software: DCI and Rails. Why DCI Contexts? DCI with Ruby Refinements. Ruby Refinements landed in trunk - Posted by santiago.pastorino on August 03, 2012.
DCI Role Injection in Ruby. The Right Way to Code DCI in Ruby. Many articles found in the Ruby community largely oversimplify the use of DCI. These articles, including my own, highlight how DCI injects Roles into objects at runtime, the essence of the DCI architecture. DCI, Concerns and Readable Code. Our latest post comes from Giles Bowkett. Home · jruby/jruby Wiki. Bloggers — JRuby.org. JRuby Team The JRuby Team - Release announcements, news, conference dates, and other information go out through the JRuby Team Blog. Team Members.