RailsConf 2014

Workshop: Simplifying Code - Monster to Elegant in Less Than 5 steps

Workshop: Simplifying Code - Monster to Elegant in Less Than 5 steps

by Tute Costa

Workshop Summary: Simplifying Code: Monster to Elegant in Less Than 5 Steps

In the workshop led by Tute Costa at RailsConf 2014, attendees learned effective techniques for refactoring complex code into simpler, more maintainable formats. The session focused on identifying and addressing common software code issues, such as Fat Models and God Objects, through the application of well-known Refactoring Patterns.

Key Points Discussed:

  • Introduction to Refactoring: The presenter emphasized the significance of understanding refactoring rules and measurements for creating quality, maintainable code. This involved differentiating between aesthetics and code correctness in software development.
  • Workshop Objectives: Participants were encouraged to bring their complex code examples for transformation. The goal was to refactor this code, ensuring it remained operational during the changes to avoid productivity loss.
  • Refactoring Patterns: The workshop introduced four specific refactoring patterns, each aimed at simplifying code:
    • Intentional Revealing Method: This pattern focuses on renaming code segments to enhance readability, thereby reducing the need for comments.
    • Special Case Objects: Reduces the use of conditionals in code by replacing potential nil values with special objects that fulfill expected method calls.
    • Replace Method with Method Object: Helps manage lengthy methods by encapsulating behavior within new classes, thereby increasing code clarity and isolation.
    • Service Objects: A design pattern for organizing code by separating responsibilities. This avoids cluttering classes (like User) with too many responsibilities, thus following the single responsibility principle.
  • Real-World Application: Costa shared personal experiences from his work at a startup and general assembly, illustrating how refactoring positively influenced code maintainability and team productivity. He noted that refactoring enabled them to handle deployments more efficiently without halting feature development.
  • Practical Exercises: Attendees participated in hands-on exercises where they applied the refactoring patterns to sample code, allowing them to practice and see immediate improvements.
  • Guidance and Best Practices: The speaker encouraged following simple rules of thumb for better coding practices:
    • Methods should not exceed five lines.
    • Classes should contain no more than 100 lines.
    • Avoid excessive parameters.

Conclusion and Takeaways:

The workshop concluded with the importance of continuous refactoring and learning from software anomalies. Costa urged developers to become aware of their coding practices, seek improvements, and engage with the community to enhance their skills. He emphasized that good refactoring is not just about aesthetics; it fosters a common understanding of project goals within development teams and ultimately leads to more successful software solutions.

00:00:16.800 Okay, good morning! So, today we'll be learning all the rules you need to know to make your code very measurable, testable, and perfect.
00:00:23.840 I'll teach you everything you need to know, so you need to memorize it, obviously, because if you don't memorize it, how can you know if it's good or bad when you see some code? Some people think that code shows aesthetics, but I strongly disagree; it should just be correct according to certain measurements.
00:00:34.480 Actually, I'm kidding! I was planning to start this workshop by asking you all to introduce yourselves to the people sitting beside you. However, I see that you're already socializing, so just in case, please present yourself to the person to your right or left.
00:00:44.240 Tell them your name and ask them if they are new to programming and how long they've been working with Ruby. Go ahead, you have two minutes.
00:01:02.640 Okay, starting! Good morning, everyone! Thank you for being here. It's amazing to see you all. In this workshop, we will learn how to transform this type of code, which you can see has some weird coding standards with dollar signs everywhere and arrows for object orientation.
00:01:15.439 I'm actually kidding; it's just PHP. However, you can put any code here that you feel is painful to work with and that seems more complex than it should be. Any code that should be clearer and easier to maintain, like if you have an application for to-do lists and can't implement a new feature, there's something wrong.
00:01:39.200 My goal is that after this workshop, you'll learn the specific steps required to improve your codebase while working on it without losing productivity and without having to rewrite the entire application.
00:01:55.600 Check it out because we will learn how to transform this code into something much cleaner.
00:02:08.399 You can see that I'm cheating a bit here, but the difference between the 'before' and 'after' can be very impressive once you implement some of the patterns we'll discuss today. I'm very passionate about refactoring and believe everyone should at least be aware of these techniques.
00:02:30.720 We may not always use them, there are no silver bullets, and I agree with David on that, but at least we should recognize areas where we could make improvements to avoid getting stuck.
00:02:50.480 Before we start, I need to know a bit about you. How many of you haven't yet obtained access to the repository with the exercises?
00:03:01.920 Okay, please raise your hands. If you have a USB stick, please pass it around. I'll be checking this every couple of minutes.
00:03:14.000 As Jeff mentioned, if you're having trouble or don’t have Ruby or the repository, please pair with the person next to you and continue working together.
00:03:42.720 Today, we will discuss refactoring patterns. I didn't want to use those enterprise terms in the title of my talk, but that is what we'll be doing.
00:04:02.159 Is anyone familiar with the concepts of refactoring and patterns? Would anyone like to describe what they think it means?
00:04:19.919 That’s okay if you only have a general idea! Yes, please.
00:04:56.400 I see refactoring as editing your draft. I know that sounds corny after what we just discussed, but it's true. You write something down and then ask yourself how you can make it simpler or clearer.
00:05:12.240 Perfect! By applying patterns to refactoring, we can ensure that there are specific steps to follow, which will lead us to better code. This way, we won't end up rewriting entire chunks of code in a single hour.
00:05:31.359 What we'll learn today is about applying algorithms to improve our drafts.
00:05:53.800 I’ll share a bit about myself and what I’ve been doing over the years and why I am so passionate about refactoring.
00:06:09.360 First, let me clarify that my name isn't Tutti; it’s actually Eugenio. I had a problem with that name because there's a very famous Italian ship with that name. When people sought me out, they would find the ship instead.
00:06:36.800 This is a Costa cruise ship, which was named after my name, Eugenio Costa, and it’s amusing because my grandparents traveled on the ship and brought back merchandise with my name on it, which caused quite a stir.
00:07:03.760 So my home is filled with teddy bears and Batman memorabilia, but this hasn’t helped much for my presence in the open-source community.
00:07:17.440 I wanted to connect with the community, to learn and teach, so I chose my nickname, Tutti, which I think is hard to pronounce.“
00:07:38.800 I come from Buenos Aires, Argentina, nestled between Uruguay to the east and Chile to the west, with Bolivia, Paraguay, and Brazil to the north.
00:08:00.160 Is anyone here from Latin America or Spanish-speaking countries? Wow, so many! Bienvenido, that's beautiful. Let's talk after!
00:08:18.560 Even though I’m from Argentina, I don’t play soccer, but I do enjoy asado, a traditional barbecue, every four or five days.
00:08:35.680 Sometimes, I clearly express what I want to say in English, but it seems people don’t understand me. I was once at work stating, 'There’s a bug in the software.'
00:08:57.040 They replied, 'What?' and I repeated, 'Dude, there's a bug in the software!' To them, it sounded like, 'You mean a boy?'
00:09:14.080 Well, if you want to be technical, yes, I mean a bug. So please, if you find something weird during the workshop and want to interrupt me, please do, and I’ll just rephrase it in simpler terms.
00:09:31.840 In 2011, I worked in a small startup called Chef Surfing. I didn’t follow any best practices and learned purely from experience, which led me to make lots of mistakes.
00:10:07.680 My team was small, and my own leader pushed me to write a lot of code, but every two months, the complexity became overwhelming and we were left fixing bugs in production.
00:10:30.560 Fixing bugs often required me to rewrite significant portions of code, which was not predictable and ultimately unsustainable. It was just stressful and often felt chaotic.
00:11:00.800 The next year, I attended General Assembly, which had a Rails application that was tested, so refactoring was not as risky. Thankfully, they encouraged me to 'refactor all the things.'
00:11:20.560 The remarkable part of the story is that I managed to refactor the codebase while my team continued to ship features and deploy, often many times a day.
00:11:41.600 I was able not just to refactor the code but also the database, making it a happy experience I wish to replicate everywhere, further improving it.
00:12:05.440 In General Assembly, we significantly simplified the code, minimizing it and making it easier to work with, providing a more straightforward structure.
00:12:28.480 My apologies, but before any hands up, who has my USB stick? Does anyone know where it is? Could you please handle that?
00:12:44.320 The team was thrilled with the refactoring added to the codebase, which allowed us to communicate better as developers, project managers, and business owners.
00:13:00.720 As soon as we started speaking the same language about concepts like classes or methods, productivity soared week after week.
00:13:17.120 So, before we move on, who here feels like they are in a situation similar to my time at Chef Surfing? Where they sometimes need to halt development to refactor.
00:13:33.200 Wow, not many. Hopefully, you’ll learn something today.
00:13:52.240 Before jumping into the patterns we will explore today, I must emphasize one critical precondition: you should always have tests.
00:14:05.840 Never refactor code without tests, as you run the risk of introducing errors that were not originally present.
00:14:26.240 Everyone loses when issues arise; you, your clients, and users of the application.
00:14:40.320 Today, we will look at four refactoring patterns. These are the magical spells you need to memorize to write correct code.
00:14:55.680 Is anyone here familiar with these patterns? I’d like for you to describe any you know. For example, does anyone want to talk about intentional revealing methods?
00:15:17.679 Okay, please, you can read the code. Essentially, it eliminates unnecessary comments because the code itself describes its purpose.
00:15:37.840 Next, we have special case objects. Who would like to introduce the idea?
00:15:57.440 Nobody? Special case objects avoid type checks and conditionals in your code, ensuring smooth functionality.
00:16:13.360 If the method has too many instance variables and doesn't effectively refactor, it might require a complete overhaul, which is risky.
00:16:36.360 The repetition of methods should be contained in their scope, making sure the refactoring doesn’t break the whole application.
00:16:54.320 Now, let’s dive into some coding examples.
00:17:04.399 We need to apply the intentional revealing method to see how it simplifies our existing code.
00:17:23.680 As we start working on a new exercise, please make sure you keep communicating and pairing up if you need to.
00:17:38.960 The exercises are structured to help you practice while benefiting from discussions and collaboration. So, let’s get started!
00:17:58.560 If you encounter challenges, check if you have the correct Ruby version or mini-test installed.
00:18:21.760 There’s a chance you’ll face syntax issues if you’re working with incompatible Ruby versions or gems, so please don't hesitate to ask for assistance.
00:18:43.680 Time is up for this exercise. Thank you for participating! I’m excited to hear how it went for each group.
00:19:08.320 This will happen in every exercise, and I'm very passionate about it. If you want to talk later, whether in the hallways or on Twitter, please reach out to me.
00:19:25.360 Now, let's move on to more content.
00:19:37.840 Some people discover peculiarities while refactoring that lead to poignant discussions about bugs and features.
00:19:58.479 This allows us to uncover issues we weren’t aware of in our applications before.
00:20:15.439 I won’t move on yet because I want to mention a very important rule from an incredible person named Sandy Metz.
00:20:32.720 She stated that your method should not be longer than five lines. That’s quite a challenge!
00:20:48.960 It can be tough when having to manage multi-conditional statements or switch cases. Yet, by applying this principle over time, it becomes a habit.
00:21:03.520 If you apply various patterns, you can actually achieve more readable and succinct code.
00:21:17.520 Please note the resources I’ll share later for every pattern will be available on speaker deck and Twitter.
00:21:32.720 Now let's discuss special case objects, which aim to cancel out conditionals in your code.
00:21:49.920 This technique simplifies your code and eliminates unnecessary checks.
00:22:07.520 While refactoring, if you encounter the 'nil problem,' consider returning a symbol instead.
00:22:24.720 This will help in debugging by allowing you to trace the symbol back to its source rather than receiving vague undefined errors.
00:22:44.320 Instead of the typical nil, creating a new object that encapsulates the logic will enhance the readability and reliability of your code.
00:23:07.040 It’s a very helpful approach that aligns perfectly with the principles of object-oriented programming.
00:23:21.840 Now let’s move on to the second exercise and explore this further.
00:23:35.440 I noticed some of you have been struggling with mini-test issues. Don’t hesitate to collaborate with someone nearby.
00:23:57.680 As you explore these exercises together, consider that the more dynamic discussions you have, the deeper your understanding will be.
00:24:16.320 Don’t forget to foster an environment of collaboration and help each other out!
00:24:28.320 The problems can be challenging, but it's about figuring out the right decisions and naming conventions.
00:24:46.720 So, let’s get into it—I'm happy to see your progress and help with any questions.
00:25:04.000 Moving on, we’ll focus on the second exercise and I’ll share my thoughts on how to improve your codebase.
00:25:22.560 Remember, the essence of these exercises is to simplify your code both in terms of readability and performance.
00:25:38.840 I’ll be here to facilitate and provide any guidance, so don’t hesitate to reach out if you’re facing issues.
00:25:54.480 It’s important to keep the workflow fun and engaging, as it aligns with our learning objectives.
00:26:06.080 Every group can report whether the approach worked better than the previous exercise.
00:26:17.760 I believe I’m happy to hear that improvement—congratulations!
00:26:31.199 Next up, we’ll tackle the 'Replace Method with Method Object' pattern.
00:26:46.600 This comes into play when you are dealing with methods that have spiraled out of control—long methods that take too long to comprehend.
00:27:10.720 We’ll be using an example from my own journey of coding to help illustrate how this pattern works.
00:27:29.920 The first part involves identifying methods that need refactoring and migrating those behaviors into new classes.
00:27:43.440 I’ll guide you through this process step by step, ensuring you understand each transformation.
00:27:58.240 Next, we'll have a quick discussion on team dynamics as we refine our approaches.
00:28:06.720 It’s crucial to remain on the same page and tweak our methods for the best possible output.
00:28:16.800 At this stage, I'd like to introduce some key considerations that go into the refactoring process.
00:28:30.320 Having a clear understanding of your codebase allows for more fluid refactoring.
00:28:46.560 Moreover, it helps to eliminate redundant processes, making our projects more efficient.
00:29:02.800 Let's re-evaluate the components of our methods and observe where we can improve.
00:29:17.600 As we move forward, it’ll become clear how intent in design leads us to cleaner, more manageable code.
00:29:34.240 Lastly, remember that naming conventions will be crucial in maintaining clarity.
00:29:53.440 Let’s wrap up this segment and transition into service objects.
00:30:04.760 I will briefly elucidate why extracting logic into service objects eases our infrastructure.
00:30:21.600 As the need arises, separating concerns will enhance code managing in the long run.
00:30:36.560 I encourage you all to explore this avenue and share your experiences so we can learn from each other.
00:30:52.240 I’ll guide you through these patterns as we advance into our next exercises.
00:31:09.760 Remember the repository branch I created for my solutions where you can find the refactored codes.
00:31:22.320 Please make sure to look into these solutions and see how they might inspire your own refactoring.
00:31:35.920 Now, as we advance further, embrace the importance of refactoring in enhancing your workflow.
00:31:49.760 Let’s work together on improving our collective understanding of the code as we tackle more exercises.
00:32:04.320 I'm excited to see how far we can take this together as a collaborative group.
00:32:16.720 Remember, constant learning can significantly alleviate future hurdles while working on projects like yours.
00:32:29.760 Also, consider refining your definitions of methods to maintain clean coding standards throughout the process.
00:32:43.280 As this workshop progresses, I'd love to engage in deeper discussions regarding your projects that require assistance.
00:32:59.280 Going back to these coding improvements, the role of refactoring becomes evident as we strive to streamline the development process.
00:33:16.800 If you're seeking advice on any uncertainties, don’t hesitate to reach out at any moment.
00:33:28.960 Through collaboration, we can continuously refine our programming strategies.
00:33:42.640 Before we conclude, I encourage you to keep an eye out for the hidden gems in your code that can often lead to significant architectural enhancements.
00:33:57.520 Through this workshop, it’s crucial to keep learning and improving your skills, as programming is a journey, not a destination.
00:34:11.760 Let’s keep the momentum flowing as we work toward our objectives.
00:34:29.200 I hope each of you is gaining insights as we embark on this coding adventure.
00:34:45.440 The goal is to foster a programming community dedicated to helping one another grow through every coding hurdle.
00:35:05.840 Thank you very much for participating and see you around!