DAVE:
I wanna close down 19 pubs with you guys. [laughter]
MATT:
Yes. Exactly.
DAVE:
And I don’t drink. [laughs]
KEVIN:
Well, nor do I. But join us for a cup of tea anytime.
[Hosting and bandwidth provided by the Blue Box Group. Check them out at bluebox.net]
[This episode is sponsored by JetBrains -- makers of RubyMine. If you like having an IDE that provides great inline debugging tools, built in version control, and intelligent code insight and refactorings, check out RubyMine 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 78 of the Ruby Rogues Podcast! This week on our panel, we have Avdi Grimm.
AVDI:
Hello from the top of Mount Ararat.
CHUCK:
We also have David Brady.
DAVE:
Good morning! And if the opening show quote was from me, I didn’t say it.
CHUCK:
We also have Josh Susser.
JOSH:
Hey. Good morning from sunny San Francisco!
CHUCK:
We have James Edward Gray.
JAMES:
Good morning everybody!
CHUCK:
And I'm Charles Max Wood from devchat.tv. We also have a couple of guests; we have Matt Wynne.
MATT:
Hello!
CHUCK:
And we also have Kevin Rutherford.
KEVIN:
Good afternoon.
CHUCK:
All right. So before we get started, we have picked up a couple of segments. The first one is a contest that we are running, it’s the Ruby Nuby and James is going to talk about that for a minute.
JAMES:
Yeah. I just wanted to say the Ruby Nuby contest is over. We got all your submissions. We didn’t respond to everyone, sorry. We did get them though. And I'm putting all of the links into a gist, which we will link to in the show notes. So please just go there and look and make sure we did catch your video. If you don’t see it in there, then fork the gist or something and add it in case I missed it. You should see your videos there and then give us some time to look through them and debate about who is the coolest of them all and we will let you know.
CHUCK:
Yeah and if you didn’t submit, feel free to go and watch them because some of them were kind of clever.
JOSH:
Yeah and just thanks everyone who did a video. Like everyone who put time into it. It was great and I have found everyone worth watching.
CHUCK:
Absolutely. We also have the Best of Parley from Avdi.
AVDI:
Yeah. So on our mailing list for the listeners to the show, my favorite thread by far, this past week was a thread called “Life after POODR”. That is Life After Practical Object-Oriented Design in Ruby, the book by Sandi Metz. Somebody asked, “Where do we go from here? What are the best ways to better improve our knowledge and understanding of our design? Being skilled at changing one design to another and at writing high value tests?” A lot of people had some fantastic advice.
Katrina Owen had some particularly terrific posts in there. So, totally worth checking out.
CHUCK:
Yeah. One other thing that I wanna mention and you are probably going to get a short segment on Halloween or the day after, we have been nominated for the “Podcast Awards”.
JAMES:
Woohoo!
JOSH:
Yay!
CHUCK:
They are going to have a big ceremony for the winners at New Media Expo and I’ll be speaking there. It’s in Las Vegas in January. Anyway, we need your help. You can vote every day, once a day at podcastawards.com for the show. And whoever gets the most votes wins the nomination. So, go to podcastawards.com, find Ruby Rogues and give us a vote.
JAMES:
And you guys are Ruby all programmers that listen to the show. So, if we don’t win by a landslide, that's actually sad because it means you guys didn’t do your job of writing scripts to launch EC2 servers to get-- [laughter] We are going to be incredibly disappointed.
JOSH:
OK. But actually, they have a lot of security measures in the voting and don’t do that.
CHUCK:
Yeah. Please don’t cheat. Just go vote.
JAMES:
Don’t listen to him.
DAVE:
Our goal is to lose by disqualification.
JAMES:
Exactly. Better to burn out than to fade away, right?
CHUCK:
Yeah. So anyway, it’s really good for the show; it helps us out and we will really appreciate it. And we are the underdogs in this fight.
JAMES:
Chuck, why do we have many people with great accents on the show today?
CHUCK:
Well, we had a request to talk about “Hexagonal Rails” and so we got Matt on because he is the guy.
DAVE:
Naturally just actually attracts people with wacky accents.
AVDI:
OK. I have a question about Hexagonal Rails; does it take a special kind of train wheel to ride on a Hexagonal Rail?
JAMES:
That's a good question.
DAVE:
No. Just bumpy.
AVDI:
[laughs]
JOSH:
I wanna know; do I have to use hex paper to do my system architecture?
JAMES:
You should use hex paper anyway because it’s cool.
CHUCK:
Wait, who are you hexing?
DAVE:
I wanna know what the movement class is by EC2 server. [laughter]
CHUCK:
Geez. Make it stop! [laughter]
JAMES:
So Matt, can you please define “Hexagonal Rails” for us?
MATT:
That's interesting. So I took the term from—Kevin introduced me to the idea of hexagonal architecture. And at the time, I wasn’t really listening to him (as quite often happens). And then, a while later I re-read Growing Object Oriented Software, because I was really sort of puzzling around looking for ways to make my Rails app better. And so, I kind of coined this term for talk. So the definition, it’s about trying to decouple the core, the heart of your application -- the bit of it that's interesting and unique. And decouple that and separate it or put what Michael Feathers might call a “seam” between that stuff – the good stuff -- and then the bits the you need to be there in order to make it appear on the internet, using Rails.
JAMES:
I re-watched your talk at GoGaRuCo this morning and--
JOSH:
GORUCO.
JAMES:
Huh? Did I say GoGaRuCo? Sorry, my bad. Sorry Josh, I didn’t mean to, you know, improperly credit you there.
CHUCK:
Yeah don’t give Josh any credit he doesn’t deserve.
JAMES:
Yeah. Josh I don’t understand why this great talk wasn’t at your conference, but we can discuss that later.
JOSH:
[laughs]
JAMES:
I re-watched it and I really liked the part where you talked about how… at one point you are showing how the controller has this inner mingled logic, right? You’ve got the logic of your domain in there, whatever business you are doing. But then you are also talking about how there is the logic of the web stuff right? Let’s redirect you or let’s renders this page. And you talked about how those might need to change in different rates. You know, the weby stuff and the businessy stuff and why you were separating those out. I thought that was really great.
MATT:
I think it’s something that I have learned from—so I've known Steve Freeman for a long time and he is one of the authors of the GOOS book and you had him on a few weeks back. And Steve is really big on this idea of not mixing up the names. So, every object you should be clear about which domain it’s operating it. And I think we see it a lot with Rails controllers -- they are doing lots of different things and they sort of attract lots of different behaviour and it makes them complicated. And they just become these kind of magnets, don’t they? For just extra behavior that keeps kind of getting slapped into the controller actions because you can’t really see where else to put it.
CHUCK:
So is this the architecture that Alistair Cockburn talks about ports and adapters and stuff?
MATT:
Yeah this is synonymous.
KEVIN:
His original name for it was “Hexagonal Architecture” simply because the first time he drew the picture of it, he drew a hexagon. But then on the c2 wiki, he actually said that he thought that that was a stupid name and he changed it to “Ports and Adapters”. But I was stuck to the Hexagonal one because I found that people kind of latched on to that picture more readily. It’s more accessible for people who don’t know what it is.
MATT:
So our most succinct definition of what Hexagonal Rails is really the attempt to apply Alistair Cockburn’s and idea of Ports and Adapters or Hexagonal Architecture in a Rails application. That's what it’s about.
CHUCK:
Right. So I'm still not clear on what the Hexagonal Architecture is and the problem that it’s trying to solve. Can you boil it down a little bit further?
KEVIN:
So, back in the good old days, we are all taught that layered architectures were a good thing and we are all beaten up if we can have a three layer architecture separating the user interface from the business logic from the persistence layer. But, Alistair recognized that there were two things wrong with that; one is there is a fundamental asymmetry in it because being a stack, it tends to cause downward dependencies and we tend to get applications that are stuck sitting on top of a persistence layer or a database or whatever that we can’t change. And what that means is that, that asymmetry sort of bubbles up all the way through and what Matt was talking about earlier on in controllers is kind of a symptom of that. That dependencies on the data base the ORM, whatever bubble up through the layers. And so Alistair said, “Enough. Let’s put the symmetry back. Let’s make the domain model the center of our world and let’s focus on matters being the most important thing. And the object in there should be independent on any technology; they should be independent of any real world concerns. And in order for them to communication with the real world and for the real world to communicate with them, we should surround this domain middle with a bunch of adapters. So, an adapter for HTTP, an adapter for e-mail, an adapter for persistence, whatever the sort of technological concerns are or the real world concerns that would allow the rest of the world to interact with those domain objects. Stick that as adapters around the outside.” So Alistair’s picture was a hexagon in the middle, which contains your domain objects and a larger hexagon around that. And then the gap between the two hexagons are series of adapters that connect the domain objects to the outside world. Now, that's kind of just moving the deck chairs on the Titanic until you also add the stipulation that the adapters must not be known about from inside the middle – from inside the domain. So, the domain must have no dependencies that go outwards.
JAMES:
I think I have a different pretty good real world example that comes up a lot. I mean, you guys have mentioned that controllers and obviously they tend to like ---. One of the things that used to be really popular and I think it’s finally getting unpopular, which is a good thing is that, in an Active Record model, we used to do like after create callbacks to send the email, right? Like, “Oh, yeah. You signed up, so here is your email about our welcome email.” or whatever right? Or “Your thing is created, so here is your receipt or whatever.” And that turns out to be pretty bad right? And you feel it the first time you go in the production console and you are mocking around and you wanna create some record, without sending the email right? You run into it and it that those things are now irrevocably tied together and you have to jump through hoops to do that, whereas there separate things that shouldn’t be you know, tied together.
KEVIN:
Yeah. So you have created dependencies in the wrong direction from your domain logic out into technology concern. And that means you can’t change the technology without breaking that dependency or changing that dependency. And if you get the dependencies in the correct direction, i.e. coming inwards, so the adapters depend on the domain objects and not vice versa; that means you can switch out the adapters and replace them with different ones, which is really useful for testing, of course. The main thing about Hexagonal Architecture is that it just brings that simple idea to the fore front – the idea that whenever we are testing our code, we always switch out the ORM; we switch out the mail technology or whatever and replace it with stubs or fakes.
MATT:
Yeah and I think that's actually one of the key drivers behind the architecture right? For when I read his original paper, he was working with yeah, databases which making his test suites slow, so they were using Fitness where we might use Cucumber today. And also with GUI – sort of rich client GUI, they just couldn't automate. So, the idea of the adapters was that they could plug-in the tests as another client of application certain ways they plug in the GUI and have this nice side effect that it could also plug in in memory data bases instead of this base data base that makes test runs so much faster. And actually, that is something that as Rails programmers, we could definitely benefit from. I mean, who here has suffered from a Rails code base with slow tests that depend on a database. Anybody?
JAMES:
That never happens.
CHUCK:
Never.
DAVE:
No.
JOSH:
Who uses a data base anymore?
JAMES:
[laughs]
CHUCK:
I use a space base.
JOSH:
So, is this what you call “dependency inversion”?
KEVIN:
You need it to implement it. Yes. You need to invert any bad dependencies that are going outwards from the middle. So quite often, the domain objects will want to send messages out to the ORM or to the user, or the email or whatever and you have to use dependency inversion to do that. But that doesn’t mean that using the dependency inversion tool or any of that none sense, it just means using duct typing or spaces if you are using static language.
AVDI:
I have a question about that. One of the most common ways I see dependencies going outwards is when something in the domain logic needs to know something about the current session. Most often probably needs to know something about the current user, who the current user is. If the current user matches this other user, then do logic A, otherwise do logic B. But sometimes other things about the session, like what is the current socket ID for pushing web socket notifications to the current user that's looking at this controller right now. What are some of the strategies that hexagonal architecture suggests for dealing with that?
MATT:
Is it my turn Kevin?
KEVIN:
Yes it is. [laughter]
CHUCK:
I wanna see the score board they have.
MATT:
So, I think the thing is when you get into this idea that there is a core part of your application that you should try and keep it pure. And if it needs to be able to something from the outside to ask it questions like, “Who is the current user?” or “What is the idea web socket we are talking to?” then you need to pass that stuff in. So you are making dependencies explicit, I think it adds a lot of clarity to the code. What I see a lot in Rails apps, I think partly because we are so used to having the generated Active Record Model siting in the name space, we get all these hidden dependencies on. Because effectively, like if you create a capital U User class, then from active record, that is a global variable. The constant User is a global variable and everywhere you do, you know, I don’t know. So I guess it will be unlikely that you will set user.current but people do things like that, right? And every time you are calling user.findbyname or whatever, you’ve got a dependency on that global variable. And those dependencies can get kind of scattered around. It’s very difficult to see where all the calls into that user class might be coming from. And I think if you get in to this idea that if you need to call an object, you have to pass a reference to in, then it just got to make your code clearer. It’s easier to see where the dependencies are. It’s easier to see when you are adding dependencies and coupling in to the code.
KEVIN:
So this also comes back to what you were saying before about simplifying the controllers and getting the domain logic out of them and pushing that down into a different name space or into different objects that don’t know about the fact that they're being dealt with from an HTTP request. And pushing that logic out forces you to create that API and forces you then to give explicit names to all of those things in that API; which definitely benefits readability and program understandability. But they are also has other benefits as well. For example, it starts to allow you to write, for example Rake tasks that can do the same thing as your controllers, which means your Rake tasks becomes another adapter sitting on top of your domain object and doing stuff thought that API.
MATT:
Yeah and I actually found as well that you can be doing things in an IRB prompt and in Rails console, sorry. That the kinds of things that controllers can do, but because the controllers are very lightweight and just delegate into the domain, model you can pick pieces from the domain model and you will be doing those things from the console as well.
CHUCK:
So I have to ask then, it sounds like you have domain models and then what we consider Active Record models as kind of two different things. How do you manage the interplay between the domain models and the persistence models (for lack of a better term). Do you ever blend them so that they are the same model or do you have a strict separation there?
MATT:
So, I'm going to say (and I said this in that talk), I haven't got like the answer to his at all; I'm figuring this out. And in the code base, in the Rails code base, most to this is still a mess. I've still got this big, ugly Active Record models that I'm trying to kind of-- it’s like they sitting on my lawn, having a party and I would really like them to go away and sort of go in to the back of the garden and because they are making a mess but, they are kind of there and I got to deal with them, you know? They are sitting there right in the root name space of my code. That's one of the things that annoys me the most actually is I've got this user class that’s squatting the root name space and actually I’d much rather have a plain old Ruby object that's my user class, but unfortunately, the Active Record model is right there. So I think without trying to widdle out the question, I haven't got a clear strategy for it. I think Kevin, you’ve been talking about this sort of the memento pattern haven’t you? Having the Active Record models the simplest possible and really just concerned with modelling the database and then putting all the other behavior elsewhere.
KEVIN:
Yeah. I mean we kind of discovered this, didn’t we? When we did this talk at Scottish Ruby Conf, we got a lot of feedback from people who wanted to try different ways of separating out the Active Record from the domain logic. But nobody yet has—as a community we haven’t established conventions for doing that. And I think in the next 12 months, we will see that happen. And one that is certainly a favorite of mine at the moment is the one you mentioned Matt on, I think Avdi’s mailing list last week, the idea of explicitly creating a domain object to represent the repository of your user base let’s say and having methods not here that allow you to get users back. But the user objects that you get back are wrappers for the Active Record objects. So, again if you think about the dependencies, inheriting from Active Record base creates a dependency going outwards -- going towards the ORM and therefore, towards of technology adapter. That means that the user object, if it is an Active Record object, can’t be a domain object. It can’t be the middle, in the strict sort of interpretation of the hexagonal architecture pattern. And that's part of the reason why Rails apps get in to such a spaghetti mess, because that object depends outwards on Active Record and yet, we’ll see it pop-up all over the domain and hand up in the controller as well. We are not managing the dependencies in a way which allows us to switch out concerns easily. So, my preference at the moment is to have absolutely no logic in the Active Record models whatsoever and to have a repository object sitting in the domain, which manages the finding and creation and deletion of those things and wraps them in a domain object that the rest of the application uses to represent.
MATT:
The nice thing about having that on—
JOSH:
Guys, I wanna jump in here. I've been good and quiet most in this thing, but—
DAVID:
I'm next.
CHUCK:
[laughs] I was going to jump in too, but go ahead.
JOSH:
So, for the last year, I've been hearing a lot of people talking about doing exactly what you are saying. Where basically demoting Active Record model classes to be nearly persistence and taking all of the logic out of them that you can and putting business object or business logic in pure Ruby objects or plain old Ruby objects. And I have to say that, while that sounds lovely in some regards, you are not doing Active Record at that point. And if you are going to go through all the trouble to do that, use a different ORM.
DAVE:
Or go with active model. Yeah.
JOSH:
Yeah. Or use some other technology. It just seems like there is this very difficult impedance and mismatch, that you are now putting on top of something that's already in impedance mismatch between objects and relational technology. And if you wanna go that way, invent a different ORM that works the way you want it to work or do something else. But, I've seen all of this stuff where people are talking about doing this. And it’s a valid response to real problems that people have with this in Active Record in a certain way.
MATT:
I don’t really find Active Records a pain to use for getting in and out of the database – its good at doing that. I just feel uncomfortable when it keeps on sort of sucking in, hoovering up all of the domain logic. So, as an API for querying databases and persisting data off into databases, its fine; it’s good at that. But like the stuff that James mentioned early on, when you start using call backs to manage other events and things, it just-- I mean I know what you mean because the Active Record pattern isn’t it.
JOSH:
Yeah.
MATT:
Make your own domain objects also be persistable.
KEVIN:
But also, the original definition or description of the Active Record pattern says very clearly, as soon as you have any interesting stuff going on, stop using Active Record.
DAVE:
Let’s be clear that Rails’ Active Record class has about 70% to do with the Active Record pattern.
They are wildly different things.
CHUCK:
The other thing that I wanna point out that Kevin has kind of mentioned here just for a second is that, yeah, as soon as you have something interesting going on, yeah, peel it out and you know, so if I have a user and then I find that I am taking care of some other concern or job in there that doesn’t really fit with what the domain logic for a user should be and whatever that responsibility is, doesn’t necessarily require persistence and by all means, move it on to a domain model that's a plain Ruby class. If you need some of the active model behavior, you can pull that in. But, ultimately I don’t think it’s an all or nothing proposition here. I think it comes down to what makes the code most maintainable, readable, usable, workable that kind of stuff.
KEVIN:
I think that is right. I think as a community, we are all still exploring what to do here and how to get this right. And I don’t think everyone has the answer.
CHUCK:
Yeah. But you don’t feel the full pain of your experiment until you take it all the way. And so I think there is some value in building a project where you fully divorced the domain logic from the persistence logic, just to see where that hurts and then see if you can find a proper middle ground that fits the problem that you are trying to solve.
DAVE:
I think there could be some agreement between Matt and Josh in that, the impedance mismatch can be kind of represented by the fact that -- how did Matt put it -- the Active Record starts hoovering up the rest of your domain. I actually want to take Chuck’s question about how do you do this and simplify it. So, I think it’s fair to say that most of our listeners are smarter than me. And I'm having trouble with actually flowing the code. You talked about inverting the dependencies, you talked about decoupling these things and I've worked with systems where the controllers almost completely empty and I do have this memory of being able to open the Rails console and stuff just work. You can just grab something and manipulate it because there is nothing in the controller, absolutely lovely. I wonder if one of you could just take moment and just walk us through the flow of the Port and Adapter or the one side of the hexagon and let’s take our user, maybe its capital “u” user, maybe it’s coming from somewhere else. But let’s say I wanna save this user and he's got some attributes on him that we wanna save and there’s a database off of over here somewhere and I built this library can talk to the database. Instead of inheriting from Active Record and telling user to save, what are the ports and adapters? What things do I have to plug in? And what things do they have to give each other via interfaces, explicit or duct type? Can you just walk through the flow of saving an object so that-- we do have some newbies that listen to the show and I know some of these is going over their heads, because I'm having hard time keeping my --- into it. But I think if you can sketch just one interaction in and back again, that it would make it clear. Does that make sense?
KEVIN:
Yes it does. I think for me, I don’t know about you Matt, but I would back up a bit and ask why the user is being saved. So, let’s imagine the user has edited his profile. Let’s say we got a use case where the user can edit their profile, so they come in through an edit form. And they’ve now submitted that form. So we are in to the, whatever controller we’ve called it. Let’s say it’s the user’s controller with the profile’s controller or whatever, and lets imagine that in our middle hexagon in the domain, we have a user base which will find the user for us; find the user object.
DAVE:
So user base is a collection of users that will find this user?
KEVIN:
Yes. So it’s the domain abstraction that represents all our current users.
DAVE:
OK. I was just clarifying that it was not the user base class. I'm sorry, base class object in a base ---. So yeah, user base is the collection of users. Gotcha.
KEVIN:
So, rather than using the user class to be that collection, we’ll have something else that's separate. And the object it will give back to us will be a user object, which hidden deep inside it will have some reference to an Active Record object. Let’s call it user data or something like that. So, the used case is an action on that user object to set its profile to something new. And I'm not sure I will have the explicit save visible to the controller. I think setting the profile would be a persistent activity that would be hidden inside the user object or in the user base object. And so, the controller would simply arrange to invoke that action on say, the user base or the user, whichever we chose. And arranged to be notified of what there succeeded or failed either by -- my favorite way of doing that is to pass in prox. That no matter what you a lot more work with perhaps you can go through that.
JAMES:
Let me try an idea here. I think I sat somewhere kind of that in between Kevin and Matt and Josh, in like the strategies I'm currently trying. So, what I've taken to doing like I believe in Josh a little bit in that, you know, Active Record is good for what it’s good for. So just to give an example, if I have a user and they have a first name and a last name field stored in a database, then it makes perfect sense to me that the method full name will be on that user. Because it’s basically just a synthetic field that just doesn’t happen to be in the database. But it is still there, it’s still field of that thing right? And so the taking everything out of the model doesn’t make sense to me. Because you still have certain things to sense to be in that persistence adapter which by the way, the difference in how I view do it. I’d view the class that Rails creates for me, the class user that inherits from Active Record base, I viewed that to be my adaptor between me and the persistence layer. And I treat it as such so my current technique is that I can put whatever I want on that user class that is basically like a class method. And that class method, can then bring up instances and manipulate them or whatever or return them to me. So basically, what I'm trying to stop on myself from doing is the horrible feature you get with the user class which has like 500 instance methods on it for doing all those things, right? So, I might have a class method on user that was update profile to stay with the same example. And that method may take in ID and then hash of profile changes or something, and it may find the user for me, make those attribute changes, try to save like Kevin I’d rather have the controller not doing that. And that method is my adaptor to that thing and then I don’t pile on the instance methods, I just go through those class methods so that the user class object kind of becomes my service sitting that on top of that. If that makes sense.
MATT:
That basically how I do it. I think the different is I would probably wrap the user class with another object so that behavior is in a separate object, so I can completely see if I ask that thing what its methods are, those methods are all methods that belong in my domain rather than being mixed up with the methods that are provided by Active Record, so I haven’t got this sort of temptation to call, “Oh well, sod it. I’ll just call find by email and username.” or something like whatever the provided Active Record methods are. There was something in Avdi's book I think about Active Record being an infinite protocol, which I really liked the idea. And not having that infinite protocol kind of leaking out in to the rest of your code base. Yeah I just find it a bit scary but maybe it’s my C# background.
JAMES:
I think I see where you are going with that, and I do understand reason to have the separate class, but then I find myself tripping over things like I just wanna hand this object down to a form for tag and I don’t wanna have to implement all the active model scaffolding between my object that's hiding a user from me when Rails already does all that for me. Does that make sense?
JOSH:
Right. So here's the thing that I've been thinking about during this conversation and that's a lot of the conversations we’ve had in the last couple of months about this kind of stuff address the fact that object oriented design and the patterns that we use are there to reduce the cost of changing code –code that you never could touch again. It doesn’t matter how complicated and unwieldy it is. We can call it an Omega Mess like Sandi Metz named it and not worry about it. But we need to use design to have the code be something that can respond to changing requirements on it. And over the life cycle of a piece of software as the requirements change, the demands on the design changes, so you know, Matt in your talk at GORUCO, you start off by saying, “Hey we do Rails and it will change the world.” and it’s a great start and it keeps you happy for a while. And then as things change and your software gets more complicated, then you need to start using different approaches to make the software tractable and keep it from becoming calcified and unchangeable. The big question that I have about the Hexagonal Rails approach, just like I have with many of these other higher level architectural approach is when is the right time to start worrying about these concerns? Obviously Rails can change the world works just fine and you can spend your first month or several months working on a project very easily without having to go to great lengths to worry about how expandable your architecture is. So, from a practical point of view, when do you have to start worrying about this stuff?
MATT:
Yeah, I think that is a really interesting quest isn’t it? Because the experience I talked about there is this one where like it’s so much fun when you first start working application and it just sort of gradually starts to creep up on you. The test run goes for like 3 minutes to 5 minutes to 10 minutes and then 15 minutes.
JOSH:
Right. But then in the other hand, if you started by building everything as ports and adapters, then there would be so much overhead in getting everything going that you would never get started.
MATT:
Well, certainly at the moment because we don’t know how to do it. But--
KEVIN:
I think that is the thing, were still norming on, we still looking for ways to solve these problems. And that's because we don’t have the answer yet then it’s not going to be easy because everyone in the world is at the bleeding edge.
MATT:
I think that is part of it. But I seriously think that there is a point there and I think it’s from Kent Beck’s blog post about, I forgot the terms he used now he talks about a modular architecture and a connected architecture. And a connected architecture is one where kind of it’s like you are in a workshop and you got all the tools just kind of splayed out on the floor. So, you need a screw driver, screw driver is just there just pick it up. Hammer is over there, it’s just here. You need the saw, it’s just down there and just put it down. And that's fine like if you are just there in the workshop in the afternoon but actually if you are in there everyday and you are doing different kinds of work in there, and you know, sometimes you are working on machinery that needs and sockets and sometimes you are doing soldering, you have to sort of tidy the workshop up. And so, the connective architecture is great when everything is sort of --- and you can just lay your hands on it. But when things start getting bigger I suppose, it’s when you need to start organizing them. So, I don’t really know what's a good rule of thumb but, yes speaking from experience, I suppose when your test runs for more than about 6 or 7 minutes, you wanna start worrying.
JOSH:
Wow. 6 or 7 minutes is when you start worrying? [laughter]
JAMES:
Yeah, I worry sooner than that. You have a higher threshold than me.
JOSH:
Yeah.
DAVE:
7 seconds is the Twitter threshold. If a --- takes longer than 7 seconds, I check Twitter.
JOSH:
In Smalltalk best practice patterns, Kent Beck had a number of hard numbers that he used for the rules of thumb but, he made them hard and fast rules in his recommendations of don't use this more than 3 times in the project. If you are doing this other than 5 times, it would get you in trouble. At least in looking at those kinds of problems, Kent was able to come up with some pretty specific recommendations about things. So I guess maybe about time we should be able to do the same thing of, “OK when you have more than 12 models, you need to start working about these kind of things.” Or If it’s not the classes, it’s the protocols and interactions and say, if you draw your graph of models and dependencies, when the connectivity gets over certain threshold, then you have to worry about it.
MATT:
That would be the --- by the number of method calls. The number of calls across the protocols I think. Sorry Kevin, carry on.
KEVIN:
I was going to say exactly the same thing – it’s in general being aware of code smells when you are introducing duplication across your controllers; when you’ve got rake tests that duplicate controller logic, when you've got models that duplicate logic, then it’s time to start refactoring. And I think certainly or me, hexagonal architecture is something to refactor towards rather than something to start out with.
JAMES:
I really think that's the most important you've said right there Kevin, is I read a great article the other day about how if you give a kid a big tub of Legos and tell him to build something, almost always, one of the first things they do is spill all the Legos on the floor or the table or whatever. And they are looking at all the pieces and their options and their given ideas and stuff like that and that. And that what Matt talks about with Rails -- change the world and we start with a fresh app and then you start just kind wiring some pages up. To me, that's like spilling the Legos on the floor and you are looking at all the pieces, you are trying to figure out where this connects, where that connects and that, I couldn’t even do a good ports and adapter design at that point because I don’t know. Right? I don’t know what's going to end up, you know, over here or over there. And I agree that it’s something that I want to play around with. I wanna get the app up on so I can poke at it a little and see what's going on and then as I cross that threshold, now I'm like, “OK I know what this part of the app is, so let’s tuck that behind some better interface.
JOSH:
That's the same point Paul Dix was making on the Service Orientation episode about, you don’t wanna build everything services right off the bat because it slows you down and it makes your app more brittle than it needs to be while you are figuring out what actually needs to do.
CHUCK:
What strikes me is that it’s an outgrowth of -- because you are exploring a problem and so when you are exploring solving a domain problem, you just build whatever it is that you have with the tools that you have. And then when you start to explore the complexity problem or the timing problem or the length of time it takes, then that's when you start exploring, “OK Hexagonal Rails or SOA.” Or whatever to make it work in that way, so that it solves that issue as opposed to does it do the right thing.
MATT:
I think it’s also when you are coming in to change the behavior of existing classes because one of the things talks Matt Pryce talks about is that you shouldn’t really ever have to go back in and change an existing class that you have written. What you should be doing is just plugging that into some other bigger concern. But of course, we are so used to doing it, aren’t we? That taking an existing controller and just extending the code in the action or taking an active record model and adding just a bit more behavior. And I think, it’s when you start changing and extending the behavior-- because that's actually like if you just create some bits on the peripheral application that it basically just displaying the database on the web, surfacing the database over the web so you can modify it and you never have to go back and change that. Like, why would you need a fancy architecture for that? It’s only there to facilitate change and make it easy to add more behavior. So it’s the places in the middle of your application, the bits that change the most.
CHUCK:
All right. Avid, were you trying to say something?
AVDI:
Yeah. I was going to say sort of related to this sort of the idea of spilling all the Legos out on the table and you don’t really know exactly how you are going to be putting them together at first and then you just sort of fiddling around with it, seeing how things fall out as you get the initial functionality. I find that more in more on projects; I wind up only writing acceptance tests for a while at first. I don’t write a lot of unit tests at first. And I do this because the point that I'm at is this figuring out how things I'm going to want things to fit together. And there's so much churn in the internal design at that point that I’d be throwing unit tests away left right. I'm curious if you guys have the same experience. If you sort of put a heavier emphasis on early acceptance tests in order to be able to rearrange things. And part of the on that question is I do see beginners a little confused about that they are starting reasonably because a lot of people talking about unit test or starting unit test very early, but then that's kind of tying them to-- not the implementation of those methods, but still trying to like the organization and internal design very early on.
KEVIN:
Speaking just for me, yes. And the reason I will write fewer unit tests at the beginning is usually because I haven't done enough object design. I've just jumped in and started writing code. And very often, that is the right thing to do if we are in the early days of exploring the idea, then I don’t necessarily know what the concepts are. But as soon as I have the time to do object design, that's the time when I’ll be writing the unit tests and making sure those object work properly. So, yes. But I'm never very comfortable with that. I always kind of smack myself about because I've not done enough of that design upfront. I just jumped into writing code.
MATT:
Yeah and I know Cucumber’s own code base suffers from this problem a little bit because we went bananas [laughs] (bananas with Cucumber) just playing with writing acceptance tests to describe every bit of behavior of Cucumber. And we are all experienced programmers; we don’t need a unit test to give use design feedback. And actually, frankly, some of the internals of Cucumber are really a bit of a mess because we weren’t writing enough unit tests. We weren’t getting enough design feedback. So there is that thing that acceptance test definitely gives you lots of room to play around with the design. But I think again, you need to be careful not to just keep playing around and throwing the Lego on the floor and actually remembering that at some point, you need to build something that other people could work on and maintain.
JAMES:
A lot of times I will actually on those early spiking efforts just fore grow the test altogether.
DAVE:
[gasps]
JAMES:
Yeah. I know, I know.
JOSH:
That's fine for spikes. The output of a spike is estimated stories, not code.
JAMES:
Right. It’s trying to figure out how does this hook together or how would I even do this. What would this look like if that did that? And I'm thinking out loud so a test has no value to me because a test is to block that right in place is that, “OK. So this should do that and this proves that does that right?” And I don't want any blocks and I wanna be able to say, “OK, that's really stupid.” Actually what I should do is -- and totally change my mind and then test hinders me in doing that.
MATT:
Can I just say one more thing about acceptance tests?
JAMES:
Yes. Absolutely. Yeah.
MATT:
In the middle part of the Cucumber book, we build a really simple application and the write a scenario. And what I did when I was writing that was the first iteration or the first time scenario goes green, all I've built is a domain model. And the second iteration so we make the scenario fail again by wrapping the domain model in the web interface and then make it pass again. And it’s exactly the same words in the scenario describing—it’s actually the same behavior, but by using different code in the step definitions, we connect it to the first time to the domain model and then second time, we step outside of it further out and connect the prongs to the whole actual end to end web interface. And it really struck me as that's the really key behavior of hexagonal thinking is to think if you write your acceptance tests, could you connect those acceptance tests just to the domain model and would they still be true? So, are you describing behavior or are you describing the implementation of that behavior? So, you know, I click this button or whatever.
JAMES:
Matt and Kevin, have you done any experimenting with SOA? We have been talking about that a lot on Rogues lately and I was just wondering, do you think that leads to a better hexagonal approach because it basically forces you to write the adapters for your services and such.
KEVIN:
I personally haven’t, but I am currently experimenting with CQRS, which is kind of similar, kind of different.
JOSH:
OK, definition?
JAMES:
Yeah, I don’t know what that is.
JOSH:
It’s the command query--
KEVIN:
Command Query Responsibility Segregation. So you have effectively two different apps; one for writing stuff to the database and one for reading stuff. And you have two different models and it’s a lot more SOA than hexagonal if you like.
DAVE:
CQRS stands for everything interesting is asynchronous.
KEVIN:
Yes.
MATT:
The team where I was working where we first gone to Cucumber and we went all the way to three hour acceptance test run, they actually blogged very recently about going down and in fact they might get it to 15 hours and taking it down to 15 seconds. And they have done that by pushing the behavior away into services which they stub out.
JAMES:
Is that Songkick?
MATT:
Yes. Songkick.com. So that's where I was working in when I first got into Cucumber.
JAMES:
Those blog posts are absolutely excellent.
MATT:
Yeah, I really recommend it. If you are interested in these subjects, those guys are living the dream.
CHUCK:
Yeah. We’ll make that link available in the show notes.
JAMES:
Yeah. They are absolutely excellent blog posts.
CHUCK:
All right. I now am really going to cut us off. We’ll get in to the picks. Let’s start off with James this week.
JAMES:
OK. So a couple of quick picks; first technical one, have a look at Xiki if you haven’t already. It’s a pretty neat kind of console environment on steroids, I guess you would say and how it lets you call commands and edit them and mess around with them. There's a really good video about what it’s like and I will put a link to the video on the show notes. Xiki is kind of backed by Emacs I think and to me; it feels very Emacsy in places. Anyways, it’s kind of cool. Check it out.
AVDI:
I beat you to that pick.
JAMES:
Yeah. That's right. I saw Josh say that. Oh, well.
AVDI:
And just for the record, it’s not Emacs based. It does have an Emacs UI but there are other UIs.
JAMES:
Gotcha.
JOSH:
It will be too late for the listeners by the time they hear this, but there is a talk on it at Ruby Conf.
JAMES:
Right.
JOSH:
So maybe soon there will be a video on it that they can watch.
CHUCK:
I was going to say, I'm pretty sure Confreaks is recording Ruby Conf so.
JAMES:
Yeah. The reason to check it out I think in my opinion is that, it’s kind of mind expanding. It may cause your rethink parts of your environment basically is the reason I recommend watching it. But yeah, Avdi was ahead of me in that one so that's a duplicate. It’s OK. I think I'm the only one who didn’t pick Sandi Metz’s book so, there you go. I was allowed one duplicate. [laughter]
DAVE:
This does not count as a pick of Sandi’s book.
JAMES:
Right. I didn’t pick it just then.
DAVE:
All right.
JAMES:
Exactly. For my non-technical pick, there's awesome TED talk “On Being “, wrong which is just totally great. You should really go watch it. It’s hilarious and entertaining and it talks about what it’s like to be wrong and how we are often wrong and why that's a good thing and really about how we should embrace that. And you know, being programmers that we are and often having the ego problems that we do. It’s a great video. So, check that out; it’s good stuff. Those are my picks.
CHUCK:
We don’t have ego problems; everybody else just has problems with our egos.
JAMES:
That's right.
CHUCK:
All right. Josh, what are your picks?
JOSH:
OK. Well, Ruby Conf which I'm going to be hopping on a plane to fly to soon. I’m just going to say that it’s going to be a week later when I’ll be listening to this. So, all the Sandy hurricane stuff is going to past, but there's a lot of people who aren’t going to make it on Ruby Conf because of all of the impact of the hurricane. I just wanna tell you all I miss you. And I know that a lot of people got hurt a lot or badly than just not being able to go to a conference and you know, keep things in perspective. So, not everybody is going to make it there. Anyway, so I have a bit of a rambling pick here. [laughs] off to a good start I see. So, I picked recently fridayhug.com, which the folks at-- I think it’s pronounced Commita put together as a RailsRumble project a year ago. And they were good enough to open source the code recently at my request, so that we could have a go at it. And I've been too busy to do anything awesome with it myself but I had a vision that I shared with the
Rogues Ruby Parley list last week and a couple of people from the list, great thanks, Justin Campbell and Erik Trom stepped up and volunteered to help me whitewash this fence. And we now rubyfriends.com!
CHUCK:
Yay!
JOSH:
Yay! By the time you hear this, it would have been in Ruby Conf. And it’s a way to document community or the formation of community. And so, it’s like Friday Hug, it’s going to be pictures pulled from Twitter with hash tags. So, if you have a Ruby friend, maybe someone you just met at a conference, you can pull out your iPhone or Android and take a photo of the two of you together and tweet it and hash tag it “#RubyFriends” and it will show up on the website.
JAMES:
And the moral of the story is that you should join Parley so you too can do Josh’s work. [laughter]
DAVE:
The most important detail from the story is we officially have minions. [laughter]
JOSH:
That's one step up from fans.
DAVE:
Yes.
AVDI:
When do we get hench people?
CHUCK:
That was politically correct.
JOSH:
You can pay ten character points for hench people.
DAVE:
We need more minions and then we can upgrade them.
JOSH:
[laughs] OK. Anyway, thanks to Justin and Erik for making this happen and I hope that everybody else gets a kick out of the site and that it turns into something handy. OK. That's it for me this week.
CHUCK:
Awesome. Avdi, go ahead.
AVDI:
I think I just have one pick and it’s not a programing pick. As I was waiting for the water in my basement to dry up -- my office is in my basement. I took some time to relax a book, a fiction book, which is practically unheard of these days. I read John Scalzi’s “Redshirts”. I'm a big John Scalzi fan. And Redshirts I think is his latest. Redshirts is a sci-fi novel about those people on shows like Start Trek who's only role in the show is to accompany the away team down to the planet surface where they are then blown up or eaten or fall down a hole or you know, turned into some sort of hybrid monster or something like that. It’s about a group of people in that situation and they come to the realization that this lifestyle is not normal and that there is clearly something wrong in the universe.
CHUCK:
Nice. David, what are your picks?
DAVE:
I just have one pick today; it’s a hardware pick. So I'm kind of moving away from OS X. I kind of broke my arm. The accessibility was such a problem. I end up discovering that a Linux computer accessing my Mac’s was a better keyboard driver than trying to get the OS X to drive my keyboard and my foot pedals correctly. So, I've been flirting with switching to Linux for a while now and Apple makes sexy hardware I just-- it’s just really hard to get away from that. And Asus has introduced a Zenbook ultra-book. The Zenbook prime; I have the-- I’ll put it in the show notes. I have the UX31A-DB71. That’s their high end 13-inch Zenbook. It’s a solid competitor to the MacBook Air. It’s less than three quarters of an inch thick. It’s under 3 pounds. The battery lasts 5 or 6 hours. It’s got a full 1080p HD display. OK the 13-inch retina is like 2,600 but 1980x1080 or 1920x1080 you can see the pixels, but you have to squint. And that's good enough for me -- especially as eyes get older. So what I found is a $1,400 computer that out computes the MacBook Air. That I don’t have to pay the Mac tax on (which I like). It’s absolutely beautiful. Other people think it’s gorgeous because it’s got that slick, tiny, tiny form factor on it. And it makes it painless to switch to a Windows dual boot Linux-- the days of trying to figure out if your laptop will run Linux, apparently are pretty much over. People are telling me on Twitter and IRC that, “No. You just get Linux and plug it in and it goes.” And that's largely been the case. I’ve plugged in Kubuntu and up she came and it absolutely is wonderful. I absolutely love it. And I started the stopwatch; this pick has taken two minutes now. I'm done.
CHUCK:
All right. I think I'm the last of the regulars to go and I will let our guests go. My first pick is something that David showed me this morning that I thought was just hilarious and that is ghostsingles.com
DAVE:
[laughs]
CHUCK:
And if you go over there-- I mean the whole thing is kind of funny and this was put together by Randy Taylor who is a friend of Dave’s and I. But anyway, you have to go in to the chat room and you have to be part of the chat room for a little while. It’s just really, really funny. And that's all I'm going to say about it. It was terrific. And then my other pick is I was poking around and I ran across a GitHub repository that is related to a tutorial out there on how to build membership site using Rails and Stripe. It’s been put together by – it’s in the Rails apps repository. I'm not sure who is responsible for it. It looks like Daniel Kehoe or something like that. Anyway, the tutorial was like and really interesting. But more interesting to me was they have most of the membership site together. And so, I was going to dig in to that and I wanna give a shout out because it looks like they are contributing both kind of the basic app or something as well as giving tutorial for people who want to learn Rails. So I’ll put a link to the repo in the show notes and then you can go and look at what else is there. Kevin, why don’t you give us your picks?
KEVIN:
OK. Sure. I've got two for you which I hope is OK. The first is kind of technical, kind of not, I suppose. It’s a book called “Metaphors We Live By” by George Lakoff and Mark Johnson. It’s the popular tip of a big research iceberg. Lakoff has this that in our infancy, we learn difficult and new concepts by constructing metaphors and that most of our complex thinking is metaphorical. So for example, he deconstructs all our common language in metaphorical term. So for example, we think of time as being a road or a journey. We talk about looking ahead the future, putting the past behind us, bringing meetings forward, putting things off in to the future. And it’s all metaphorical language based around that journey or road. So, it’s fascinating stuff. And Metaphors We Live By is the kind of popular introduction to that. It’s a great read. And I thoroughly recommend it. And great father for if you use the XP practice of system metaphor. Once you have read the book, you will look at your own language and vocabulary in a completely different way. I thoroughly recommend it. My second pick is the Paleo diet; also called the “primal diet”, the “caveman diet”, the “stone-age diet”. It’s the idea of only eating pre-agricultural fruits. So no, grains, no vegetable oils, no refined sugars. Only things that hunter could eat; so, meat, roots, nuts, berries, leaves, fish. I switched to this. I was ill, seriously ill a couple of years ago and I switched to this diet. And as a result to doing this, I discovered I had an Glutenology which I have never knew about before; which explained suddenly explained an awful lot of things I have been having for the rest of my life sort of thing. So, I have lost a little weight and I'm healthier and fitter. And I think probably the diet has contributed significantly to my health in the last couple of years. So, that's my pick.
DAVE:
That's awesome.
JOSH:
Kevin, I picked I have a niece who is an author. She and her boyfriend do the Primal Palette website. It’s a Paleo blog and they this “Make it Paleo” cookbook came out last year. I'm excited. She and he are going to be visiting me next week and they are going to be cooking a lot for me, I'm sure.
KEVIN:
I’ve got that book. It’s terrific. Thank them for me.
JOSH:
Oh, I will do that.
CHUCK:
Terrific. OK Matt, what are your picks?
MATT:
Right. Kevin just having knocked wheat, I'm going to give Kevin a tool for being able to still eat bread but, he can have wheat-free bread if you like. So I love making bread, it’s one of my favorite hobbies. I live a long way from anywhere. I used to live in the city where I can buy really nice interesting bread. Now I live in the middle of nowhere and shops sells really dull, crap bread. So I learned how to make it myself. The resource I used for teaching myself was “The River Cottage Handbook Number 3”. So all of the handbook by River Cottage is really good if you wanna learn about making preserves about that and the bread one, just worth really well for me as a geek, it explains exactly how the process works about what you are doing to the dough when you are kneading it and you are changing the gluten structure. So it’s a really good book. Really explains to me how bread making works and I highly recommend it. I highly recommend making bread. It’s a great sort of bringing a little bit of the wild into your kitchen. It’s great fun. So, that's my first pick. My second pick is loose leaf tea. I've been practicing tea different development for years. I love drinking tea but I only recently, made the switch from bags to loose leaf tea. And my whole world has opened up, delicious tea. So, yeah, loose leaf tea is my second pick. Right now, I'm drinking Orange Dulce, which is a black tea flavoured with orange. It’s very nice. So that's my two nontechnical picks. I've got a technical pick which is “webmachine”. So I just got playing with it yesterday and I heard about it a while ago. And I just start a little side project yesterday and just picked webmachine. And it’s really interesting framework for writing a web server of some sort. I'm curious about – it’s like a completely blank slate basically for writing something that's surfaced on the web. So I'm interested in the context in the conversation about Hexagonal architectures having decoupled from the concern being on the web. What I might be able to bring using web machine because it just does web stuff and it doesn’t try and do anything else. So it’s really blank slate. So, that is interesting one. Lastly, a little product placement, I thought I’d pick up the “Kensington Si600” presentation remote because I did a bit of digging around a while back to try and find a good presentation remote. If you’ve ever tried to use the remote that comes with Mac to your presentation, you will probably realize that it only works about 6 inches away from the Mac. And this is a really good remote. You can just plug it in to any computer and it immediately tells you what to do. It doesn’t matter which way standing it works. So yeah, that's a nice little product.
CHUCK:
Awesome. All right. Well, let’s go ahead and wrap up the show. We are doing POODR [laughs] (I just thinks that funny) anyway, its Practical Object-Oriented Design in Ruby as our Book Club, so go pick it up and read it. We are going to be talking to Sandi in January if I remember. So, anyway, other than that, I don’t think with have any announcement so we will wrap this up and we’ll catch you next week!
JAMES:
Thanks. Bye!
DAVE:
Kevin and Matt, thanks for being here.
KEVIN:
Thanks for inviting us.
MATT:
Yeah, thanks for having us.
AVDI:
Thanks a lot.