 Okay, let's let's get started Welcome my name is Alistair, and I work at a company in Toronto called Neulogy and It's a great place to work. I've been working there for about five years on a code base. That's about 12 years old It's a really large code base. I think it's about with tested something like 500,000 lines of Ruby on Rails code 300 models like it's a very large code base and when you work in such a large code base names are very important and I think when you're programming in the small You can get away with perhaps poor names But as your program gets larger and larger obviously you have more and more names and you need some kind of system for Generating the names, so we're going to talk a little bit about that today So it's kind of unbelievable to me, but I actually wrote my first program in 1974 and it was in high school and My math teacher decided that we should start having a I think he called it the computer science club or something and We started writing programs and because he was a math teacher. We mostly did mathematical problems and I was in grade 11 and the program that I was probably most happy with was actually solved this It was called the simplex method of solving a system of linear equations represented as a matrix And so we'd we'd sketch out our solutions on the blackboard and then we'd transfer our Program to graph paper and we'd check it fairly carefully and then we transfer it to these cards We didn't have a key punch So we'd use we'd use a pencil and we'd fill out our cards carefully transferring them from the graph paper Put them in an elastic, you know, put an elastic band around them and we put them in a box And the box would go downstairs to the office and at some point There'd be some kind of inter or inter school email system And they would be taken to the administrative building where there was a large mainframe in the basement At some point after that someone would take my cards out of the box and they'd run them through the They'd run as a batch job There'd be some kind of printout because otherwise you couldn't tell what your program did the paper would get wrapped around your Cards Elastic would be wrapped around that be put in the box. It would be sent back to the school board and we'd get it So the compile cycle was about three days so So it's kind of unbelievable how much things have changed since then and I would you know in those days you'd be very careful about you know a small typo or anything like that Right, you'd read your code over many times before you would actually submit it Obviously you couldn't make very much code You know these days I can make much more code. So for myself I Eventually learned professional programming in C and then I switched to C++ and that was a really nice advance and then I switched to Java and These days I do I use Ruby and rails in Postgres are the main tools that I use every day been using those for about five years Now I wanted to mention Postgres Because what's really interesting is that I learned sequel, you know 30 years ago You know it was developed in academia in the 60s and it was first commercialized in the 70s I mean Larry Ellison owes his fortune to really bringing the first relational database into into the commercial world So sequels being something that has been valuable to learn and it's lasted kind of 30 years Whereas my you know my knowledge of Fortran. I don't use anything from that these days I don't really you see C++ job. I don't use any of those So what I what I found over my career is that the the half life of my knowledge is something like five years Meaning every five years about half of what you know is no longer valuable and you're gonna have to replace it with something else however along the way there are those things which I Found a picture of some gold nuggets. I think little nuggets of things that actually have long lasting life And if you can find those you can you don't have to kind of rebuild your knowledge quite so often So that's really what I wanted to talk about today a particular nugget that I think is like super valuable And it's this idea that naming is really very very deeply connected with designing and Also that the opposite is true Designing is very deeply connected with naming and really the two go hand-in-hand And so what I wanted to do today is take you through and a particular example that happened on a project that I worked on about a year ago And I want to take you through all the different steps that I took to improving the design and improving the names Then after we get through the example We'll sort of circle back and talk about some of the theory and some of the practice that you could use on your own program to do something similar so the program is called qCloud and It's used by people on a On an iPad typically and they'd be wandering around a factory doing quality control That's where the Q comes from quality control QC qCloud It's quite a simple application because what happens is people design a form and then people fill out the form And we call that a sheet and the sheet might have several inspections and today. We're going to talk about sheets if you you know if you're on the highway somewhere and you you stop off at a Restaurant and you go into the washroom you might see like a piece of paper on the back of the door in the washroom And it'll have signatures and people's name on it, right? That'll be that's like a that's like a sheet with inspections happening Here's a here's an inspection from This is like a real example from one of the Customers inspections. So there's one inspection. It's the color of the of the tamper strip so The person would be Taking a sample of some product that would have been created and they look at the little tamper strip and say yeah, it is red So that inspection passes There's and there was one company who's processing cheese And they're they're making sliced cheese. I guess out of big giant blocks of cheese and The first inspection they have is called does it smell? Apparently that's one of the ways in which they inspect their product to make sure it's fine The other thing is that you're gonna have to capture a name So we want to know who actually submitted the inspection Who actually did that inspection? So that's a problem. We're gonna try and solve this is the database table for a sheet and It's representing the sheet on the right One thing that's very interesting is when you look at this table you go hmm. There's like a little pattern going on in here There's four columns and there's another four columns that have some kind of repetition So often one of the first places you want to start when you're naming things or looking for design and improving your abstractions Is to notice this kind of pattern of duplication? So here we see some duplication so there's something going on and we want to try and solve this duplication So this is the starting point of our example and we're just gonna kind of work through it And this is really what happened on this project as well So when I joined the team, I noticed hmm. This is seems weird We're missing some kind of concept when you get this kind of repetitive naming You can see the reviewed reviewed reviewed submitted submitted so there's whoever made those column names is basically telling us that they're somehow related But it's not very strongly represented in the application at the moment now What I would say is I would say that the sheet is composed of a reviewed and is submitted something or other It doesn't have a name at this point, right? So we would like to give it a name. So what should we call it? How should we how should we approach this problem? Well, it turns out that in rails there's a composed of Class macro that we can use to actually express the concept of one object being contained with another object When an object is contained inside, it's either zero or one like it's not you could put them You could put it in a separate table, but oftentimes it makes more sense to just have it inside the table The canonical example that they always use and they use it on in the rails guides to is an address Typically an address is composed of multiple fields, but you think of like one address being as part of a bill Or perhaps for your cable bill There's a billing address plus a shipping address something like that and both of those addresses over the same type And you never have you either have no address or one address. So you don't actually need to put it in a separate table so composed of It's for representing a little small object that's sort of hiding out inside another table so this is my My active model object that represents the sheet and this is what I would have to say if I wanted to tell active model that these four Fields are actually the fields of a single object and I would use this composed of Macro and I have to do it twice right because we've got two of these little objects hiding inside The sheet object so you can see the connection between the columns in the database and The value object that I've created here. You can see the class name says attribution event So it turned out that that's what we decided to name this little collection of four parameters We decided to name it an attribution event When the whole project kicked off it was originally called Enable well the product people came up with this name with the rest of the team and we called it enable attributability workflows and As soon as we had the word attributability we realized it's not a very good word, right? It's not a great name Nobody could say it nobody could spell it, but it was going you know it was seeping into our code everywhere So we decided no no let's just call it an attribution event because we're attributing the review or we're attributing the submission to a particular person And so this is how we can say it so we've actually we've actually we've actually got some abstraction now instead of just four Columns by themselves you now got we've grouped them together into a little value object called an attribution event So this is sort of the typical flow of how you improve your code You notice some duplication and you decide to abstract it and as soon as you abstract it you realize you need now need a name So we coined the name attribution event Now attribution event is just a little value object. That's what it looks like We just have to specify how the four columns are going to map into attributes on this little value object And we do that through the constructor So previously this I would argue that this little object was kind of hanging out hiding before right this type was hiding inside The table the fact that we always had those same four columns duplicated meant that whoever wrote this code kind of understood That there was a type hiding out So we've actually made an accomplishment here We've taken these four things and we've actually given these four columns that are associated We've now come up with a name for them So now now on the team we can talk about a sheet being composed of a reviewed and a submitted attribution event Now what is an attribution event? Well once you look at it you could sort of say well it identifies a user and there's a timestamp Nice So there's the user identification We could just keep the user ID But we decided to make a copy of the email and a copy of the name in case that changed right Sometimes when you're sort of capturing things to make a recording you have to actually copy the attributes as opposed to just having a reference So we copy over the email and we copy over the the name and keep it over the user ID in case it changes right And this is the timestamp now I think you know on the team we realized we had this increased understanding We've got now got an attribution event Which is a user and a timestamp But if you look at the way this code is written you can't really the the user concept is not really quite as Pulled out as it could be So we're going to improve that in a moment Here's what we had before If you wanted to create one of these attribution events before you would assign all four Attributes one at a time made a small improvement where now we can do this We can assign the attributes all at once after creating one of these little tiny attribution events And depending on whether we assign it to the submitted attribution event or the reviewed attribution event the same type goes into different columns However as soon as you do this and you look at it you go, hmm We've got inspector inspector inspector. We got a little we got some more duplication happening here So once again, we need to do something to make the code a little bit more abstract So you just want to be really sensitive to seeing these kinds of bits of duplication How do we solve the duplication problem? Well because we've got a little object We can actually put a nice little constructing method in it So we can make a nice little factory method and we can just pass in the user and we can default the current time One of the great things about starting to create these little kind of tiny little value objects is they start to attract other methods So we had before and now we're making an improvement, right? I can just pass in the inspector and from that inspector, which is a user I can get all the user attributes that I want And because I'm mostly capturing events now, I don't actually have to pass it and I can make that a default parameter So it's just starting to get easier to work with this code There's another important benefit of making the code go this way is there's actually some errors that previously Were possible that are no longer possible So here you actually just forget to set the email And with our new design, we can't actually make that we can't actually make that mistake anymore Here's another kind of mistake you can make Well, you actually put in you know a different user's email Like these kind of mistakes could have gotten into the code base And now they can't get into the code base anymore because we're got more abstract kind of code So there's a lot of benefits to finding names Noticing do well noticing duplication making abstraction Coming up for a name for that and then typically as you make these moves you'll you'll You'll get to a new point in your code where once again you can notice more more duplication or more abstraction possibilities So here's where we got to Here's what we have in our main class now we've written quite a bit of code And you would have to write this code anyways, but now we've made it We were using you know the rails composed of feature to make it clearer as to what we're doing But if you look at this code, you can see ah duplication again We've got this kind we've got this reviewed reviewed reviewed and submitted submitted submitted So once we spot this kind of duplication we can think oh we've got a missing abstraction So what I would prefer to do Is to write something like this I'd rather just be able to declare my attribution events rather than having to do the whole composed of piece So this is a class macro which you can add to your code And it's really valuable once you start getting stuff more abstract because now you can do things like this It turned out that a little while later we actually had to add a discarded event And it became very easy to add it to the code base because we just declare another attribution event The other thing is that if you were to like search through the code base looking for attribution events They just kind of pop out now right you can find them all over the place Whereas previously they were just there was a it was kind of a hidden concept So how do you do this in rails? How do you how do you how do you make these new kind of class macros that you can use? You can do it in pure ruby, but it's it's it's really easier to do using a concern So this is an example of how we can use a concern Concerns are a custom design for being able to write these kind of class macros and they're basically mechanisms for hiding complexity Some people don't like that. Some people like that Your mileage will your mileage will vary you have to decide whether you think it's worth it In this particular case, we chose to use the fairly complex mechanism of a concern. So what does the concern look like? Um, this is what it would look like Now that's the code that we were just writing by hand a moment ago So what we're going to do is we're going to make we're we're we're writing a class macro We're writing a function that will write that code for us And there's how we remove the duplication right because we had remember before we had reviewed reviewed reviewed submitted submitted So now the abstraction the duplication has gone away because we've got a variable here We've introduced this new method now called attribution event. We pass in a type and then Because we're going to include the concern this this class macro will be made available to us And when the class first gets read and the class macro will be invoked and it will basically build the little composed of code for us There's a certain amount of ceremony you have to use to make the concern You just have to say oh, I want this to be a class method It's it's a lot of uh, well, I don't know it's it's a lot of ceremony here But that's to allow the calling code to be low ceremony So that's what we had before and this is what we get now So we just have to include this new concern that we've made and now we can declare attribution events And we don't have all the duplication that we used to have before So that's using concerns So what have you done? How we said an attribution event identifies a user identifies a time stamp We realize that there's different kinds of attribution events So now this is what our this is what our code is starting to look like now We can just include our concern for attribution events and then we can declare attribution events And then we have a couple of ways of creating attribution events We have that nice little factory method that nice little creation method build Which kind of abstracts away the fact that we're taking three components from a user now this kind of kind of Separation of concerns also makes your code much more valuable in the future Let's suppose that there's another attribute of users that we would like to capture in the future We're just going to have to change that in one place in our code I mean we're going to have to create the database columns But once we've created the database columns, we want to pull some I don't know a phone number off the user and store that it's very easy because it's all going to be inside the actual None of the calling code will change right they just pass a user and if you want to grab another attribute It's fine. We just store it. Everything will work fine So we've come quite a lot and way from just having database columns We've now got this much more stronger more powerful kind of concept The next thing that came up was we were having debates on the team about what does it mean to Log capture assign save or record an attribution event So we played around with record for a while But it turns out that we're doing all this work in the context of a compliance project And the thing that we're actually recording is is called a record So we realized that's not a very good name, right? Can't tell whether it's pronounced record or record. So that's not a good name Log seems it doesn't really seem like a log We started using assign because that's our that's our current technique, right? We have to just assign the value object So we tried playing around with different sort of things in the code And tried different playing trying different verbs And in the end we decided that capture was the right the right name to use So this is the kind of thing this is kind of thing I often try when I tell people that I don't really know what the name is I try to let the code kind of decide So I kind of kind of try using different names in the code to see Which names make sense So I noticed even when I'm giving this presentation I always talk about capturing attribution events now, but for a while we weren't really sure how we were doing that So what I'd like to do is I'd like to do this instead of doing instead of doing the assignment I'd like to be able to write this code Luckily we have our concern and so we can actually just in because we've built this concern We can start to include instance methods as well as clash macros So we can make this nice little method called capture attribution events And you can see the type concept is kind of sneaking in again, right? And so when we include the mat when we include the concern it writes these clash macros for us and it writes this little instance method for us So now you can do this so before I used to have to assign four separate Attributes in order to capture an attribution event whereas now I can just say oh capture the attribution event It's a submitted one and here's the user Now under the covers, you know exactly the same code is executing It's kind of interesting in some ways that we haven't actually made any change to the database scheme at this point So all the code that depends on that existing scheme is just working fine We just got a more expressive way of sticking those values into the database and also getting them out, right? the nice thing about the The composed of macros that when I read a sheet out of the database, I'm going to get references to these little attribution event objects, right? So that's my example from qcloud And the two mechanisms that we used were composed of and concerns So that's the only example So now what I'm going to do is to kind of revisit the example and talk about some of the Resources that you can go to find out more about how to do this kind of stuff And I want to talk about one particular Diagram that really made a big difference for me and it talks about what the interaction between naming and designing So this is the words that we eventually like came to right? And I don't know for me. I don't know for you But for me, I would have I would have had a hard time kind of deriving these words from just the four database columns It wouldn't have been clear to me that this was really what the code was doing But now the code actually says pretty much the english, right? So when I talk to the product people about capturing attribution events and what are the fields in an attribution event We're all talking the same language now so that's kind of that's kind of where we started and that's where we ended up and I don't know. I I I hope you got some kind of sense of this kind of thing where the naming actually contributes very much to our design And Once we start designing and we make abstractions we have to give them names. So designing is very connected to naming So these are two books that I would say you want to start with Eric Evans wrote this great book called domain driven design Where he introduced this practice called ubiquitous language And Kent Beck wrote this book extreme program where we introduced the practice called simple design So we're going to talk about those Eric Evans believes that this was his you know a significant contribution to the world of software And I think he's right He kind of synthesized a lot of object oriented design principles, but he actually coined this phrase of a ubiquitous language And ubiquitous language means that everybody on the team Uses the same language for everything So you would expect to So for example in in the qCloud application, there's a setting which says enable attribution workflows And so that turns on the attribution workflows So that the terminology just sort of gets everywhere One of the things that's tricky about this is that after six months on a project If you decide that you'd now like to refer to a concept with a different name If you practice domain driven design, you're obligated to go into your code base and change all the names to the new name It's tremendously powerful if you can do it though On the project that I currently work on which is another project at my company We have a it's a supply chain application and people are making products Which are finished goods and they're using sub components and the users think of these things as items But in the code it's called skew And we never got around to renaming it but every time we have conversations with the product people we go We're going to make a new item in the item master and we go oh you mean skew and they go no an item Anyway, it just it just causes a lot of friction and a lot of translations So ideally you want to try to minimize the frictions when you're talking to your product people And it's kind of amazing when you have if you get all your ubiquitous design And you get it all lined up correctly then when you're talking about the code you're actually talking about the product and vice versa So you can see that on qCloud. We tried to do these things and we have sheets and we have inspections And we have forms and so there's actually models called form sheet and inspection Anyway, it's a great book. There's been a couple of books that have been published since then I think there's a there's a freely downloadable copy on info q which is kind of just a summary of this book This book I think came out in 2004 It's a great book So simple design xp came out in 1999 Second edition simple design is these four these four practices So the idea is that your your design would be simple to the degree to which it passes its tests reveals intention No duplication and fewest elements So I would say you can pretty much just use these two concepts and you'll get you know, you get 95 percent of simple design Now i'm assuming you're also doing tdd. So you're if you're doing tdd You're already writing all your tests and all your tests are passing anyway, so you don't need to include that as part of simple design But really what you're really trying to do is you're trying to remove duplication in other words to reveal intention Primarily by removing duplication again that gets you most of the benefits of of making your code more understandable And also you want to improve names Now at one point people are always wondering like what's the priority? Is it more important to improve names or is it more important to remove duplication and different people would argue about it and turned out turned out that uh Someone called jb reinsberger also known as j brains. I guess because that's his uh his handle he he wrote this really great diagram And really what I hope is that you will be able to use this diagram To improve your code He basically says look it doesn't matter which one you can start with either one So let's start let's start on the left with the green start here So we're going to remove some well, let's yeah, that's I guess that's where we started remove duplication We know we noticed that there was some duplication in the names of the columns So you can see some structure structure needs names and we made we know we made attribution event We came up with that name And oftentimes when you're improving names new abstractions emerge And so you have to you get a higher order kind of duplication. Do you remember when we first created the um The attribution event we were passing in three separate user fields and then we realized oh that's kind of that's kind of a form of duplication Right, why don't we just pass in the user so we made the little build method So he calls this the simple design dynamo. I don't I think he's just joking about the trademark But anyway, he calls it that so but I mean I don't know it's really like How to really be an influence on how I program because it means I don't have to get the names right initially I don't really have to get the design right initially. I can just make all these like small moves So like the in the example from qCloud. I showed you like I had none of us had any idea that that's where we were going to wind up We just started making small moves We're just a little bit of duplication make some abstractions more duplication make some names Like it wasn't a matter of like thinking really hard to come up with where we got to it's a matter of just going around this cycle a bunch of times So the other thing too is you you can stop whenever you want to and then you can come back and pick it up later right Just make these nice incremental improvements So extreme programming Explained has this concept of simple design. It's one of the core practices sort of in the inner loop of what developers do every day Did you test your own development? They do refactoring? They do simple design and you do pairing if you're doing xp So it's really fundamental design practice JB has some nice Articles about this as well I don't have references in my slides, but when I publish them I'll make sure there's references So this is where we started We just noticed That there were some duplication missing concept We made we took advantage of this little composed of macro to basically call out the fact that we had these little objects which we named attribution event So that's kind of like one cycle around the dynamic design dynamite Made this nice little value object getting some improvements Hmm notice some duplication with the inspector name made this little build method more abstraction Huh, lots more duplication here missing concept introduced this nice. Uh, well, I don't know if it's nice anyway introduce introduce this concern to sort of Put that complexity out of the way So we started here and we got to here So now we can just declare attribution events and we can capture attribution events of different types When I when I when I declare the attribution event reviewed I'm really declaring a kind of little reviewed type which I can then use when I go to capture it Just go around this circle a bunch of times so I guess my My uh, I guess my hope Is that you don't settle for poor names Because if you do you're missing chances to add more abstraction, so I guess I don't know pretty please something like that It makes a big difference on your project if you really if you really obsess about names I think what was really liberating for me about the dynamic design dynamo is I don't have to obsess So, you know, I don't have to obsess and worry about getting them wrong improve them The code will change its shape. I can now look at the code and the code will help me like kind of get You know get me some more insight Build an abstraction need a name go round and round and round naming is very important, right? Like this is this is a really fun tweet anyway, so naming things is super important and I think that I really got to I I know for myself that I understood the value once I realized Oh, it's not really just naming. It's naming plus design And that naming really is very very deeply connected with design And so when I'm improving my names, I'm really thinking more about just improving the design It's not just substituting one name for another name Anyway, thanks right so so the question really was If you're going to use a metaprogramming kinds of techniques, are you creating a barrier to you know some people on your team? Is that a fair? I mean I mean in some sense you're really asking, you know, you're really revealing the main complaints or concern that people have with rails in general, right? You know, I mean, I think You know, you're balancing abstraction and convention over configuration I don't know. It's a really difficult question. I mean, I think I think The way we do it on our team I guess is when new members come in we just kind of take them through all this stuff and we you know We show them through it and we develop these features as a team rather than having some Part of the team just go off and do this kind of metaprogramming and then come back to it I mean, I I I share the same concerns, right? I I I mean, I know for myself. I feel it's taken me Four years or more of doing ruby on rails to really be comfortable Starting to do this kind of stuff Because I feel like it's another design skill to actually learn when it's appropriate to add To use metaprogram to do this kind of stuff. It's much more straightforward to you know Just use the framework as is if you want to do your own frameworky kind of stuff Then you actually have to become good at building framework kind of stuff I I don't know I wish I had answered your question, but there's no answer really Yeah So the question is when you when you have these little composed objects Why not just put them in a separate table? So we considered that we considered that And it's a perfectly reasonable design So instead of having these little Four column objects inside Single, you know the sheet database sheet Table we could all put them we could put the reviewed the submitted all out in a separate table I Just made a choice. I don't think there's a huge difference I mean I I like this choice because it's like a stronger representation because you're you're saying that the The multiplicity can only be zero or one When you put it in a separate database table, you have to you have to enforce Uniqueness by reviewed type or I mean you have to do something else It's not it's not you're not exactly expressing structurally the constraint that can either be Zero attributions or one attribution event That was part of that that was part of the thinking behind it But um, you know, we we consider going both ways You could go either way. I think to me. It's just natural to say that rather than Um a sheet being associated with an attribution event. I sort of think of as a sheet has an attribution event Like it really does have an attribution event right inside I think there's really not a lot at stake I don't know. I feel like I don't know why I'm so agreeable today or something I probably really argue news you're on my team, so Okay, I guess that's it. Thanks