Learn Clean Code

So you can write code that works, more or less, kind of, on a good day and when nothing unexpected happens. There are a lot of developers, aspiring developers, and even amatuer hobbyists who can do that. What you’ll find here is a collection of resources to help you make the jump from functional spaghetti to clean, robust, efficient code.

If you just want to sharpen up in spare time here and there, try one of the many Weekly Iteration episodes aimed at better code. Those with a little more time (or a more serious desire to create squeaky clean, high quality code) can dive into the Refactoring trail, which is a whole series of detailed tutorials on this topic.

Trails

Clean Code

Refactoring

Refactoring is improving the quality of code without changing its behavior. Refactoring often is one key to keeping development speed high.

?

Refactoring is improving the quality of code without changing its behavior. Refactoring often is one key to keeping development speed high.

11 hours
Next Up

Explaining Variable

Learn how to simplify a method by breaking it down using explaining variables.

Unstarted

Replace Variable with Query

Learn to replace variables with query methods.

Unstarted

Extract Method

Extracting methods makes complicated code clearer and encourages re-use. It also also encourages you to name a collection of operations, which tends to improve readability.

Unstarted

Extract Class

Learn how to safely split up classes in small steps.

Unstarted

Null Object: Part One

Learn to encapsulate logic surrounding nil by introducing Null Object classes.

Unstarted

Null Object: Part Two

Take your Null Object skills to the next level by completing this additional exercise.

Unstarted

Extract Value Object

Learn how to simplify a class by extracting a value object.

Unstarted

Introduce Parameter Object

Learn how to replace a long list of parameters with a single parameter object.

Unstarted

Extract Validator

Learn how to extract a validator into its own class with this exercise.

Unstarted

Cleaning up a Controller

Slim down a controller that's gotten a bit bloated.

Unstarted

Replace Conditional with Polymorphism

Learn how you can interact with entities of different types by replacing conditionals with polymorphism.

11 steps remaining
Visit trail

The Weekly Iteration

Hosted by

Joe Ferris and Gabe Berke-Williams

Joe Ferris
Gabe Berke-Williams

Joe and Gabe review form objects, and explain why they can almost always replace accepts_nested_attributes_for. See an example Rails app written with nested attributes and how and why we recommend switching to form objects. Nested Attributes...

Hosted by

Joe Ferris and Melissa Xie

Joe Ferris
Melissa Xie

Show notes: Melissa joins Joe once again to demonstrate another refactoring technique from Ruby Science: move method. Learn about Feature Envy, how to reveal it using Extract Method, and how to remove it using Move Method. Follow along yourself...

Hosted by

Joe Ferris and Melanie Gilman

Joe Ferris
Melanie Gilman

Melanie joins Joe to demonstrate a simple (but useful) pattern: Parameter Objects. Melanie replaces a long parameter list with one object in a single bound! Try it for yourself in our refactoring trail.

Hosted by

Joe Ferris and Melanie Gilman

Joe Ferris
Melanie Gilman

Show notes: Melanie joins Joe again to discuss the classic refactoring step: Extract Class. Learn how to safely split up a Large Class in small steps, keeping your tests green as much as possible while Melanie demonstrates this technique live....

Hosted by

Joe Ferris and Melissa Xie

Joe Ferris
Melissa Xie

Melissa joins Joe to discuss a basic refactoring technique: Extract Method. Follow along as Melissa applies this refactoring live to an example from Ruby Science. After watching, you can refine your refactoring techniques using our refactoring...

Hosted by

Chris Toomey and Joe Ferris

Chris Toomey
Joe Ferris

In this episode, Chris is joined by thoughtbot CTO Joe Ferris. With the magic of live-coding, Joe demonstrates how a simple Extract Class refactoring can lead to a host of code improvements.

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

Ben and Joe compare a number of code samples and compare solutions written using both inheritance and composition. Learn how to use composition to place an emphasis on objects and flexible runtime state.

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

Ben and Joe discuss the dos and (mostly) don'ts when it comes to ActiveRecord callbacks. You'll find out why you're generally better off not using this feature, with several suggestions for better alternatives.

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

In this episode, Joe and Ben look at a class which was written without using TDD. By rewriting it with tests first, we discover that a new class was waiting to be extracted, making the overall solution clearer.

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

How do functional program and object-oriented programming stack up in Ruby? In this episode, Ben and Joe dive find out. We've put together a number of code samples, each of which follows an object-oriented, functional, or hybrid approach. We'll...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

Ben and Joe follow up on a previous episode on extracting classes to demonstrate the classic followup punch to Extract Class: Invert Control. They show the previous example in the context of an integration-tested Rails application, and...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

In this episode, Ben and Joe discuss value objects. You can learn more about value objects in Ruby Science, or on Martin Fowler's blog. You might also want to try you hand at our Extract Value Object exercise on the Refactoring Trail.

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

This episode covers the D in SOLID, the Dependency Inversion Principle (DIP). In it, you'll learn why you might want to inject a class' dependencies and how to do so. Additionally, we'll show how following this principle makes it easier to follow...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

Take a tour through the history of dependency management in statically compiled languages. Learn why languages like C++ and Java need to explicitly build up small interfaces where Ruby is saved by duck typing, and then discover the lessons Ruby...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

Ben and Joe tackle the third principle in SOLID: the Liskov Substitution Principle. Learn some basic rules you can apply to subclasses and other "is a" relationships to improve flexibility in your applications and reduce subtle bugs from interface...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

In this episode, Ben and Joe discuss the Open Closed Principle. Also mentioned was polymorphism, the composite design pattern, decorators, factory method, and chain of responsibility. Finally, you might be interested in the immutable data...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

Ben and Joe cover "S" from SOLID, which stands for "Single Responsibility Principle," often abbreviated as "SRP." We show examples of why you might choose to obey this principle, as well as how the principle relates to [cohesion], Tell, Don't...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

Ben and Joe discuss Joe's recommendations for RSpec best practices. You can read Joe's original blog post, peruse our style guide's testing section, or review our summarized best practices for RSpec. You might also want to read about the mystery...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

Ben and Joe do a little live coding, demonstrating how to extract a Null Object from an existing class in order to encapsulate conditional logic related to nothingness. If you'd like to play along, we have two exercises for practicing Null...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

The Law of Demeter.

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

In this video, Ben and Joe illustrate the steps to safely extracting new classes. You'll learn a reliable, repeatable process for creating new classes and moving functionality into them without risking bugs in your application or failures in your...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

In this episode, Ben and Joe tackle a highly useful but lesser known method from Ruby's Enumerable module: inject. While watching, you'll see how inject is just an abstraction over certain types of recursion. We'll use examples to demonstrate...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

In this episode, Ben and Joe discuss the an OO design principle known as Tell Don't Ask. They walk through a number of examples, discuss its subtleties when using MVC, and cover query and command methods. Original blog post PragProg blog post on...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

In this episode, Ben and Joe refactor some code submitted by a subscriber in our forum. Starting with a controller action containing complex business logic adding up to more than fifty lines, they extract a class to encapsulate that logic, using...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

In this episode, Joe and Ben discuss a fairly advanced example of refactoring. You'll dive into the good, the bad, and the ugly of code before and after being rewritten. The new code uses a number of design patterns, including the Builder...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

In this episode, Ben and Joe discuss several different types of coupling in code. While watching, you'll learn about three different types of coupling: Pathological Coupling, Global Coupling, and Control Coupling. You'll learn what these...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

In this episode, Ben and Joe discuss why abusing nil is unfriendly to your fellow developers, and dive into some of the other ways of representing nothingness. While watching, you'll learn how nil can be contagious, confuse a domain, and violate...

Hosted by

Ben Orenstein and Joe Ferris

Ben Orenstein
Joe Ferris

Joe and Ben introduce a concept from the functional world: Functors. Learn how you're using functors in your every day work already, and see how to apply those concepts to make code with nils safer. Check out Learn You a Haskell For Great Good...

Hosted by

Chris Toomey and Ben Orenstein

Chris Toomey
Ben Orenstein

Recently, we ran a group-coding app-building contest for Upcase subscribers. In this video, Ben and Chris review each of the submissions, both highlighting great aspects and suggesting some areas for improvement. Live code review at its finest!

Hosted by

Chris Toomey and Ian C. Anderson

Chris Toomey
Ian C. Anderson

Keyword arguments allow us to write code that is both more expressive, and more flexible. Tune in as Ian and Chris dive into some of the more subtle aspects and demonstrate how we can use keyword args to produce clear, reliable code.

Hosted by

Ian C. Anderson and Chris Toomey

Ian C. Anderson
Chris Toomey

As developers, naming is our most powerful tool to make our code understandable. It's an essential part of refactoring. Learning what to pull out, and what to name it, makes our code more maintainable. In this episode, you'll learn how to apply...

Hosted by

Tute Costa and Chris Toomey

Tute Costa
Chris Toomey

Join Tute Costa, the maintainer of thoughtbot's Paperclip gem, as he talks about how to be the best maintainer you can be, including how to quickly respond to issues and how to version your code.

Hosted by

Joel Quenneville and Chris Toomey

Joel Quenneville
Chris Toomey

If your application uses third-party APIs, it can be complicated to write good, flexible tests that don't depend on the service being present (or don't touch production data). In this Weekly Iteration, Joël Quenneville and Chris Toomey examine...

Hosted by

Chris Toomey and George Brocklehurst

Chris Toomey
George Brocklehurst

On this episode of The Weekly Iteration, George Brocklehurst, development director from thoughtbot's NYC office, joins us to take a tour of a handful of design patterns through the lens of the Django web framework. Specifically, we'll take a look...

Hosted by

Chris Toomey and Connie Chan

Chris Toomey
Connie Chan

Historically, developers and designers have reached for JavaScript to build certain presentational features such as animations and transitions. With modern CSS features, some of these capabilities can now be achieved with little to no JavaScript....

Hosted by

German Velasco and Joel Quenneville

German Velasco
Joel Quenneville

German & Joël talk about creating higher level data abstractions in Elixir.

Hosted by

Joel Quenneville and Stephanie Viccari

Joel Quenneville
Stephanie Viccari

Compilers are powerful helpers but they can only do so much with primitives. Joël and Stephanie fix a bug by introducing domain-specific types. Learn about how these encode real-world context, what are the downsides, and how some functional...