|Venkat Subramaniam, Agile Technology|
One of the things that I care about a lot is developing applications and being successful with it. That's one of the reasons why I spend time not only thinking about it but also writing the practice of an Agile developer with Andy Hunt. One of the things I want to do, just like how I would pick languages that I want to use, is pick technology framework solutions that can solve problems for me or more precisely solve problems for my clients. And what I really like about technologies that are coming up right now is that I can focus not on implementation, but more on solution. What I mean by that is, one of the key things of our Agile development -- and a lot of people probably don't realize this because Agile means different things to different people -- is that we spend time developing software that actually solves a customer's problem.
You probably have seen this little thing that kids play with, like the Whac-A-Mole. And then these kids grow up and they program, and guess what happens with the system they program? Most of the systems we work with are Whac-A-Moles. We fix one area and then something fails in another area. That's not going to build confidence among customers. So when they give us feedback, we want to go back and provide a solution that works, solves the problem in the area but doesn't break other areas. So the inner feedback cycle is where the code we're able to know that it still is meeting all the expectations, the programmer's expectations, and it's still functioning to the degree that is expected to function. So these two feedback cycles are extremely important.
Code generation is so twentieth century. If you generate code, it's like a little sore you want to kind of keep itching. People modify code and so on -- you don't want to do that. Code synthesis is much more superior. When you synthesize code, it's not a code that's left on disc. It's in memory, it gets, it comes in, it works for you, it's dynamic, it evolves in memory, it goes away, and there are a lot of things you can depend on and use the service. Things like GORM and Grails give you this great amount of flexibility because of this code synthesis. As a result, you are focusing more on getting your work done rather than trying to hammer this infrastructure. The infrastructure doesn't control you; you control the infrastructure. You are able to produce results very quickly. Go back to them and show them what you've done and get their feedback. And I think that's where the real benefit is -- where you can be agile and focus on solving problems in a constructive way. How does Grails support code synthesis?
There are two strengths that you're depending on when it comes to Grails. One is the strength of the Java platform. We've been used to this for the past 10, 12 years. The Java language has become complex, but the Java platform has become more capable. The second thing Grails depends on is the Groovy language itself, which is pretty dynamic. You've got the strength of meta programming. You can have methods being injected dynamically and so on. And the other thing is the object relational mapping facility that Grails uses, which is the GORM. And in GORM you're not doing generation of code; a lot of code gets synthesized. So when you're trying to access data, it synthesizes the methods to find the data, save it, validate it, update it and so on. But I'm a developer. I'm using the stuff, but I don't really care how it gets the job done, or should I care?
Well, you do, because it is your responsibility to be creating these. And if you're not creating this, you're configuring these things. You are spending your time and effort spinning the wheels that you just shouldn't be spinning. The fact that these things are getting synthesized for you means you don't have to spend your time and effort on it anymore. So as a result, as a programmer you're spending your time focusing on the higher level of abstraction and the solution you can provide rather than the low-level stuff that you don't have to worry about anymore. So this is exactly how Grails fits into Agile?
Absolutely. The two cycles are extremely important. The inner circle, the outer circle, and they're not really one within the other completely. There is a little bit of an overlap between them because they're tied to each other, but in Agile you cannot have one feedback cycle without the other. If you only care about providing solutions for the customers, then you have the Whac-A-Mole problem. You keep breaking things. Somebody once said, "There's a difference between developing the software right and developing the right software." And those are extremely important things to keep in mind. Not only do I want to spend the time creating the software right, I want to make sure I created the right software. And so that is the inner circle and the outer circle. The inner circle, that's to me that the software is right. The outer circle, that's to me the right software. And one without the other makes no difference, makes no sense. So then you use Grails to help you develop the inner circle.
The tools and the techniques that Grails provide you are really for the inner circle. And the fact that you can quite easily get the work done so fast, so that you don't have to be spending the time creating the infrastructure, mixing Ajax for example is almost trivial because of the integration of the different frameworks into it. As a result, the outer circle is also quite possible because you're not taking weeks and months to get things done when you get the feedback. You could literally go back in hours and get the feedback and say, "Hey, is it what you wanted, am I in the right track?" One of the things about Agile development is if your objective is to implement software that meets the expectations the customers had, you will fail. You cannot build software based on what they wanted. You need to be able to build software based on what they want. So the smaller the feedback cycle is, the duration is, the more in sync you are with what they are evolving. Users, unfortunately, are human. They think, so when they tell us that they want something, their mind is not frozen; they keep thinking about it. Developers are human also, and they sometimes mishear or misunderstand what the users are asking for.
Absolutely. Sometimes they miscommunicate. And sometimes we also hear what we want to hear and not what we are told. Also, sometimes the users give us a solution, rather than giving us a requirement, so the feedback cycle helps us to put us back on the same page. The real benefit then, from your point, for using Grails and Agile is that you get good support for the inner circle and it enables good support for the outer circle.
Exactly. One of the other things about Agile development is the smaller steps, smaller bites. Somebody said, "How do you eat a pizza.?" One bite at the time. We are civilized people; I don't try to swallow a huge bite. That is exactly the way it is with Agile development. We want to take the smaller bites. So it doesn't matter what technology you can integrate with. You want to take the smaller bites, smaller steps, and Grails allows you to do that. There's no pressure for you to go off and take a massive amount.
Here's another thing I really like about Grails. I can say this over and over, and I would never be tired of saying this. And that is, a database at the end of the day to me is an implementation. And Grails does not require me to spend any time on a database when I start implementing a solution. I can postpone database as much as I want to. The advantage of that is I can develop a fully working application from the feedback point of view, show it to the customers, and have them exercise it, without having to persist any data. And when they say, "Yeah, that looks like what we want," then I can go and tie that into the database. Ok, now you got me here, because Grails is tightly couple to Hibernate, right?
Not really; that's the beauty. It is tied to Hibernate or whatever implementation you want to tie it to. It doesn't require you to define the database schema. So you don't have to be defining a database schema on the first day or even the first week. It can take away from your object model. So how do you throw a tracer through that environment if you're not touching the database? When Hibernate says, you know, I want to touch the database.
Because by default, Grails allows you to talk to HSQL the in-memory database. And even there, you don't have to define the schema. You're just capable of extracting the details it needs from the model. Now Grails, Groovy allows you to do optional typing. What optional typing means is if you twin, you don't have to say what type it is. Or you can go all the way like Java and start giving type information. So if I define a model and if I start saying what type each of the fields in my class is, then it's able to extract the details right from that. I don't have to be sitting there and defining the database schema, the database structure. So, I'm working at the Groovy code level, and the only time I really need to start interacting with the real database is when I really want to. And that is agility.
There's an interesting principle called the YAGNI principle. Rodger Fisk coined the term YAGNI principle. It says if you don't need this database stabile, if you don't need the schema, you're not forced to do it. So I can wait until my object module matures. And once it's reached a certain amount of maturity, not based on my assumptions, but based on the realities of what the customers are expecting from the application, I can then tie it back to the database. To me, that is agility. I am not forced to do things and keep tweaking it because the framework requires me to do that. Where does the object model exist? Does it exist in Groovy or in Java? Is it in the middle of the framework or where do you put this?
It exists where you want it to be. Grails gives you quite a bit of flexibility. By default when you start this, Grails doesn't just recommend MVC. It doesn't just tell you it would be nice if you're using a model view control architecture. It tells you to use MVC, it follows you home, sits next to you, stares at you and makes sure that you're doing MVC. As a result, when you create the M, the model is where the real object model is. And you can do that in Java, you can do it in Groovy. Obviously doing it in Groovy gives us a lot more benefit because we got the dynamic language capability, and we can at the same time take advantage of this optional typing capability of Groovy as well. Ideally, I would put that in Groovy, but that's not a requirement. Though the persistence actually doesn't happen if I don't hook it up in the model?
You can configure that at a later time. And you're not forced to do it on hour one or day one. And I can wait until I say, hey go ahead and use it. No, obviously there's one small constraint, right? When people are playing with some data, you want to provide them a certain amount of test data for them to work with. There are boot-strappers available for you to load up a certain amount of initial data to start playing with. And again, keep in mind that the objective is not to provide the perfect solution. The objective is to get something working in front of them, so that they can give you the feedback. You don't have to go on a tangent in one way or the other. While there are certain pieces of an application that are quite demo-able and exercisable, there would be other parts of the application that are fully functional and releasable. And you can take advantage of whatever you want to do in different parts of the application.
It's not an all or nothing proposition. You decide to use it to the degree you want to. As a programmer, you do what makes the most sense. And that's the beautiful freedom that it provides for you. It's lightweight, it doesn't burden you with things you don't have to do, and the things that it wants you to do are the things that are rightfully so. The other thing is one of the advantages you get in writing code is even from tester development. One of the nice things I like about tester development is that it makes your code more cohesive, loosely coupled. It makes it more modular. And Grails gives you the capability to write more modular code. You can create a lot more templates for the code. You can create your code in the control, but control can easily talk to either a Java code or a Groovy code in the library of the source directory. You can start writing tests on them separately. You can make the code as modular as you feel fit. And to me, that again is a great advantage. It's like being in a free society. You decide to do the right things, and nobody stops you from doing it. You're not forced to do certain things; it's your judgment call. So this must help in the testing process also, because then you can boot-strap in particular pieces of test data on that part.
You can certainly do that and also configuration is minimal. And whenever configuration happens, it happens in Groovy code. So you don't have to go to the XML application. As a result, when you do decide that you want to make a change, a lot of times you don't want to make a change because, making that change is so hard, you've got to change all these files, you've got to make change in all these different places, or you've got to go and learn this laborious syntax that you're not familiar with and can't keep it in your head. It's much easier because in your work as a programmer, you're working with code and the code itself becomes configuration where it needs to. So that also helps a great deal to make that change affordable. I had the opportunity to listen to Bob Martin recently give a keynote and he said that features were not the main output of a developer, that code was the main output of a developer. Do you have any comments in regards to that particular statement?
My interpretation from that statement is that probably what he meant is that you cannot possibly be agile if your code sucks. Right? That's exactly what I think the message of he was trying to get to.
And that is a very valuable thing to listen to. If I can go to my customer and say, "Hey, I'm agile. Tell me what you want to change," and they tell you what they want to change. And they come back and sit down and say, "Wait a minute, the last time I touched this code I couldn't go home for the weekend. Heck no, I'm not going to change this." So there's this broken window theory, right, from pragmatic programmers. We should care about our code a lot. Don't let anybody trash your code. If your code quality is very high, then you're able to respond to those changes.
Again this comes back to my argument about whether the inner circle is important or the outer circle is important. You cannot have one circle without the other. So I would take that statement and change it saying that the relevance of your features, more than features. Studies that show that only about 20% of features in a software project actually gets used. What that means is we are working very hard to build complexity into software wherein we should be working really hard towards building capability into software.
Sometimes people come to you and say they've got a large application. I'm sorry, that doesn't mean anything to me. Large means that it's huge, it's fat, it's tall -- that doesn't mean it's useful. Sometimes people say they've got a large team. What does that mean? Does it mean that you've got all these incompetent people that you need more people and more people? Again, these are not good metrics to drive by. If you say that you have an application that is highly valuable and people use most of what you provide, I think that means something. So I think we should ask ourselves, "How do we build relevant working software?" And if we focus on that, then the two things become very clear. We should focus on building relevant features and with high-quality code. You cannot have one without the other. You can have a beautiful code that nobody cares about and is probably a failure because you've wasted money building it. Or you could have a very good application, but the minute people want to change it, you're back to the Whac-A-Mole problem and you cannot keep up with the change. Well, and this comes into another question. How do I know that I'm writing quality code? Is there any way for me to tell?
Absolutely. Most of us will think we are doing a good job. One of the other important things about Agile development is to court criticism. It is such a sickening part for anybody to sit here and say I'm good, and I cannot improve. What a sad thought that is. I want to say I'm good, but I think I can learn and improve a lot more. So here is the best way to kill a code. You write code and nobody ever looks at it. Then what happens? The code ends up looking like my closet. I'm sure there's a tornado going inside my closet, right? But the front yard of my house is beautiful. There are two reasons for this: One, I care that others look at it. Second, my homeowners association is a pain in the neck, so when others look at it, it's a better quality.
So one of the best ways to make sure our code is really of good quality is not to think so, but to prove so. And that is to have other people look at it. There are two ways to do it. One is to pay a program developed along with the pairing. And even in pairing, one of the things I highly recommend is not to pair alone, switch your pairs. We switch pairs every day. If I pair with you today, I'll pair with somebody else tomorrow on the team. That way more people end up looking at the code. Collective ownership, anybody can take the code and change it if they can take the responsibility to change the code.
One of the other things we do on projects is code review. We finish the code, and before we go too far, as soon as a task is done, we put it out and say, "OK, here is the code. Find something that you can improve." And you court criticism. People look at it and they say, "Yeah, I like it. Here are the things I like in what you've done. Here are the things I recommend you could do."
I'm not a big fan of tools because a fool with a tool is a bigger fool, a dangerous fool. Having said that, tools in the hands of good people can make a difference. Tools like code analysis tools. There are tools that can help you to look at code coverage. It's one thing to say we are doing testing; it's another thing to say we've got fairly good code coverage. Sometimes people just install a testing tool, run a few tests and claim that they're doing testing. It's like me getting on a treadmill once a month and claiming that I'm exercising, right? That doesn't count.
The more people read your code, the quality of code becomes better. Sometimes people say, "Well, the guy who wrote this code doesn't work here anymore, and nobody understands this code. You always wonder how could code become like that, such a liability. That happened because most of the project managers care about short-term game. If you write code today and you're going to write code tomorrow and you're going continue to write the code rest of the week and rest of the month and rest of the year, you'll be the fastest one to write this code. But in the process, you made the code more complex. You make the code unreadable by others. Come back from a vacation, you can't read it again. That's one of the reasons why people don't go on vacation I guess. That assumes the people who are actually reading the code can make useful contributions to that.
Oh, you're absolutely right. And that is one of the reasons why code review should never be done by so-called priests. Some companies hire these priests. Priests are, you know, experts. They don't write code anymore; they just review code. They've become policemen. They walk around with a big stick. It doesn't work that way. The person who reviews your code must be the person who would actually pick up the code and change it the next day or who already picked up the code and changed it yesterday. This is a person who can actually collectively maintain the code and evolve the code. That's why it's a peer review, not a priest review. Do you see any automated processes that help with code reviews, check-ins, things like that?
There are certainly tools available to do this, but I would not use one. One of the advantages I find in people working together is helping with this so-called bus factor. The bus factor is the number of people who should be run over by a bus before your body fails. Code review is very bureaucratic now.
Here's the reason why code review is a problem for a lot of people. In a lot of organizations, code review means you get together on a Thursday afternoon, project the code on a big screen and start critiquing it. Here are three reasons why that doesn't work.
The first reason is the guy who wrote the code says, "Wait a minute. You guys are going to get together and bash me over this in the afternoon? I don't want your code review." And others say, "Look, I'm already behind schedule, and the last thing I want to do is to look at that stinking code that other guy wrote." And the project manager says, "Hey, guys. The last time we did code review there was a fight going on and one guy actually quit. No more code review for you."
Code review like that is emotional, political, and it doesn't work. But here's the way we do code review on projects. If I work on a task, my task usually is about a few hours, push it to half a day to a day. If I took a day to write it, how much time do you think you're going to take to read it? Given the fact that you're a peer, you're working on that code constantly. I'm not asking you to look at something you've never looked at, right? You're familiar with the concept. You'll probably take about 15-20 minutes to review it. And at the end of the 15-20 minutes, it's a very mature comment. You're just saying, "Here are the things I like. Oh, by the way, that's pretty cool, I haven't seen that being done," The other person going to take that and use it. That is a very positive comment to have. You want to give the positive feedback and a constructive criticism at the same time. People don't want to do this type of activity. They don't want to look back. I've never seen a project really take on retrospective, and I think it's an important aspect of any project cycle.
I agree. And let's deviate totally from this for a second. I would say, almost everybody you come across, would agree that exercising is good for our health. We're in a meeting of a hundred people. Ask them to raise the hand if they think exercise is good for them. Almost all of them will raise the hand. Tell them to leave their hand up if they actually exercise regularly and you'll be surprised how few hands are actually up. Why is it that we all know that we become healthier when we exercise, yet we don't do it for ourselves? That is just human nature, isn't it?
Venkat Subramaniam is the founder of Agile Technology Inc. and co-author of Practices of an Agile Developer.