Ruby Rogues
087 RR Book Club: Practical Object-Oriented Design in Ruby with Sandi Metz
January 09, 2013
Episode 87
087 RR Book Club: Practical Object-Oriented Design in Ruby with Sandi Metz
Ruby Rogues
0:00
0:00
Speed:
Share This Episode
Show Notes
1:35 - Introducing Sandi Metz
6:15 - The book writing process and the speech writing process
17:30 - Flow of POODR
21:35 - Why design is for everyone
24:20 - The fear of writing a book: Am I really an expert?
27:00 - Breaking the rules
34:00 - Cheat sheets, screencasts, and diagrams for POODR
42:00 - Topics beyond POODR
45:20 - Why Sandi loves Rails
51:05 - How long will Rails last?
55:30 - When should you begin introducing design?
1:01:00 - Working with an Inheritance interface
1:06:30 - Rules for testing
1:14:45 - Well-tested objects without well-tested interactions
1:18:45 - Sandiâs rules for coding and breaking them
1:26:15 - Having too many small objects versus having too big objects
Picks:
Endless Space game on Steam (James)
Infinite Monkey Cage podcast by BBC Radio 4 (Avdi)
Marked App (Josh)
Herman Miller Aeron chair (Charles)
Bubble Timer (Sandi)
Gutter Cleaning Robot (Sandi)
Special Guest: Sandi Metz.
Transcript
DAVID:
I tweeted this morning. Iâve gained seven pounds since I got a Fitbit for Christmas. This thing clearly does not work. And somebody wrote back and said, âYou have to shake it.â
[Hosting and bandwidth provided by the Blue Box Group. Check them out at BlueBox.net.]
[This episode is sponsored by Jet Brains, makers of Ruby Mine. If you like having an IDE that provides great inline debugging tools, built-in version control and intelligent code insight and refactorings, check out Ruby Mine by going to JetBrains.com/Ruby.]
[This podcast is sponsored by New Relic. To track and optimize your application performance, go to RubyRogues.com/NewRelic.]
CHUCK:
Hey everybody, and welcome to Episode 87 of the Ruby Rogues podcast. This week on our panel, we have Josh Susser.
JOSH:
Hey, good morning everyone. Happy New Year!
CHUCK:
James Edward Gray.
JAMES:
Iâll be your cyborg panelist for this episode.
CHUCK:
David Brady.
DAVID:
Happy New Year, everybody! Well, I guess, last week was when you listened to me anyway. Happy January. Hi!
CHUCK:
Avdi Grimm.
AVDI:
Hello from sunny Pennsylvania. And if I sound a little funny this week, itâs because Iâm presently coating myself in sand trail in order to assume an immortal pre-worm form. [laughter]
CHUCK:
Awesome. I'm Charles Max Wood from DevChat.tv and I'm working hard on RailsRampUp.com, so go check it out.Katrina isnât here this week. Sheâs off chasing reindeer in Norway. And weâve got a special guest, and thatâs Sandi Metz.
SANDI:
Hi!
CHUCK:
So, I'm sure it comes as no surprise to anybody that we have Sandi here since she wrote the Book Club Book: Practical Object-Oriented Design in Ruby.
DAVID:
I'm surprised she agreed to come. [laughter]
SANDI:
Withall the hype in the Fall, how can I resist?
[crosstalk]
[laughter]
JAMES:
Actually, I'm pretty sure if you listen to our episodes over the past several months, almost every time Iâve had to say the name of the book, I think Iâve gotten it wrong including in last weekâs episode. So, yeah.
SANDI:
Just say POODR.
JAMES:
Well, the problem is I can never remember it. Like, what the P stands for. I think Iâve called it Pragmatic, Practicing, whatever. And then, I can never remember if itâs âin Rubyâ or âwith Rubyâ.
SANDI:
You know, I can't remember that part myself. [laughter]
CHUCK:
You know, I keep mixing it up with the GOOS book. And so I'm like, âPractical Object-Oriented Software Guided byâŠâ No. I was always like practicing this morning so I could say it right.
JOSH:
I just pretend that I'm David Brady and call it POOPER. [laughter]
SANDI:
Yeah. Whoever put that on Twitter, the person who said, âPractical Oriented Programming.â And then someone said, âPOODR, really?â
[laughter]
SANDI:
I have a friend whoâs five years old. He refers to his dadâs laptop as âThe Pooderâ. [laughter]
SANDI:
And so, thatâs how I remember.
CHUCK:
Yeah. So, real quick. I know most of us have met you at various conferences and things, Sandi. But for our listeners who may not have had the pleasure, can you just introduce yourself really quickly?
SANDI:
Sure. I'm Sandi Metz. I'm a woman of a certain age. So, that means I've been writing software for longer than most of you have been alive. I donât work for a startup. I donât work for a consulting company. I actually sit at a desk and write code for a living and I've been doing that for 35 years or so. The first significant number of those years were long enough ago that it was COBOL. And then, I fell into SmallTalk. So, I wrote SmallTalk apps for 12 or 13 years. I had a little brief segue into Java and then was rescued by Ruby in the mid 2000âs. And then, I got caught at a conference. I got overheard in a hallway rant and some people started trying to get me to write a book which took a while. And then, I wrote a book. So, the reason I'm here today is because I've been in a cave all my life writing code but some folks made me come out of that cave a little bit. And now, I have to talk. You guys arenât strangers fortunately. But I have to go to conferences and talk and get out. [crosstalk]
JAMES:
Was it them convincing you to write a book that took a while or the writing of the book that took a while?
SANDI:
Both. It took about three years for me to really write it. And then, it took two years overall to actually get it written. So, it was an extremely long and painful process.
JAMES:
Nice.
JOSH:
And everyone that has ever written a book knows what thatâs like.
SANDI:
I can recommend it to you all. [laughter]
DAVID:
We just have some business to take care of and then, we can jump back in on this. The first thing I want to announce real quick is that we have the best episode survey that you can get to at RubyRogues.com/Survey. So just go in there and let us know which survey was your favorite. And James also has an announcement for us.
JAMES:
Yeah. So, itâs time for another book. And we held the book on Parley, gave several options and the one that rose to the top of the pack is âPatterns of Enterprise Application Architectureâ by Martin Fowler. I actually got that name right because I looked at the front of the book when I said it. So, thatâs the book weâll be reading next. Itâs pretty thick. But in the intro, he says really that the first part is the part you read and then the back half is kind of a reference if you want to thumb around. Or if you want to read that too, great! Weâll probably give a couple of months and discuss it, probably early March. So, pick that one up and get started.
DAVID:
Thatâs where we actually find out [audio distortion].
JAMES:
Yes, and more. Youâll be surprised when you crack it open and read through. This book is 10 years old. And when you crack it open and read through just the pattern games, youâll be like, âOh my God! This is the Rails book.â [laughter]
DAVID:
So, dated is what you mean. [laughter]
JOSH:
Before we get into talking about the contents of the book, Sandi, I wanted to ask you about the -weâre talking a little bit about the writing process and how excruciating it was for you. I've seen you speak a couple of conferences now and watched a couple of your videos. And to our listeners, if you haven't watched -- if you haven't gotten to see Sandi speak in person or haven't watched one of her videos, go watch her videos because sheâs a really amazing speaker. And like everything she says is really carefully thought out. Sheâs definitely not up there riffing extemporaneously like some of us do on stage. [laughter]
JOSH:
But Sandi, I wanted to ask you about the interplay, the interaction of the book writing process and the speaking process. Because I assume that there was some period of time when you were talking about this material when you were still writing the book.
SANDI:
Yes. The first thing I would say is that talks are equally painful. Talks take a long time to put together.
JAMES:
Yeah, Amen!
SANDI:
Right? And like, any talk -- if youâve seen a talk online that I gave, I would say that the average prep time for me for a talk is everyday for up to two hours for about three months. Now, I know that that probably marks me as someone whoâs painfully incredibly slow like, clearly people give good talks who donât have that much -- donât have to put that much effort into them. But the talks are absolutely crafted. Like a lot of people say, âOh, donât worry. Youâve done everything youâre going to say.â I can promise you that when I give a talk, every word is scripted and every slide change is marked in the script. And so, when I get into trouble with my talks is when I wander, if I started like making stuff up, I get off-track. And so the talks -- it was very interesting while I was writing the book and making talks about the book content - how different the mediums were. Itâs so much easier for me to explain things if I can draw a lot of pictures. And in a book, you can't really like put a slide up and you make a tiny little change on the slide and then make another little change on the slide and then make another little change on the slide because people will just feel cheated when theyâre reading a book, if you have 10 pages with the same diagram with slight differences on it. And so for me, that was the huge benefit of giving talks, that I could draw a lot of pictures that had very tiny differences in them; where in a book, every time I want to explain the same concept, I had to just use words. And that made it particularly hard to do the writing.
JAMES:
Itâs interesting to hear you say that because in one of my notes here that I worked out while reading the book was I really loved the perfect ratio of prose to code. Itâs like you show me some code, and then you explain it. And so many books just go so wrong in one direction or the other. I was reading a book just the other day thatâs just code, code, code. And I mean, they show you like a two-page script they wrote. Then they go through and thereâll be like a line of prose explaining what one particular method is which is then reprinted. I mean, I just got so beaten over the head by the code. And then, thereâs other books where they just babble, babble, babble, babble, you know.
SANDI:
Blah, blah, blah, blah, blahâŠ
JAMES:
âŠsome code. But I thought, in your book in particular, the pacing between the prose and the code was just so perfect. It was like a conversation. It was really good.
DAVID:
I want to jump in on that really quickly just because there are a few things I want to add to what James said. The first is that none of the code samples -- I read it on my Kindle. None of the code samples were more than a page and a half long on my Kindle. And that paid-off in two ways. One was Iâm not flipping through, trying to keep a large application in my head. It was just a smooth application. The second thing is, all of your code examples were things that I could reasonably keep in my head while youâre explaining why they do or donât work or what the trade-offs are between this approach and that approach. And that really, really is nice. Iâve read other books; Iâm not going to pick on any. But Iâve read a few where you start reading and you get into that place where youâre going through like 10 or 12 lines of code. And itâs just like, âOkay, just give me a repository at this point.â But what we had there was just something that was bite size and it was really, really nice.
SANDI:
First of all, let me say it is so nice to hear praise. [laughter]
SANDI:
Well, I wonât go overboard. Hereâs the thing. Itâs likeâŠ[crosstalk]. Whatâs that?
DAVID:
Are we friends yet, Sandi? I could say more nice things.
SANDI:
Yeah, we are friends. I love you all. I mean, I really live in a vacuum and I didnât have as much feedback while I was writing it, which was a bad idea. I mean, itâs my own fault that that happened. And so, I had a vision of the reader in mind. And I tried very, very, very hard to communicate with that reader. I can't tell you. For all the people who might be listening to this who think they might write a book and then immediately put off by all this talk of pain. I mean, the thing thatâs really great about it is feeling like that effort is paying off. And so, it makes everything worthwhile in the end to have it, to feel as if it is useful. Anyway, the hardest thing about writing anything is the examples.
And I think everything that you guys are saying goes right back to that like picking good examples carries a book, right? If the examples are bad, you hate them. If the examples are engaging and [inaudible] and they teach you the right things, then they keep your attention. And so, I was lucky that my love of bicycles gave me a domain that interested me, that I thought might interest the readers. On top of that though, I thought there were two things that I did that I really, really cared about. One was that I wanted colors and text highlighting. And the other is I wanted it to be easy to read on eReaders. And those two things arenât common really, especially in the big iron publishing world of Addison-Wesley. But I put a lot of effort into making sure the code would look good, like on your Kindle, and be readable on your Kindle and be in a chunk-size bite on your Kindle. It turns out that too were paying off. Lots of people want to read on those devices. So, it makes it reachable and you can carry your Nook or your Kindle around with you and read it. In terms of how the ratio of code versus prose, I feel like I just got that wrong over and over and over again. And then Iâve obsessively edited until -- like I wrote a lot of things that didnât make sense even to me. [laughs] Like, I would write them. I would. I would write stuff. Itâs like a classic thing where you try to explain stuff, like weâve forgotten what itâs like to be a novice. And I would write code examples and I would have the transitions between example A -- Example 1 and Example 2. And then, I would realize, I left like 14 steps out. And the part that the novice reader or even the intermediate reader needed to hear, I skipped it. I just like totally skipped it. I left everything out that would allow you, as someone who didnât know these techniques, to go reproduce them yourself. And so, I think the size of the examples, the transitional steps. Like more and more transitional steps got introduced as the book went on because I was a miserable failure at taking the right size step between one example and the next. But really, struggling with the prose and trying to figure out how to explain all the intermediate steps drove the additional code transition examples.
JOSH:
Sandi, one of the things that I find when I talk to a lot of software developers who write, is that we experience some parallelism between the process for writing software and the process for writing prose.
SANDI:
Yeah.
JOSH:
So, when I wrote a book which nobody ever bought because they cancelled at the dock before it hit the shelves. But we took on the writing process as kind of a software development process with the same sort of cycle. Did you do anything like that where you have like test-driven development of your prose?
SANDI:
I didnât. I would say that I did a thing thatâs probably similar. But for me, I thought of it as writing a story. Like a book is a story. Itâs a story where thereâs a bunch of story arcs and they curve around and they curve around and come back and curve around. Itâs like spiral that keeps getting bigger with every chapter. So, I had that in mind. I just sort of had a beginning, and a middle, and an end. And every chapter has a beginning, and a middle, and an end. And I had a theory, I donât know, like I wanted it. So, early on in the writing, I got some feedback from my editors that was a little too informal. [laughter]
SANDI:
Yeah. And it probably was. I mean, I've formalized it up a little bit but still, I think itâs substantially less formal than most books like this.
JAMES:
It is, absolutely.
SANDI:
And so, I had to make a decision early on about whether I was going to like itâs in the -- whatever it is -- the Professional Ruby series. A lot of books in that series are pretty academic and formal. And so, for me, I had to decide whether I was going to try to find the voice, use my voice or whether I was going to try to be that voice, whatever that voice was that they wanted. And in the end, the writing was so hard that I was just, âOkay. I need to edit my language.â I was just like, âOh, heck! I'm just going to say what I want to say. And Iâm going to say it the way I want to say it. And if they hate it, well they can just not publish it.â [laughter]
JAMES:
So, letâs be clear. Sandi is not a professional despite the serious style. No, I'm just⊠[laughter]
JAMES:
I think youâre right and that really comes across. I have tons of examples written down from when I
was reading it. Like for example, in that SRP example. You showed that off so awesome. And you just started off with this harmless little class, itâs fine. And you're like, âAnd then this request comes in and you do this.â And then I'm like, âYup, Iâd do that.â And then, âThis request comes in and you do this.â And I'm like, âYep, Iâd do that.â And then I'm like, âNow, youâve blown the SRP.â And itâs like, âWait! Did we? Oh, yeah, we did.â Itâs such a great conversation that just guides you through. Another one I've written down where youâve mentioned something about using attr_reader methods for the variables and you have just been talking about public interface. And I'm like, âBut wait! Those add to the public interface.â I had that question. And then at the very next paragraph, youâre like, âAnd of course, those add to the public interface, soâŠâ It was really like a conversation.
I can't stress that enough.
DAVID:
Yeah.
JOSH:
So, weâre talking about the book now. I want to talk a little bit about just the flow of the book since weâre getting into that. And I got to say that thereâs a lot of material in this book. So, if people are listening along at home or in your car, or mowing your lawn, whatever you do when you listen to us, hi! The flow of the book, I think is -- I mean, this is not just a book for people who know objectoriented programming and want to get better at their software development with it. Itâs actually a really good teaching text for object-oriented programming because itâs so practical and hands-on with the things that really matter about object-oriented programming. And like James said, the conversational flow in it, I think, is really great. But the way that you talk through object-oriented design and then show the practical implications of, âOh well, this is a public interface. Therefore, hereâs how I have to deal with how I'm arranging the code that uses that.â Or, âWhy would I want to talk to, in my own access or method, instead of talking instance variable directly. What does that do for me? And whatâs the effect of encapsulation?â Polymorphism, letâs jangle with this. I love that everything was really concrete. That you talk about the obstruction and then you show concretely what that means for your code.
DAVID:
The real power there for me was just that a lot of the concepts were things that weâve talked about on the show, or Iâve talked to other people and theyâve explained to me. Some of them, I do on my own and some of them I donât. But the thing that really got to me was just that by the time I was done, itâs exactly what Josh said. I had this, âOkay, this is exactly where I want to do this and why.â And you know, my codes going to be better for it simply because even though I understood the concept, I didnât completely understand how to apply it. There was a lot of that in there that maybe really paid off for me.
SANDI:
I mean, I feel like we suck at explaining things and that we had failed the people, especially the people who are coming up in Ruby. Like, what does it mean to do designs? But now, we can talk about big issues, right? Like, what does it mean to do design? What is all this stuff? And I know some of that stuff just because I came out of a SmallTalk world. I haven't read many of the books. I've read some of them. I've been writing code a long time and maintaining code a long time. And the stuff thatâs in the air that helps me like somebodyâs in the universal translator. Like I finally get it and then I can explain it. And what I find is I spend a lot of time drawing pictures in the whiteboards and telling people how to write object-oriented code. Itâs really unfortunate to me that we have this sort of divide in our community between, thereâs this academic world of stuff that we donât really understand and we can't read the books and they donât make any sense. Thereâs all these words that donât really help us write code. And then thereâs us, where weâre sitting everyday and weâre trying to produce products and get features out the door. And thereâs this huge amount of knowledge that is incredibly helpful. Itâs like we donât have a good way to talk about it so that we can understand it and make use of it. My goal is really to -- like I didnât really make up. I would say there are very few ideas in this book that I made up. And probably every idea that I thought I made up, I really just stole from somebody but I'm too ignorant to know that I did it. What it is, is a translation. It is. Itâs like, hereâs what these things mean and hereâs why you care. Like hereâs how to use them in your code. And it feels to me like thereâs a lot to be learned. And we should learn it. Like, we can write better code in an easier way where we can produce the apps that make us happier. These guys, like Martin Fowler, Kent Beck, Bob Martin, thereâs a whole gang of people that are part of this huge history - Ward Cunningham, that have information. If we could only understand everything they were saying, we could really improve our ability to rewrite apps. [laughter]
JAMES:
Sandi, you said at the introduction of the book that âDesign is a finecast for a novice to work atâ. And I thought that was a real testament to what you were just saying that this is for everybody.
SANDI:
Yeah.
JAMES:
This isnât for experts sitting around, having their philosophical debates. This is something we can all do.
SANDI:
My definition of design is âhow your code is arrangedâ. If you define design that way, then everybody who types a line of code is doing design.
DAVID:
And if you're not thinking about it, then itâs probably just poor design?
SANDI:
Well, yeah. Well, thatâs an interesting segue into the debate in our community right now about design, right? Like some people would say theyâre not thinking of design, then they shouldnât think of design. What I would say is like, âHereâs what object-oriented design does.â It understands that for any problem, thereâs an infinite number of -- well, not a number but thereâs a bunch of different ways to arrange code to solve most problems. And if you understand design, if you understand all these things that the object-oriented design brings to the table, then you can predict the consequences of different code arrangements. So, you can say, âOh, I could use Inheritance, and I would have this cost and this benefit.â Or, âI could use Composition and I would have this opposing cost and benefit.â And in this situation, given what I know about my app and what I want to do, I'm going to choose one or the other with some feeling that I get what the consequence is going to be. If you donât know those things, you just write code and you have no idea -- you're making a choice about consequence but you donât know what it is. So for me, understanding what I'm choosing when I choose how to make a code arrangements, it gives me more degrees of freedom about how to write apps that are going to be where I can push on them later. And theyâll change in the way I need them to.
DAVID:
There are several ways of explaining because I'm teaching youngsters code. Youngsters. [laughter]
DAVID:
Intuition is what happens when youâve forgotten seven ways to solve a problem. And so, you get faced with this problem and youâre like, âEhhhhâŠâ And what you mean by, âEhhhhâŠâ is, âI'm thinking about some trade-offs and they feel yucky.â And you haven't hit on one thatâs perfect. And there isnât one thatâs perfect. They all have trade-offs. I love that.
JOSH:
So, as Master Suzuki said, âIn the beginnerâs mind, there are many possibilities. In the expertâs, there are a few.â
DAVID:
Yes.
SANDI:
Yes.
JOSH:
And both sides of that equation, there's a front and a back.
DAVID:
Lest people figure out how accurately they are in thinking that I am arrogant, I feel like George Carlin. And I'm pointing this out because I'm going to toss the ball to Sandi here because youâve mentioned this a couple of times. But one my goals for 2012 and especially for 2013, is to step back and say, âWhat can I do thatâs new?â And what I love about POODR is that as I read through it, I kind of put people down. And I was like, âHoly crap! That blows my mind.â And George Carlin, he wrote âNapalm & Silly Puttyâ. At the preface, he said, âI've been doing this stuff for 20 years and I just barely think I've figured it out.â And your book has really made me realize that, âAh, I feel like I just barely figured this out.â And then I read your book and I'm like, âOkay, got to keep working on it.â I mentioned that because in the pre-call, you said that you had the same experience which terrifies me because if you haven't figured it out, I'm screwed.
SANDI:
Okay. Well, maybe you're screwed. I can't really speak to that. [laughter]
SANDI:
I think I'm like everyone, right? I believed that I knew something. And then, I started trying to explain it to other people. A couple of things happen when you write a book. Itâs worse even in a blog post because like in a book, in this book, I felt an obligation to give, especially novices, explicit direction about how to behave. I feel like I had to tell them, âGo, do this. Do it this way.â I have to give them rules like early on the Dreyfus Scale. And so, thatâs a horrifying thought like you want to paint a big target on your head. Like write a book and publish it and tell people how to write, how to design object-oriented code. Like, this is insane. So, I had that real tension the whole time. Well, I went ahead and this is what I wanted to do. I wanted to write a book where nobody could complain that I told people the wrong things. Thatâs what I wanted to do, right?
DAVID:
A book with no trade-offs?
SANDI:
A book that said this or that, or this or that, or this or that. A book where nobody -- itâs so personal. It was a personal fear thing, right? Like what I wanted to do was write a book that no one could complain about what Iâd said on the Internet, where no one could take issue with me where I have to defend myself.
DAVID:
How does it feel to have succeeded?
SANDI:
[laughs] I wanted to write a book where I would never have the possibility of being wrong.
JAMES:
Thatâs awesome.
SANDI:
And soâŠ
[crosstalk]
SANDI:
Go ahead.
CHUCK:
I want to address that a little bit because I highlighted a whole bunch of stuff that I drove the people on Twitter crazy because I was tweeting it when I highlighted it. You have a couple of quotes in here that basically outline, âHey look, you know, thereâs a risk here and there are trade-offs.â One of my favorite ones, I just want to read it here is that it says, âPractical design does not anticipate what will happen to your application. It merely accepts that something will and that in the present, you cannot know what. It doesnât guess the future. It preserves your options for accommodating the future.â And so, what that says to me is you donât always have enough information. You may never have enough information. You will never have less information than you have now. So make the design decisions that you feel like you have to and defer the rest, until you donât have to anymore. And so it was basically, âHere are some rules. But use your best judgment because you're going to get more information thatâs going to inform you better later.â And so, that kind of opens things up. Here are the rules but if you have the information that says that you have to break them, then break them.
SANDI:
Yeah. And you can imagine, that was not the first thing I wrote.
JAMES:
Right. [laughter]
SANDI:
Because itâs true. Itâs this tension. I felt the need to give people, who were not yet capable of making their own decisions, very clear guidance about how to behave. But I wanted to really avoid that. Like some people have this idea about design like design has a bad rep. There are people who curse and spit when they say âobject-oriented designâ. And I'm not one of those people, clearly. I really believe that design has a lot. Design will help us all but itâs a certain kind of design thatâs designed to find a certain way. And so, what I wanted to tell people is -- the point I wanted to make really is thereâs a bunch of trade-offs and thereâs a point in your career when you get enough experience to make good decisions about the trade-offs like only you know. Only you know your app, only you know where the most likely points of change are. But for people who donât have enough experience to make those decisions, we got to give them rules. And I have to give them rules they wonât hang themselves with, that they wonât cargo cult. And so, that challenge the tension between telling people, âBehave this way until you hate this rule.â [laughter]
JAMES:
Awesome.
DAVID:
I think you said that in the book.
SANDI:
Yeah. As soon as you can make a cogent argument to me about why you should break the rule, you are welcome to break it. Thatâs how you know that you have enough experience where you can make your own decisions. But until then, until you can tell me why you shouldnât have an [inaudible] reader for every variable, I wonât look at -- okay, here I'm going to have a little rant -- I donât want to look at any code where you're saying â@somethingâ in your code, like donât access that data item. Donât treat it like data, send a message. So, I have a whole bunch of blanket prescriptions that I would give newbieâs. Itâs like, âAlways do this. Never do this.â Then, I'm keenly aware of it. I break all these rules myself. And I fully expect people to go out and break them too.
JAMES:
Yeah. Itâs clearly an excellent point.
JOSH:
And if you cook, you got to follow the recipe until you get to the point where you know when you can make substitutions.
SANDI:
There it is. Yes.
JOSH:
Just try baking. [laughs]
SANDI:
And hereâs the thing. The way we get great new recipes is if someone breaks the rule. So, you make up new ones.
DAVID:
I [audio distortion] because theyâve done something similar over and over and over and over again. And so, they know what the trade-offs are - going back to what we were talking about - they know what the trade-offs are of substituting this for that or adding this in, with everything else.
SANDI:
Yeah. The recipes that are made up by novices, we never hear about them because they donât win.
JOSH:
I'm going to try and make this anecdote really short. I was just talking to someone about this recently. A mathematician was studying knots, in the field of topology. And his wife was an avid knitter. And heâs like, âOh, I want to see if I can model knitting in Math and learn a new thing from it.â So, she shows him how knitting works and he writes down some mathematical descriptions of knitting. And he goes away for a few hours and plays around with it and he comes back and says, âLook! I've invented a new way of knitting. I just transformed some of these equations and I have a new form of knitting.â And he sits down and explains it to her. And she says, âOh, we call that
âpurlingâ.â [laughter]
JOSH:
Which for anyone who knows knitting is purling is knitting from the other side of the cloth. And so, his level of sophistication was completely a different level from her level of experience practical knowledge. So, my point with this anecdote was that unless you have a good grounding in the accepted fundamentals of design and what all the pieces are, like, âOh, I have a public interface.â âI have an Inheritance interface.â âI have all these pieces of it.â When you get to the point where you have to innovate, where you have to break the rules, you may not even know if you're breaking the rules or you're following a different rule.
SANDI:
Yes. To me, the most powerful thing about that is giving something a name because once we know the name, once I know itâs âpurlingâ, then we can have a conversation; and once we all agree about what purling is. And so, part of what I wanted to do and POODR was like take all those scary names and make them normal. Like, I donât tell you what polymorphism is until after I show you. And I'm like, yeah, thereâs a big long word for this but I donât talk about Aggregation until after I show you, I donât talk about Composition until -- because itâs like, weâre all doing it. Most programmers, even novices, are doing some form of most of these things but they donât know the names and they donât know enough about refactoring to do the transitions between them.
[crosstalk]
DAVID:
The really cool thing about that too was itâs kind of an experiment with the reader. You know what I mean? You know where youâre going but the reader is like, âWhat if we rearranged it this way?â Then like you said, you give it a name. But for us, itâs a discovery process. For you, itâs a guided tour, thatâs what youâre giving us. But for us, itâs the process of, âWhat if we do it this way?â âOh, I
see!â
SANDI:
It feels to me like thereâs room and I donât know what the media is for this. But that discovery process, thereâs such a need for a way that people can go put their hands in an experimental space and like do the refactorings. I donât quiteâŠgo, you go.
JOSH:
So Sandi, one of the things that I kept wanting to see in this book -- so this book, like I said, it has a very conversational style which, I think, makes it very readable. And then, you have these summaries at the end of each chapter that says, âOh, great! Hereâs all the things I showed you.â But throughout all the chapters, thereâs all these really practical prescriptive descriptions or prescriptions for how to do things really effectively. And I just want a cheat sheet for the book.
SANDI:
Itâs funny different people have come down on both sides of that issue and since of course, it was easier not to do it than to do it. I let that vote win. But yours is not the first voice, that should happen somewhere.
JOSH:
And then what I want to see is I want to see you and Avdi sit down and prepare a screen -- letâs see. Thereâs nine chapters in the book. Thereâs eight chapters plus testing. I just want to see a screen cast series of just like showing this stuff in action.
SANDI:
I am in agreement. First of all, anything that I got to work with Avdi on would be, âoh, so coolâ. [laughs] So, thatâs a win. But it confuses me a little bit that people do seem to want like talks, instead of reading the content, because to me, the reading is so much faster than the watching. But itâs clear that thereâs someway in which our brains are arranged so that listening to someone talk and seeing them draw the pictures has powerful meaning.
AVDI:
We talked a little bit about that at Ruby DCamp, right? I mean, we had that really well-attended session on drawing pictures about code. And a lot of people really got a lot from the different ways people have come up with for visualizing code or visualizing design. Thereâs a story I like to tell from when I was watching you present your talk GoGaRuCo where you -- I forget now the title of the section that you were going through but itâs like sort of a quick-fire section of going through, basically, transitions of a diagram. And I can't remember for the life of me now.
SANDI:
It was a picture that I've done a Composition. Iâd ripped out someâŠ[crosstalk]
AVDI:
Yeah. Demonstrating composition in a visual form. As you were going through, I actually heard somebody behind or next to me say, âWhoa!â It has these visual representations. They have a strong learning component for a lot of people. And they really stick with you and thatâs one of the things that I kind of wish that I could do more in the Ruby Tapas videos is visual stuff like that. Number one, I donât really have much of a gift for it. Number two, I generally donât have time because I want such a quick schedule on those. I donât usually have time to add a lot of extra stuff. But even there, I've noticed that itâs interesting in a visual medium how much sort of side band information you can sometimes add.
SANDI:
Especially after that talk. So, Avdi and I were both at Ruby DCamp in the Spring. And we talked, we had this session he was referring to. Weâve attended this session on visualizations. And it really was fascinating to look at, to see the different ways in which people visualize codes. And I'm not only talking about like UML class diagrams here. I'm mostly talking about the transformations of one design to another. So, it would be a refactoring, say from an Inheritance to Composition or refactoring into Composition. It feels to me like thereâs something powerful there. If we can figure out how to do images, moving pictures to teach people how to write a code, then it reaches a whole part of their brain that the words donât reach. And I donât know. I'm giving a talk at BaRuCo in Barcelona in the Fall. And itâs far enough away that I have time to think about maybe putting a whole talk together about visualization. So, Iâll do refactorings based on visualizations. Who knows how itâs going to turn out? I donât really have any idea where I'm going with it. But for me, objectoriented programming is like I have this mental image of the app; the app in memory of the objects and the messages passing between them as it runs. And it feels like if we could draw that picture, that if you could do any animation of the message of your objects in memory coming and going and the messages passing between them, that you could play it like a movie. And you would be able to look at it and tell where the design was wrong.
JOSH:
Have you considered doing flip books?
SANDI:
I donât know. I haven't. What I know is I donât know how to do this. But what I do know is that if I had a chart of numbers and I made a graph out of it, I can look at the graph and know instantly whatâs true. And I cannot parse the numbers. If we had a way to do that for applications, you would be able to see, âOh, thereâs too many message or too many objects.â Or, âThereâs a bottleneck here.â Where itâs very hard to look at the source code on disk and tell that, which is what we do now. We look at the source code on disk and we build up these models on our brains about whatâs true.
JAMES:
I think you're really on to something there and just listening to you talk. That even in a book, you show an example and then you say, âAnd so, what you need to do is change that code to this.â And then you show another example. Even though we say weâre changing that code, thatâs not what happens in the book, right? Thereâs that chunk of code and then thereâs the other chunk of code. Itâs kind of disk connecting our brain. And Avdi was a little down on Ruby Tapas earlier but one of my opinions is that itâs so powerful because I actually do sit there on video and watch him change that code from one thing into the other thing. And I actually wish Katrina was here right now because she would explain this much better than I would. But she talks about the shape of code, that we recognize a lot of things by shape. Like we see that and we know, âOh, thatâs wrong.â For some instinctual reason that we can see that shape, that bulky method, for example, and we know that thatâs bad, right? And we have that instinctual reaction to the shape. So we were really watching Avdi in the Ruby Tapas videos mold the shape. Itâs almost like heâs messing with PlayDoh and heâs reshaping the code while we watch. And I recognize that like you're saying is probably even better ways to show something like that than just a straight screen cast or something. But it is a very interesting topic.
SANDI:
I'm waiting on someone to take it and run with it who can write the code. Like run your test, run the profile, or take that data and draw me this animation.
AVDI:
I got a question thatâs maybe changing the focus a little bit. I've already spent two hours interviewing you about your book. So, I donât want to ask you anymore questions about the book.
JAMES:
Drill her. Just make her sweat. [laughter]
AVDI:
If anybody doesnât know what I'm talking about, if you get the deluxe edition, the Sponsor Edition of âObjects on Railsâ, that interview comes along with it.
JOSH:
[crosstalk]âŠsheâll give you the right response.
AVDI:
[laughs] What Iâm curious about is sort of beyond POODR. Since we talked, youâve been out and about quite a bit. Youâve talked to many, many people at conferences. Youâve done a little bit of, I think, going into companies and talking to them. What are the things that you feel like arenât in the book that youâd like to talk to people about now, that people are asking you about and having trouble with?
SANDI:
The interesting thing is that it will come as no surprise that people want me to give them advice about their Rails apps. They want to know how to deal with where you put logic if it doesnât go in your FAT model. They want to know how to deal with presenters. So thereâs that, right? What I find is that itâs like the book is fixed in the middle and thereâs stuff on the left of it and on the right of it. On the right of it is like, how do you play these techniques to the Rails app and what are the best practices that the Rails community can offer you? And thereâs a huge amount of dispute in the Rails community right now. Actually, thereâs uncertainty and thereâs dispute, weâll divide those into two different categories. The before, maybe thatâs on the right side of the book. On the left side of the book is it turns out that people need what I see when I go out -- like I'm at [inaudible], right? Some business invites me to go there. They want me to show up and look at their code. And when that happens, I walk into an office full of people and a bunch of people say -- the conversation goes like this, they say, âWell, we have this app. Itâs a terrible mess. Itâs got 100 classes in it, they're all [inaudible]. Theyâll test run forever.â And, âI'm going to open up my test center and I'm going to point my finger at this method and ask you to tell me how to fix it. Thereâs this enormous amount of complexity that we build over a number of years and I want you to look at this bit of code and tell me how to improve it.â Thatâs what happens to me.
JAMES:
And Sandi fixes it in 20 minutes and they lived happily ever after.
SANDI:
You can imagine the terrifying thought that one is going to be in that situation. But what I've been finding is that all the problems are simple and that they're all the same. And also that the people in that situation want me to give them very specific definite rules about how to write code and I finally came and started giving it to them. I made up the rules for them. And so, it turns out that people have methods that are too big, they have classes that are too big, they pass too many parameters, they use âifâ statements and âcaseâ statements. And all of those problems really are symptom of one thing and the solution is the same solution - break it down into smaller bits. And so, what I've been finding out in the world is that the bits are too big and that people should make smaller bits. That solves huge amounts of problems. And if you know any of the object-oriented techniques about making things smaller, like do you know what bits you're looking for if you're looking for Composition, if you're looking for Inheritance? Then you just have a leg up because you can talk to your friends about it. So, one of the things I'm seeing is that on the right hand side, they want me to fix their Rails app, but on left hand side what everyone needs to do is go home and write smaller statements.
DAVID:
You brought up Rails and I have to read this out of the book and then you can respond. I'm really curious to hear what you have to say. It says, and I quote, âAvoid writing frameworks that require users of your code to sub-class your objects in order to gain your behavior.â
SANDI:
Yeah, donât do that!
DAVID:
How do you feel about Rails?
SANDI:
I love Rails. And hereâs why I love Rails. I can write a web app even if I donât know much. I can write a web app if I donât know OOP. That cracked the door open to let people produce products, to get features done, to make web apps. And we are in that business. We are in the business of producing features for our customers. And so, I have nothing bad to say about Rails. I use it, I like it, I'm grateful for the effort that people have put into it over the years. However, there -- and hereâsâŠokay, it is the perfect solution for the problem it solves. Damn near, very nearly perfect for the problem it solves. However, many of us have a slightly different problem. And so now, weâre going to diveâŠ[crosstalk]
JAMES:
All of us have a slightly different problem because Rails is the Basecamp problem and thereâs only one Basecamp.
SANDI:
Exactly, yeah. I mean, like the CRUD problem. I would argue that if you have the problem of -- I have a database that I want to put a webinar face around and itâs straightforward. I have this direct mapping between a screen that the user sees and a table in a database and a row in a table in a database. Itâs perfect for that. At that point, I'm going to have to get into some slightly more fuzzy language. Like if you think of the controller as the request is coming in from the users on one side of your app, and thatâs on your left hand. And if you put your right hand out, youâd say, âThe data where it goes on the database is on my right hand.â And if thereâs a direct mapping between the data thatâs going on your database and the request thatâs coming in the controller, you can put your hands right together and that works. And itâs fine and that what Rails does. It wires them right together. However, if anytime that you have an impedance mismatch between those things, then you move your hands apart and thereâs some space in the middle. And this goes to hexagonal architecture, right? If thereâs a body of things that should fit between your hands and you put them in your left hand in the controller, or in your right hand in the persistence layer, what youâve done is youâve made it hard to reuse that logic which shouldnât really be tied to either one of those things. And so, yeah, I think the Basecamp problem is the problem where the hands are pretty close together. And itâs really easy to write a Rails app to solve that problem. And itâs perfect for doing that. I believe that -- I would tell you that many, many people are in significant pain because of the Rails apps right now because those are the people who are talking to me. And they're in a pain that I believe object-oriented design can solve. And itâs not enough -- okay, let me back up again.
Let me just say this. I have no interest in the fight - the design fight.
DAVID:
Sandi, you are picking a lousy fight here. This is huge⊠[laughter]
SANDI:
I am not. When I take the Myers Briggs test, I'm a flat line right down the center, every time I take it. I mean, it is a true thing. Letâs just mention the elephant in the room, right? From David, DHHâs perspective, he is exactly right. And when I heard him on the Rogues, I agreed with 99.9% of what he said. For that problem, you donât need to do much other than pour your logic into Rails. And you should do no more. Itâs a waste of time and money to do more if thatâs the problem you have. However, what I do object to, the only thing I really object to is I see a lot of people who have a different problem and it does not help them to say, âDonât look at the design.â There are people who are in pain that design can help. And they should be allowed, they should not be dissuaded from learning the techniques that might improve their lives just because those techniques donât necessarily apply to every Rails app. And the other thing I would argue is if you looked at Basecamp, Iâll bet you would say -- Iâll bet anybody who knew object-oriented design would look at Basecamp and say the code is well-designed. Iâll bet the design is good enough so that people would like it. Okay, I'm like a bad academic. And so, I can tell you that I once thought I made up the Law of Demeter. I did. I thought I made it up. I was having a rant to that and someone told me like the name of it. And I was like, âReally?â
JAMES:
Thatâs awesome.
JOSH:
Ignorance of the law is no excuse. [laughter]
SANDI:
I thought I made up the Null Object pattern. Actually, I did make it up. One day, I was working on something and I was like, âOh, I just made an object that will just answer everything,â as if itâs okay.
AVDI:
We call that âpurlingâ.
SANDI:
Yeah.
[laughter]
SANDI:
I believed that a lot of people who say, âGood design is a bad idea.â I mean, itâs not they're not good programmers. Itâs just that they figured this stuff out themselves and they're already doing it.
JAMES:
Right.
SANDI:
Right? And so why reinvent the wheel?
JAMES:
[crosstalk] those particular pains.
SANDI:
If it doesnât hurt, just keep on doing it.
JOSH:
So, SandiâŠFirst off, Chuck, this is going to be a long episode, weâre not going to do picks soon. [laughter]
JOSH:
Just get over it.
DAVID:
I'm skipping my pick as well.
JOSH:
So Sandi, the thing that people have used more than a couple of frameworks over the years. I think weâve all had a similar experience that when you're building an application using a framework that the first -- I donât know, call it a year or call it a month, I donât know. But the first era, the framework is awesome and it helps you get stuff done and it gives you a huge leg up and you are out the gate right away and you got all this cool stuff going on. And itâs an incredible force multiplier for your productivity because the problems that you all have to solve at the beginning of your application are pretty similar kinds of problems. And then when you get into the middle of your application or the second era, then the framework is sort of ambivalent. Itâs still got the structure and itâs influencing the shape of your application but itâs not really providing as much leverage for productivity as it was in the first era. And then in the third era, the framework is actually interfering with you being productive and creating new value in your application. And then many applications, thereâs this fourth era where theyâve sort of built another framework on top of the framework to help them move forward. Does that sound accurate to you?
SANDI:
In shorter terms, yes. [laughter]
SANDI:
Rails One, Rails ran in 2006 and itâs 2013. I've been alive long enough so that my -- I have databases that are now on their third different framework wrapping around. They had SmallTalk over them, they had some Java over them. Now, I have Ruby over them. Now, I'm looking at -- I'm wondering about Go, I'm wondering about functional languages. I'm wondering about other things I can do in Ruby. Itâs like the framework. And so, in order for my data to live into the next generation of technology, what I want to do is have most of business logic not be wrapped up in a framework. And I think in some ways, that parallels with what you just said Josh where at first, like all I needed to do was put up a web app. But then as the business logic became a bigger and bigger part of that app, it was important for me to preserve my investment in that business logic by having it be independent of framework. Like I said, I love Rails. I've used it used everyday. Well, not really everyday but I use it a lot that I donât want to be stuck like Rails isnât the only framework out there.
If you look ahead in 20 years, are we all going to be doing Rails?
JOSH:
Oh, I hope not! I'm going to be retired.
[laughter]
CHUCK:
Rails version 50.
SANDI:
Yeah. And in some ways, weâre living in a world where the Rails community is not -- like when the Rails community was startups that came and went as the VC capital ran out, then you'reâŠthose are not my peeps. My peeps are the people who write big apps or even small apps where the data is what has value. What weâre trying to do is put a face on that data so users can interact with it. And so in that sense, the frameworks come and go and my goal is to have the framework give me the most value for the least trouble. And itâs important to me that frameworks, that Iâd be able to write code that I can keep even when the framework is gone. Thatâs not a perspective that you have on day one of your first job at a startup.
JAMES:
Thatâs a really great answer. And you probably donât know this but you're playing heavily into this kind of perma-debate that we have going on, on the Parley mailing list where the DHH is explaining a lot of his ideas to us and some other people, Corey Haines, Josh, Avdi, myself in particular, are providing some counter points.
CHUCK:
That was a great way of saying weâre all fighting with DHH. [laughter]
JAMES:
I can't tell if weâre winning. [laughter]
AVDI:
I donât think weâre completely fighting.
JAMES:
No, weâre not. Itâs actually a really excellent conversationâŠ
CHUCK:
It is.
JAMES:
âŠwhere DHH is making a lot of fantastic points. And while some of us believe heâs wrong on some
of those, itâs very well-done and itâs a great discussion. I would love to bring all of it here but I can't. Letâs do this one part because it ties into a lot of what Sandi says. In that thread, weâve had a lot of talking about things like object-oriented design, things like dependency injection, or hiding your instance variables behind methods or things like that versus the counterpoint of YAGNI. So, doing this upfront and I come down on the side where I donât take YAGNI to be straight in the center. It could be this or it could be this. So, Iâll pick the perfect halfway point and do that. Thatâs not what I do. I go, âIt could be this or it could be this. So, err just a little bit on the side of design.â For example, I've usually injected dependency pretty much just right when I put it in. And my reasoning for that is that I found it makes the code more flexible in the future and thus, those objects tend to get used more. Whereas if I donât do that, then what I find is that I donât use those objects more because they're not as flexible, right? So, it basically becomes self-fulfilling prophecy. Anyway, I showed something like that to DHH in the thread and my example was probably pretty bad. But he tore it down as classic YAGNI, âYouâve added a few lines for a problem you donât have now,â et cetera. I was wondering Sandi, where do you fall on the divide? Do you literally not start introducing some design until you felt a bit of pain there or do err a little bit on that side? It would be good to hear your thoughts on that.
SANDI:
For simple coding techniques, there are some that I pretty much follow all the time. I break these now and then, but my pattern, like thereâs some things where I think -- there are some decisions where the cost is the same whether you do it way A or way B. For that, I'm going to say instance variables. Like to me, the cost is [inaudible] and sending the message to get that object versus the cost of referring to the object itself by referring to the variable. Those are so close to being a wash that I never refer the instance variable, that I always send the method. And so, lots of these decisions that people say, âYAGNI,â Iâll be like, âIt doesnât matter.â If it doesnât matter in the present, Iâd do the thing that leaves me the most moving room later, the most flexibility later. Along those lines, so one is instance variables. The dependency injection example is an interesting one because when I'm forced to give people a rule, what I tell them is never refer to the name of a class inside another class. That rule means that you always have to inject every dependency. Now, Iâll tell you that I break that rule. I break it. But mostly, I inject dependencies rather than getting a new instance of a class in another class. And I can defend this as saving me money today. And Iâll do it. I can do that by saying, âYou always have two uses of a class. You have the rest of your apps makes of it and the use that your tests make of it.â And I get so many benefits by being able to inject dependencies in my tests so that I can stick some other object in there if I need to [inaudible] and make a test double, that I feel like -- the good analogy is buying lottery tickets, like I'm buying a lottery ticket every time I injected dependency. And they donât all pay off. But if I do it all the time, it goes back to what you were just saying, James. Thereâs enough of the time that I discover that I save enough money in testing or I discover that I do reuse it or want to inject another kind of object. That pays off often enough so that I feel like I save money today by generally thinking about code in terms of injecting its dependencies. The whole YAGNI thing, like I'm a true believer in YAGNI and I almost never cause myself a problem with under design. Like when I make a mess, itâs very often because I have picked an abstraction too soon. And so, I've gotten way more comfortable with leaving messes in my code where I expect to find an abstraction and do a refactoring. But I'm going to wait on like three cases instead of two. Iâll put a case statement in there that will have two branches in it because I think I'm going to have a third and I normally get rid of it but I'm waiting on more information. For me, the decision point about whether to reach early for the abstraction or whether to leave the mess and wait to fix it later, it depends on whoâs going to make it.
JOSH:
Thatâs a great sort of high level conversation about that. And Iâd like to, if I can, drive that down to one particular issue as an example.
SANDI:
Okay.
JOSH:
In Chapter 6, you're talking about Inheritance and what are some good ways for designing that essential Inheritance interface. I remember many years ago, first encountering the concept of an Inheritance interface and that if you're building a super class that you know people will be making sub-classes of, you have to design it with that extensibility in mind. I loved what you showed in the chapter there. I got to the end of Chapter 6 and I looked at what you had created for the super class, sub-class decomposition there and how you factored that out. When I looked at the code at the end of Chapter 6, what you had in the sub-class was something that didnât need to be a subclass at all. And that there were no calls to super in it, there were no dependencies on the internal structure of the super class. And I looked at it and I said, âThis is Composition. This doesnât need to be a super class/sub-class relationship at all.â And then a chapter or two later, you showed, âNow, we can refactor this code into something that actually is Composition.â And the thing that I saw at the end of Chapter 6 was, âThis is actually a really good set of diagrams for people who are building Inheritance APIs.â Thatâs great. But my look at it was maybe it was just like refactoring too far. It had gone to the point where, âOkay, we have our class units now just about ready to be turned into a Composition relationship rather than an Inheritance.â And I think that when I'm building things in mind, I'm going with the Inheritance as a way of extending things and composing things in my code that I'm okay with tighter coupling. Thatâs sort of what itâs about.
SANDI:
I donât at all disagree with you. If I maintain the code, I can leave all kinds of messes and wait in on more information because I know I trust myself to fix them. One of the things that I confessed to Avdi when he and I talked about the book was how bad I am at making class method. How much I
err in making class methods. I make class methods all the time and I know theyâre wrong. But in the present, I can never figure out, âHow is this going to hurt me? This seems like the easiest, cheapest way to do it right now.â And Iâve gotten to the point where Iâll just do it. And Iâll know that eventually, Iâll figure out why I hate myself for doing it and Iâll fix it then.
CHUCK:
Instinct.
SANDI:
Yeah, and itâs the same way with Inheritance. Since I came from a world where I didnât have modules, I have Mixins. So, Inheritance was often our only choice. It was a choice, it wasnât the only choice. Obviously, we could have used Composition. But we use a lot of Inheritance and SmallTalk. And I think the refactoring of that example in the book all the way to the point where you can easily change it to Composition, I have that bias because I have used Inheritance too much and had to push it all the way to there to get out of it. And so, if you maintain your own code or seeing your people maintaining your code, your obligations about what to leave change and leaving things so that the people who come behind you can do the right thing. Like thatâs the last question I ask about code. When I write it, I do the right red-green-refactor. I work on it, I get to where I'm going to check in and I run a diff. And I look at all the methods. I added all the names of it and all the parts. And I think, âWhat would this look like?â I run the test and I read what the test say, what the story it tells. And I say, âWhat does this look like,â to someone who knows nothing about the code. And I have that bias because I write a lot of code that other people maintain. And so, the last thing Iâd do is go fix the names and fix the âifâ statements in the test and break the methods up to make them a little more intention revealing. But if itâs my code, I'm just like, âAhhh, Iâll deal with that later.â We can use design, like I'm a designer and you would take my badge away.
You would take my card away if you could see some of the code I write. And thatâs okay, because weâre just trying to save money. Weâre trying to get code out the door. But the point behind learning these techniques is not to use them all the time but to understand how to use them when you need to and how to get to them once you have a mess. Because most of the code we write involves -most of the design problems we have are problems of refactoring, not initial problems. Itâs rare that we do, weâre not doing perfect design for the whole app on day one. We donât know enough. What we do is we write a bunch of code, we throw it out the door and then we get more information and we have to get from here to there. The problem is getting from here to there, right? You wrote some code you threw it out the door. Itâs good enough, and then change happens and you have to decide how to do it. So now, I need two things, I need to understand what change I want to make in the code and I need to have enough refactoring skills to get from here to there. So those two things, like deciding where to stop really depends on whoâs going to maintain the code.
CHUCK:
So, I have another question. I'm going to completely change the topic but while I was reading the book, I read through probably the first eight chapters and I was like, âOkay. I really like these approaches. I've really learned a lot about these. But there was something I wasnât quite comfortable with about.â And what it turned out to be was all the stuff in Chapter 9 which was, âOkay, well Iâve designed all these interfaces to accept these messages in these ways but I didnât have a great way of proving that they did what they were supposed to do.â And so, Chapter 9 which is honestly, the longest chapter in the book, but for me, it was the biggest âAha!â And it was just one thing after another because it was, âHereâs how you approach this to basically make your test as flexible as your code so that it can actually prove that your code does what itâs supposed to do without repeating itself and without being too robust.â I really, really appreciated that just for the sense that it made me comfortable in implementing the rest of the stuff that you put into the book.
SANDI:
Isnât testing cool?
JAMES:
Heck, yeah!
DAVID:
Yes.
SANDI:
I mean, it is, yes. So, I donât think I had anything to write about testing and then I sat down and tried to figure out what I would tell people to test. And then I realized, âOh!â Thereâs like three simple rules, right? Test, make assertions about state for incoming messages and make assertions that you send to outgoing messages and ignore private methods. Rules are really simple. But it turns out they're incredibly powerful. And also, test roles. Make test approvable to play their role.
And thereâs four things together to make everything easy.
CHUCK:
Can I push back on something really quick on that and that is that a lot of times, Iâll compose methods out of private methods. And most of the time, you're right that you test your public method, you test what comes in and goes out. And thatâs fine. But sometimes, I kind of codified a complex sequence of things I have to happen into a method on a class. And a lot of that winds up in private methods just so that I can say, âLook, this is the interface you want to use. And the rest of the stuff just makes it so that I can read what I put into my public method.â I can't get to those private methods directly. And so, it usually turns into a battery of a whole bunch of tests to manage the complex process thatâs there. Is that an indication that I have a problem?
JAMES:
Yes.
CHUCK:
Or is that something that I may have to reach in and test my privates?
JAMES:
Nope. It is a common problem actually. And I have a pick for this episode thatâs exactly about that. So, how about we save it for there?
SANDI:
So does that mean I shouldnât express anything?
JAMES:
You can butâŠ[crosstalk]
CHUCK:
Express please.
SANDI:
Hereâs what I would say. Donât test private methods unless you really need to. In which case, test them as much as you want. I have code, and this is what happens, right?
DAVID:
I love you, Sandi. I love you so much!
SANDI:
Hereâs the deal. So, you have private methods and there are nasty gnarly complicated unstable things. And if you just test the edges, if you just follow the rules I gave you and test the boundaries of your interface, if you screw up a private method then itâs really hard to fix it because the error message is a long way from the thing that failed. So, the writing test of private method means that you're writing a test that tightly couples you to something thatâs unstable. And thereâs a cost and a benefit to that. If you break it, if it ought to work and you break it accidentally, your test will tell you -- they will drive you very close to where the problem is and make it easy to fix. However, if you decide on a different -- if you decide to change that unstable private implementation to something else, then you have to throw your test away and write a new one. It may be that itâs worth it to you to test a private method because -- when I'm writing a new class, I often have tests for all the private methods in it. And then as things settle down and I feel like the private implementation maybe is more steady, at that point, either I take the test of the private method out or I put a little note in there that says, âIf these break, delete them.â
DAVID:
You uttered a heresy that just lit me up so happily. You did a Lunch nâ Learn at Heroku and you talked about testing. And you talked about testing private methods and you got through the, âIf itâs hard, go ahead and test this so that you can work your way through it.â And then you said something that made my jaw hit my chest. You said, âAnd then once itâs working, delete the test.â
SANDI:
Yeah. You donât need it. Itâs just in your way.
DAVID:
Itâs in the way of anybody who comes after.
JAMES:
One of the âDestroy All Softwareâ episodes recently was really good about that. He gets a bug report and itâs something like, âWhen I go to this link, Iâd get an exception.â And he said, âAlright. Letâs debug this using test.â And so, he actually starts from a high level driving the application kind of test and he figures out what the scenario is to hit that URL and get it to throw this exception. So then, using nothing but the stat trace, he goes down one level further and basically tries to write that test and just the controller-level test, directly hitting the action, triggers it again. Then again, using nothing but the stat trace, he goes down to the model layer and figures out what it is there. It is really cool bit of programming. Heâs not opening the code. Heâs not looking for that bug. Heâs just writing this test. So what he ends up with is like this layer cake of tests that led him to the bug. And then when he fixes it, obviously he verifies that the whole layer cake works. But then, he also talks about how, âAnd now, we can probably remove a bunch of these tests because they were just for me.â
SANDI:
Cool.
CHUCK:
Or leave them in if they add value because you did have coverage around that one way or the other.
JAMES:
But the problem is he covered it in three different layers. Letâs talk about how there might be some value to leaving them if itâs like a user interfacing feature that is costing you money when it breaks or something like that. But in most cases, what he basically did is he reduced redundancy in the test that didnât really make sense, right? He could at least cut off two of the layers and leave the other one.
CHUCK:
Yeah, only one layer has real value.
JAMES:
Yeah.
JOSH:
The one thing that I got to say about -- actually, I have two things to say about Chapter 9. One, Chapter 9 was awesome. I loved the, âHereâs the different ways that you test this stuff.â And I'm pretty sure that I've done all of those things multiple times in applications, but never quite that methodically. I think Chapter 9 is going to be completely dog-eared as I work on my next app. But the thing about it is that I agree that this is the right way to write a large body of tests and this is going to give you much more maintainable tests as you get a big test sweep. The thing that I have a little bit of reservation about is like you said, âDesign is hard.â And while this is like the right way to do things that just like program code can have bugs, test code can have bugs and can have design errors. The thing that feels like is missing is the safety net. When I do Rails applications, Iâll do acceptance and integration tests so that I have a happy path through my application just to make sure that everythingâs stitched together the right way. And the testing approach that you talked about in Chapter 9, I think it works and I tried to poke at it even though it was sort of late at night when I was reading. I tried to find holes in the testing approach but it really does seem like you have all the pieces hooked together. What it doesnât have is like some allowance for people who are going to get this wrong sometimes and whatâs the safety net that they should be doing to make sure that they donât screw up their test in a way that screws up everything else?
SANDI:
Itâs completely missing innovation test. Thatâs whatâs missing, right? In the end testing. What that chapter is, is about unit testing. And I probably donât ever say that anywhere in the book. Itâs the cause of the example app. Like, this is an app that fundamentally has no user interface. So, itâs hard to know where the edge is to test it. There are very few use cases that go all the way through. So, the short answer is I totally agree. Like this is not enough. But I tend to write unit tests and integration tests and nothing else, nothing in between. And it makes me put all my code in something thatâs unit testable which is a good thing. I can't have helpers. I can't have code views. If I wanted to be tested, it has to be in a PORO, in some kind of object that I can get to any unit test.
CHUCK:
A PORO?
SANDI:
Plain Old Ruby Object.
CHUCK:
Okay.
SANDI:
Yeah. If you make that rule that says -- if you're afraid to write code without test which I am having, once you write your first test and you realize how bad your code is, then you're ruined forever. I definitely want to write tests and I want to write tests first code but I donât want to write controller tests. And so, I end up in Rails apps. That drives me toward trying to put everything in an object thatâs easily testable. And so when I do that, then I just have the bottom level test like in Chapter 9 and then thereâll be some wrapper test at the edges of the whole application and thatâs where the safety net is.
JOSH:
Okay, good. Maybe when you revise the book.
SANDI:
Shoot me now.
[laughter]
JAMES:
I was actually thinking earlier, I can't remember who asked Sandi, what would they like to include that they didnât. It was Avdi. What I wanted and I actually took a note about this when I got to the end. What I wanted was a lot of your examples. You know, weâve talked about the conversational styles and itâs this class moves into this other class or maybe two classes if youâre splitting something out kind of thing. What I want for a second edition or a follow up or whatever is some cases where we move up to the medium levels of complexity of object interactions, where youâve got like a handful of objects interacting, and you're applying these rules to them.
SANDI:
And it feels like the book is a terrible medium for that. Like it does need something like we were talking about before where thereâs some other, some websites on interactive thing, where people can go and get up to their elbows in that sink of objects in a way that you can easily manipulate them. I donât know really what that is but I am deeply sympathetic for the fact that itâs the next step for learning.
CHUCK:
I have a question, Sandi. You mentioned you test units and then you test innovation. One -- I wonât say anti-pattern. I will say one effect, when I try to do that, one result of the trade-off that I end up at is that I end up with these objects that are well-tested but the interactions between them are not tested to my satisfaction anyway. Is that because -- are you creating more objects that encapsulate those interactions?
SANDI:
Yeah.
CHUCK:
AaaahhhhâŠ.
SANDI:
[laughs]
CHUCK:
Thank you. Open my fridge and turn on the light. Okay.
SANDI:
I've been wanting to give -- okay, so people wanted rules for me like when I go out and see strangers when I look at their code. So, I finally gave them some rules and the rules are, and this is painting a big target on me to give you these rules. But I want to say them to you and see what you guys think about them.
CHUCK:
Please.
SANDI:
Okay. So, I ended up giving, âThis is the bottom line. Your class can be no longer than 100 lines of code. Your methods can be no longer than five lines of code.â I wanted four but I felt like I had to give them five. âYou can pass no more than four parameters and you canât just make it one big hash. Your controller, in a Rails app, when a call comes into your controller, you can only instantiate one object to do whatever it is that needs to be done.â
JAMES:
I love it!
SANDI:
âAnd that your view can only know about one instance variable.â So those are the rules I gave them. I told them they could break them, right? They could break them.
CHUCK:
But then everything would be too simple.
SANDI:
Yeah. So, what do you guys think about those rules?
CHUCK:
I feel terrified.
JOSH:
Whoâs the audience for those rules? [laughter]
JAMES:
You Josh, you.
SANDI:
This was a shop of people who had mid level experience but had created some big -- they had a control with many, many lines of code in it with many, many modules and views that had so many instance variables that they felt like they just had to set every instance variable known to human kind to make them work, right? I mean, these are people -- I would say, everybody. Everybody is the audience for that rule, frankly. Like, if you donât know the rule -- if youâre afraid of making a mess out of your Rails app and you follow these rules, if you could figure out how to follow these rules, I think you would stay out of trouble.
CHUCK:
So, one thing that really strikes me with these rules is that for the most part, if you really try, you should be able to follow them. And if you canât follow them -- see, this is the thing with programming rules that I think people donât understand is that when you say, âIâm giving you this rule,â they think, âOh well, Iâm sure I can find an instance that breaks this rule.â The whole point is yeah, but when you break the rule, you should be able to explain exactly why you need to break the rule. In that way, then you can justify what youâre doing. But otherwise, youâre not forced to think about what you're coding and thatâs really what the issue is.
AVDI:
Thatâs a fantastic point.
JAMES:
I agree.
SANDI:
I told them they could break the rules if they could talk their pair into agreeing with them.
AVDI:
Yes, and thatâs good.
JAMES:
Thatâs awesome. [crosstalk]
AVDI:
That is why I like the term. Iâve seen a lot of pushback against rules. Letâs call them guidelines and stuff like that. [crosstalk]
AVDI:
I mean, as far as words mean anything, thatâs why I like the term ârulesâ because it has that implication that you need to talk somebody into -- you need to explain to someone why itâs okay to break. Thatâs exactly right. If you can explain to your pair, âThis is why it makes sense to break this rule here.â And they agree with you. [crosstalk]
CHUCK:
Or to yourself. [crosstalk]
CHUCK:
But the thing is if youâre doing it by yourself, because itâs hard is not a valid reason for breaking that rule.
JOSH:
So hereâs the thing. And it goes all the way back to the title of the book, Practical Object-Oriented Design. And the thing that I think is the hidden magic in this book, is that every chapter when Sandi is talking about the trade-offs that are involved in these things. One, sheâs upfront about the fact that itâs all trade offs, and that itâs all about âwhat is the cost of doing the workâ and âwhat is the benefit that you get out the other sideâ. And these rules, Sandi, these rules that youâve talked about, I think they're great as goals and yes, you should be able to break them when you need to. But the thing is theyâre sort of tuned for âif I do the work to follow this ruleâ, most of the time, Iâm going to get a benefit from it down the road. And that when youâre evaluating breaking the rule, I think the right mindset for that is âhow much is it going to cost me to follow the ruleâ versus âhow muchâŠâ
SANDI:
Itâs going to save me, yeah. Itâs about the money.
JOSH:
Yeah.
CHUCK:
And when weâre talking about breaking the rules versus not breaking the rules, weâre going back to the conversation about whether or not we have enough information. That information doesnât have to come from the user, it doesnât have to come from the product owner, sometimes it comes from, âGee, Iâm going to break this rule and see what happens.â And when it comes around and kicks you in the rear end, you go, âOh, I now have enough information to know that this design decision was the wrong one, and Iâm going to go the other way.â
SANDI:
Yeah. And very often it means breaking it into small bits, which is what all these rules make you do. Like if you have to break things into small bits, you're going to really try for the bits to have high cohesion, right? And so, lots of things naturally fall out of this, itâs like whatever. These are arbitrary guidelines that I gave people who were really desperate for help about how to make decisions in the present where they felt like they didnât have enough information. But the decisions that theyâve made in the past, using the same criteria had turned out very badly. They donât know enough to do the right thing and they understand that there is a better thing. And they can explain these patterns, some of them, but they donât know what to do right now. They havenât bridged that gap yet that will keep them out of trouble in the code they write today. And so, I donât know. It was my best guess about how to give them some sort of practical guidance.
JOSH:
To people in that situation, anything is better than nothing.
SANDI:
It felt like it. And they were -- who knows how it will work out? Iâll check back in and find out like, âAre you following the rules, first of all? And if you are, did they seem more helpful than harmful?â I mean, I know that my code looks a lot like that. I mean, what would you guys say? Does your code -- if you evaluated all the code, the most recent Rails app that you wrote based on those rules, would it mostly follow it or would it mostly not follow it?
DAVID:
So, Chuck, our client listens to the podcast.
CHUCK:
I know. [laughs]
DAVID:
I'm going to go ahead and take the bullet for both of us and say, âHell, no!â And my experience from this, I get this simultaneous thought that has been recurring to me frequently. I didnât link them together until just now which is that programmers, I have observed recently especially, have an incredible ability to tolerate pain and just assume that itâs unavoidable. So, why try? And I listen to these rules and I'm like, âWe break all of these rules and we know that at some point, weâve broken the rule.â Sometime around 750 lines of code in the class, you start thinking, âMaybe this class was too big.â
CHUCK:
Maybe.
DAVID:
Maybe. And what I'm realizing is that I break all of these rules regularly. I personally at some point, I have rules -- well, I donât have a hard and fast rule. At some point, I know itâs too big but I sneak past your rules without sensing any pain and IâŠ
SANDI:
So, let me ask you a question then. Why is it that -- I think we, as human beings, have a bias. The bias is to let it go too big more so informally than to break it up too soon. Itâs kind of like, if Iâm going somewhere in my car and I could drive past a bunch of intersections, I usually make the last possible turn to get to the place Iâm going. I donât turn at the first opportunity. I turn at the last chance. And so, it feels like we are biased toward letting the thing, to continuing to do the thing that weâre doing. And when I ask people, âWhy donât you have a lot of little classes?â They very often have an answer to that question. They say, âOh, it would be too many small things and it would be confusing.â
DAVID:
Yes.
JOSH:
DHH said that in one of his Emails. He said, âI donât want this proliferation of classes.â Like having too many classes in your file system would be a problem.
DAVID:
I will own that because I have actually said that. Thatâs what I hated about Java programmers. Too many classes and I couldnât keep them straight.
JAMES:
Let me give another good example of that. I was actually having a conversation with a slightly more junior programmer recently and he had a class where it was very clearly doing two things. Like on one thing, he set up this scenario and then on the other thing, he handled that scenario. And I told him, âYou want two classes there. One that sets everything up and one that handles the thing.â And he said, âBut if I break them apart, I canât see them together and theyâre related.â And I said, âThatâs a problem your editor solves with something like split panes or something like that. Thatâs not an issue of the code itself.â
CHUCK:
Itâs funny to me that you guys are bringing up these reasons to keep it together. Usually in my case, what the deal is, is just that somebody asked for another feature, it was really easy to just glom onto the class that I already had. I might have to tweak one or two methods but itâs not a big deal. So there is no pain to add it. The pain comes in later when I have to modify something thatâs already there in a major way. So, I donât feel the pain until I have to split it up. Itâs in attention.
AVDI:
I feel like thereâs a common perception that adding a class is a heavy weight operation. [crosstalk]
JAMES:
Thatâs right.
AVDI:
Iâve even felt this myself sometimes. And Iâm not even really sure where it comes from because, I mean, itâs not as heavy weight as it is in a lot of languages but itâs there. And there are some things that maybe Ruby could even do better like the fact that if it makes sense to add a class but youâre really just going to be instantiating one object in one place, it would be nice if Ruby made it easier to say, âI just want basically a singleton here, a one-off object that has these traits and thatâs it.â You can do that but itâs syntactically harder than it ought to be. I donât know what all can be done to lower that perception of it being heavy weight. Maybe we all need a sprout class macro in our editors. One thing that you can do is, you can do more internal classes. So, if part of that it feels heavy weight is the fact that you add a new file every time you add a new class, consider if youâre just sprouting a new class, maybe just sprout it inline for now inside the class that youâre working on and then factor it out.
JAMES:
Great idea.
JOSH:
I just want to say, that can be a little dangerous if youâre working in Rails and the way the class loading works.
AVDI:
Yes. There are a lot of little ways that the Rails conventions kind of makes these things a little harder than they ought to be.
DAVID:
So if I can articulate my personal pain, do you guys want to take it up? I know weâre way over time. But Iâm getting free consulting out of Sandi, so I just canât pass this up. [laughter]
JAMES:
Sandi, weâve got a few apps you're going to need you to look at after the podcast. [laughter]
DAVID:
Exactly. So creating a new class is not hard. Potty training a new class frequently, for me is. What I mean by that is I feel like if I split an object into two separate objects, now they both have independent life cycles and I feel like that -- I learned object oriented in C++ which is kind of like learning to program in basic, itâs just an extension of brain damage and I accept that.
SANDI:
I hate that for you.
DAVID:
Yes, me too. So when I create this object, I donât want to have this object thatâs partially constructible that might be in an inconsistent state. I feel like I suddenly have to worry about set up, tear down, life cycle, protection, capsulation. Am I worrying about the very feature I should be embracing?
JAMES:
Yes, can I take a stab at that?
SANDI:
Yes, please do.
JAMES:
Yes, because to give an example, just that I ran into the other day. I had some class that was doing interaction with some response from an API. And one of the things I was doing there is parsing the âJâ sign it gave me. So when I wanted to parse that âJâ sign, of course, âtrap errorsâ in case it gave me crap or whatever, a few things. So there was a few parts to that parsing. And originally, I did it inline and then eventually, I'm like, âOh yeah, that belongs in some class.â So I split it off and then I would just create this instance with the data and then call this parse method or whatever and it will give me the real Ruby back without any errors or whatever. So I split that off and I thought, âOkay, good. Thatâs separate now.â But then, what happened is I realized I was doing that all over the place. I mean, who doesnât change some âJâ sign into something. I donât want errors. I just want the result or whatever. And so, that little class that I split off, you talked about, âOh, but now itâs its own thing.â Yeah, thatâs whatâs great. Now, itâs its own thing. And I went back and ripped out about ten places in my app where I was doing that and just made that class and used it.
DAVID:
Isnât that awesome that you just pile everything onto it?
JOSH:
So this is where I get to crow about my achievement on locked from last week.
[laughter]
JOSH:
James, so in the DHH episodes throughout on Parley and I know weâre not doing Best of Parley anymore but because we have over 500 people on Parley now.
DAVID:
You just broke some peopleâs hearts right there, Josh.
JOSH:
Yeah. So in that thread, David was -- we were talking about various patterns and how to basically decompose things into manageable chunks. And I tossed out a pattern that I've used where you basically make up. People have been calling these things Form Objects, but I think of them as resources. Theyâre not active record models, but theyâre still models and that thereâs something that you can put behind a restful controller. And itâs a very frictionless way to structure parts of your application so that they use the Rails conventions effectively. You can get a lot of leverage out of just throwing an object behind a controller using mapped out resources in the routes and, bam! Youâre done. And itâs very little code to pull out something from one model and make it essentially a first class resource on its own. And the process of pulling that out, I find that the mechanical steps of actually doing the work, to pull that bit out and put it in its own class to manage those interactions, is far less work than fretting over, âShould I do this or not?â
SANDI:
Just make the object. Just do it!
JOSH:
When I get to the point where Iâm suffering with it, itâs like Iâll spend like three or four hours wondering, âOh, how can I do this within this thing?â And then I just bite the bullet and say, âI'm going to pull it out in its own thing.â And ten minutes later, everythingâs better.
JAMES:
Kent Beck talks a lot about this, right? That once you're giving yourself that other object, now you have that logical place where that stuff goes. And then you realize, âOh, yeah, this would make more sense here, and then this thing can handle that.â Itâs funny how it frees your mind because it separates those concerns for you.
JOSH:
Corey Haines calls that a behavior attractor. But anyway, the achievement unlocked was I showed this example and DHH looked at it and said, âThatâs a great looking pattern.â [laughter]
JAMES:
Which is almost the exact opposite of what DHH said to me. [laughter]
JOSH:
If he likes it, it must be good, right?
SANDI:
So, I want to respond to like the last three things that got said, and I wrote them down.
JOSH:
Go for it. Go for it!
SANDI:
Donât mind me. Iâm just trying to get a word in edgewise with the Rogues. [laughter]
CHUCK:
Itâs hard. Trust us, we know.
SANDI:
But you know, Iâm just teasing you because I know that Iâve spent the last two hours talking. So we were talking about too many small versus a few big, right? Thatâs the design tension and Chuck, I think, said, âThatâs not really what happens to me. What happens to me is that I have a little bit of new behavior and I put it in an existing object. I put it in a place most like where it ought to go.â Then David was like, âI donât really want to make more objects because I feel like I have all this set up, I have this tear down like they bring.â It feels like they bring these burdens with them to have new objects. Does that characterize what everybody said correctly?
CHUCK:
Yes.
DAVID:
Yes, pretty much.
SANDI:
So my response to David would be, your objects are still too big if they feel like they need a lot of set up tear down, right? Theyâre still too big.
DAVID:
Yeah.
CHUCK:
Okay.
SANDI:
So, what happens is if youâre already in the situation or if youâve already fallen off the cliff and you have this 750 line object, and you divide it in half, those objects are still too big. And very often, people have a hard time doing these refactorings because they cannot see that their life is improved by that first change.
DAVID:
Wow.
JOSH:
Itâs like finding a guy whoâs driving an RV around and complaining about how he can never get down narrow streets or find a parking space? And you tell him, âYou should really be riding a bicycle.â And then he goes out and gets a giant three-wheel bicycle, with one of those trailers that you hook up to, to carry everything around on. Like doesnât get the whole idea of bicycling, tries to get a bicycle thatâs as much like an RV as possible.
DAVID:
I think youâre assuming too much self honesty. He doesnât go out and buy a bicycle, he goes out and buys a 4x4 and calls it a bicycle, and says, âThis bicycleâs too big.â [laughter]
CHUCK:
Itâs the same problem.
SANDI:
If youâre driving that Humvee, thatâs all you can see. You canât see any further and we have to respect that. So the problem here isnât -- the teaching problem is that once the code gets so far out of control, many of these techniques donât really improve. They add complexity instead of removing complexity in the short term for code base thatâs out of control. A lot of people complain about the zone because thatâs all they can see. So our challenge as people who believe in these ideas is to either help people start out with apps that donât get out of control. Or to provide techniques where the app is made up of ten, 800-line models can get back into control. Itâs a painful road to hoe, to make an app happy and friendly again once all the parts are too big. So I donât really know the solution to that other than just by helping people one by one because itâs a matter of faith.
JOSH:
Thatâs when you throw everything out and start over.
SANDI:
Yeah, the Humvee guy does not have faith in bicycles and teaching him faith, itâs a matter of faith to get them to do all the intermediate refactorings that take them to a better place in their code. So, I have an enormous tolerance for small objects, I love them. And I donât care that I donât remember what they do. It does not matter to me. I trust them.
JOSH:
Sandi, this is the terrible question and thatâs, when do you give up? I mean, when do you look at an app thatâs a mess of crap and itâs not just ten 800-line objects, itâs 100 8,000-line classes.
SANDI:
The good thing about the mess of crap is very often someone made it work. You canât change it and it hurts. But they made it work and so you know what the users want.
CHUCK:
Thatâs why we got paid, right?
SANDI:
Thatâs why we got paid because we delivered that software. But it can be true, like sometimes, I advise people to use the user interface and start one feature at a time, one use case at a time writing new code and turning the old code off, or even leaving the old code on, taking the links out. Sometimes the cost of fixing it is much higher than the cost of rewriting it. And I just look for seams in the code where I can break it and it is true. If I think, it would take me a week to figure it out how to change the code. But if Iâm willing to eventually throw away the whole app, I can add this new behavior to an existing feature by rewriting the whole thing faster than I can figure it out. Then, some ways, yeah, you cut your losses. You learn something, you move forward doing the best you can.
JAMES:
There are ways to handle those big things though, right? Like you introduce a service object and push as much of this one piece behind it as you can, just to guarantee that youâve got the seam in there.
JOSH:
So these are like things that you can do to work around it. The question I asked, though, was -and maybe there isnât a good answer for this, but how can you actually evaluate whatâs going on in this big mess of code? So you had all of these, you said, âI gave up and told these people these rules of thumb for what to do in their code.â Can you give a rule of thumb for, if your code is this big of a mess, you should give up and start over?
SANDI:
I have not been paid to say this, I would say run Code Climate and go to the churn graph and look in the top right hand corner. And if you feel like that glass is costing you money, start refactoring.
JOSH:
Okay.
CHUCK:
Caught object right there?
SANDI:
Yeah. Itâs like the thing that you check in all the time thatâs really complicated. I can promise you itâs costing you money. That may be the only class, that class might be ten classes, right? I mean, you might have to break it up into a lot of pieces, but refactoring that class might be all you need to do in an app. And if that takes youâre pain points away then, youâre good to go.
AVDI:
So never give up, never surrender.
JAMES:
Thatâs right!
AVDI:
I love that movieâŠ
SANDI:
Itâs always fixable. And, you know, fixing is fun. Itâs enormously satisfying to clean up the mess.
DAVID:
A little bit of therapeutic refactoring, huh?
SANDI:
Yeah, Katrina.
JOSH:
Thatâs great. Is that a good point for us to switch to picks finally?
JAMES:
Yes!
CHUCK:
I think so. No one seems to be winding down soâŠ
JAMES:
Just to be clear, no one has had a bathroom break since this started.
SANDI:
I had a coffee.
CHUCK:
Oh, oh, oh! Who needs to go first? [laughter]
DAVID:
I have so many follow-on questions but Iâll save them for another call. I just want to say for the listeners, I really am a better programmer than I sound.
[laughter]
CHUCK:
Yeah, heâs highly practiced in writing good code and asking dumb questions.
JOSH:
Sandi, so we donât have enough time to talk about everything we want to talk about. Will you promise us that youâll spend a little time with us on the Parley list and have some conversations there?
SANDI:
Yeah, thatâs something that Iâve been meaning to do anyway. Hereâs the thing, I just find I suck at electronic media. I hate it. Iâve been lurking on the Objects on Rails group thinking, âWow! Thatâs a good question.â âWow! Thatâs a good answer.â âWow! Thatâs a good question,â without ever having jumped in myself. [laughter]
JOSH:
So hereâs my pro tip for email lists like that, treat email messages like they were methods. Write a five line email.
SANDI:
That would help, because I do. I always feel like I have nothing to say, or a book to write.
JOSH:
Just say something short and sweet.
CHUCK:
So the last mailing list you joined in on, your response is POODR? [laughter]
SANDI:
Read the book, yeah. Iâve been telling people and I probably shouldnât say this for recording. Because itâs being published with a national publishing company, it means Iâm making no money so I can recommend it without a conflict of interest. So yeah, buy and read POODR.
[laughter]
CHUCK:
There you go!
JAMES:
Absolutely.
JOSH:
Thatâs great. Okay, thatâs a good place to stop.
CHUCK:
Alright. One other thing, I forgot one announcement at the beginning before we get into the picks. And that is that I am going to be in Las Vegas next week. I will be at New Media Expo where they are going to be giving out the Podcast Awards. We were nominated, so you can watch it live.
JOSH:
Thanks everyone for nominating us! [cheering]
CHUCK:
Yes, and for voting during the voting. A lot of those shows are pretty popular but I think we have a fairly engaged fan base. So I think we really do have a shot. I just donât know how good it is.
JOSH:
And by the time everyone hears this episode, weâll know.
CHUCK:
Yes, thatâs true. But anyway, you can go to PodCastAwards.com and see who won. Anyway, letâs get to the picks. James, do you want to start us off?
JAMES:
Sure. My first pick is a link, I believe came up on Parley. It might have been Cory Haines that threw it out, if I remember right, to a video that Michael Feathers did called âThe Deep Synergy Between Testability and Good Designâ. And itâs extremely on topic for the conversation we just had and talks about a lot of the things that we just discussed. Chuckâs question about âI have this small public interfaceâ, âa bunch of private methods under itâ, and âthereâs difficulty in testing thatâ. Thatâs his first example to the âTâ. So literally, watch the first 15 minutes of this video if you want to know that. But he goes on to a lot of things about how testability and good design are intimately related and itâs a lot like the testing chapter in Sandiâs book. So, great video. Then just some fun stuff. I was on vacation all through the holidays and playing a bunch of games. I found some stuff I really loved. So if youâre a video nut and you like 4X strategy games like I am, if hearing something like, âMasters of Orion IIâ makes you wistful, this is a great game thatâs on steam right now called âEndless Spaceâ. And like I said, 4X strategy, a lot like the MOO series. So, if you miss that kind of thing, hereâs a great way to get it back. Combatâs a little different but it grows on you. Thatâs good stuff. The other games I was playing while I was on break were board games. Hereâs a list of some of the great ones this year from the Morning News today. What I love about this list is they give you the Top 10 and tell you how those were chosen but then there are some other âdidnât winâ and âhereâs whyâ. Ilove a âdidnât winâ game because it was too complicated, thatâs my kind of thing. So anyway, Iâve played a lot of these games, theyâre good - Lords of Waterdeep, Love Letter, Eminent Domain. I was playing a ton. So anyway, lots of good games in there if youâre a big board game fan, those are them. Okay.
CHUCK:
Awesome. David, what are your picks?
DAVID:
I said I was going to forfeit my picks in the interest of time and Iâm going to stick by my promise.
CHUCK:
Okay. Avdi, what are your picks?
AVDI:
So during my extended transformation into my sandworm form, I found my eyes were particularly sensitive to light. So, I listened to things instead. So I got a couple of podcast picks. First is a single episode of Pennâs Sunday School, where Penn Jillette talks to George Takei. He talks a lot about Georgeâs experience in the Japanese Internment Camps; really, really interesting stuff about a chapter of American History that probably most people donât know enough about. But then he also talks a lot about his experiences coming out and stuff like that, really good stuff. Also, I listened to a bit of Dan Carlinâs Hardcore History. Thatâs a fun podcast. Oh yeah, one of my favorite podcasts for a while now on a rare occasion when I find time to listen to one is the Infinite Monkey Cage from BBC Radio. Itâs a hilarious Science program. I donât know how to describe it but itâs really, really good.
JOSH:
A hilarious science program. Sounds like a great description to me. [laughter]
SANDI:
Iâm signed up!
CHUCK:
Alright. Well Josh, why donât you pick?
JOSH:
Okay. In the interest of brevity, Iâm just going to do one pick this week and thatâs, this is something from the Apple Apps Store and itâs called âMarkedâ. Iâm trying to get my business partner to do a more development type workflow around the content that goes in our applications. So, Iâve shifted a lot of the pieces to be able to work off of Markdown. Heâs not technical. So, he doesnât use TextMate and he doesnât have all the tools to be able to do things, so I found this nice little app that is basically a Markdown preview app. Itâs at MarkedApp.com and it links you to the store for apps, in the apps store. But itâs great. You can just, you have this little window up on your screen all the time and then you go in your favorite text editor. I told him to use iA writer because thatâs nice and simple and doesnât do crazy formatting like pages or what have you. But Marked is great. You can hook it up to your own Markdown renderer. So, if you want to use Github flavor for your Markdown, for example, itâll do that. You can hook in your own style sheets and you can see what things will look like when they get rendered. And this is really great. Itâs a nice light way to see what Markdown is going to turn into. It even will just sit there and watch the file. So, you donât have to switch over to the app and hit refresh or anything like that. So Marked, thatâs it.
CHUCK:
Alright. Iâll go next and then weâll have Sandi give us her picks. So my first pick is something that I sorely missed being at my in-lawsâ house, and that is my Herman Miller Aeron chair. I had my chair fall apart. I posted the pictures on Twitter. You can go dig back through the archives. It was just before Christmas when it fell apart. Anyway, I got a headrest for it, the whole nine yards. And itâs amazing the difference that a chair will make. I didnât realize just how much better I feel sitting in a chair thatâs built to be ergonomically healthy versus not. So, I definitely love that. The second thing that Iâm going to pick is something that I am working on right now and that is that Iâm going to be starting another podcast. Weâre going to be talking about IOS development. So, if you know people that you want to be on that show, then Email me, chuck@devchat.tv and weâll be getting that show together and be talking about that kind of stuff.
DAVID:
You need an intervention?
CHUCK:
I know. Sandi, what are your picks?
SANDI:
So before I give my picks, let me complain that Iâve been on the fence about that chair and you just cost me $850. [laughter]
CHUCK:
Youâre very, very welcome. Itâs amazing the difference itâs made for me.
SANDI:
So, I should thank you now?
CHUCK:
Yeah, I got the one with the, what do they call it, the lower back support?
SANDI:
Yeah, the lumbar.
CHUCK:
Yeah, the lumbar support.
SANDI:
I might go after this and get it. I really have been on the fence and I need it badly. So, thank you for that pick. I have two picks. One was directly related to my ability to get the book out the door. Itâs called BubbleTimer.com and itâs an incredibly simple website that lets you list things that you want to do or donât want to do and fill in a bubble chart like a school test-taking bubble chart in 15-minute increments. So you can say, âI want to spend less than four hours a week watching T.V.,â or, âI want to spend 15 hours a week working on the book.â And you just bubble off the cells when you do it. For me, for a project that lasts a really long time, itâs really difficult to ever take time off. And being able to bubble in, being able to really simply track time and know that, âNow, I can rest because Iâve done all that I have to do this week. I donât have to be on it or feel guilty about it all the time.â It was incredibly psychologically powerful to be able to do that. So, I recommend it to everyone who either wants to stop doing something or wants to do a really long term project but feel like they get to have a break now and then, BubbleTimer.com. The next thing is, itâs Fall in North Carolina. So, I got to get my Gutter Cleaning Robot out. And I think everyone should have one. So, Iâll post a link in the show notes. I get to put the ladder up on my house one time and put the robot in the gutter and drive it around. It is really fun. I can recommend it. [crosstalk]
JOSH:
You didnât get the Skynet interface upgrade that letâs the robot get driven by the satellite video?
SANDI:
I would. That would be totally cool. Putting a 24-foot step ladder on a two-storey house adds an element of danger that you just donât want to miss.
JOSH:
Nice. [laughter]
JOSH:
Been there, done that, nearly fallen.
DAVID:
Extreme Housekeeping!
SANDI:
Get the robot.
CHUCK:
That sounds cool. Weâll go ahead and wrap this up. Thanks again, Sandi, for coming. This is honestly one of the best episodes that weâve done. Itâs just been really fun to talk to you.
SANDI:
You guys were fun. Itâs been a delight.
JAMES:
Thanks.
JOSH:
Sandi, put in one last plug for your book.
SANDI:
Practical Object Oriented Design in Ruby. [crosstalk]
JOSH:
Whatâs the website?
SANDI:
POODR.info has links that will take to every place that sells it.
DAVID:
She embraced the POODR. Thatâs awesome.
SANDI:
Sure. That way, you donât have to remember whether itâs practical or pragmatic. JOSH: And Sandi, do you have any speeches, you said youâre going to be speaking at BaRuCo which is, I guess, mid-September in Barcelona. Do you have anything else lined up this year yet?
JAMES:
Yeah, sheâs coming close to me.
SANDI:
Yeah. Iâll be at ConFoo in March, first of March. Iâm going to Ancient City Ruby in St. Augustine. I submitted to Rails Conf, so I hope to be in Portland. Oh, Iâm going to LoneStar.
JAMES:
There you go! Thatâs close to me.
SANDI:
Iâm giving a keynote at LoneStar so that will be new territory for me. And then, Iâm drawing pictures for BaRuCo. So yeah, come see me!