Motley: Build an application according to architectural layers, from the bottom-up.
Maven: Build an application using vertical slices. Build just enough UI coupled with underlying layers such as an object and data model, to satisfy a user scenario. Deliver customer and business value at the end of every sprint to ensure feedback early and often.
[Context: Motley thought he was doing iterative development the right way, but his boss has been all over him for not delivering tangible results]
Motley: I'm telling you, I can't win! We have been doing iterative development with the Scrum agile development model and my boss is still screaming at me that he is not seeing anything tangible coming out of it. I keep telling him that it will take a few sprints for us to show real value.
Maven: Have you forgotten one of the key aspects of agile development? Working software sooner. Agile teams should concentrate on delivering customer and business value at the end of every sprint. Get something real into the customers' hands quickly so that they can provide feedback early and often.
Motley: It takes time to get something real! We have to do a bit of infrastructure work first, and then build on that.
Maven: Ah, have you heard of "vertical slices", my boy??
Motley: You call me "your boy" one more time, I'll turn your shirt inside out with you still in it. "Vertical Slices"? Sounds like something you do to salami. I'm not going to bother asking what you mean by this because I know you'll tell me anyway.
Maven: Correct, my- friend. Vertical slices help deliver customer and business value at the end of every development iteration. Instead of developing one large feature requiring multiple iterations to see results, we break the work into usable pieces. Take a typical, but simplified, architecture:
One approach to development would be to first build the data layer (the lowest level of infrastructure), then build the object model on top of it, and then finally end with the UI. This is pretty common practice.
Motley: What's wrong with that? I need the lowest levels to build the middle and upper tier. You HAVE to agree with that! And besides, I am delivering business and customer value if I build the data layer and deliver that piece of software in one iteration.
Maven: Does the customer really care that you have a "data layer"? I think not. There is nothing for the customer to tangibly see until you have built the UI in later iterations. Additionally, once the customer does see the UI a couple months later and they can provide feedback, you risk having to do a lot of rework in the infrastructure if the customer wants changes. Even a small UI change can render various APIs in lower layers useless.
Motley: But I still need a data layer (in this architecture) to build the entire application.
Maven: Yes, but chunk up the work. Avoid building from the ground up starting from data to object model to UI. Instead take a vertical slice of the overall architecture and deliver a user scenario (user story). You build "just enough" of the data layer, object model, and UI to satisfy the user scenario. You get real working software sooner upon which the user is capable of delivering feedback. The focus switches from delivering technology to delivering real user value.
Motley: Flaw. Should I say it louder? FLAW. Putting software together in a piecewise fashion is going to lead to a bunch of spaghetti without a real architecture. This will never work.
Maven: Don't be such a pessimist! Or is it a cynic? I can never keep those two words straight. Anyway, you still need to have a vision for the product architecture. This agile type of approach does not preclude planning the entire system. It says that you plan the architecture at a high-level (components, interactions) and then build it in vertical pieces that span all layers. I still want a holistic architecture plan in place to guide development across several iterations. I just don't go into tremendous detail around exactly what the specific component APIs will look like (for example).
Additionally, I avoid building a full horizontal layer that may contain a bunch of code that will not ever get used, or get thrown away, once I get feedback.
Motley: Well, I may have to take some shortcuts to implement scenario #1 and then redo some work in the first slice to implement scenario #2. I just wasted effort! As we all know, eliminating waste is a key agile principle.
Maven: Well, it's actually a lean-
Motley: Yeah, yeah - a lean principle. Don't nitpick and respond to my comment.
Maven: It is true that sometimes you may have to refactor some code in the first slice to start adding to it in the second slice. That's fine - you have good unit tests in place that make refactoring easier. You may also have rework based on user feedback. This is all fine in that the rework for one small iteration is typically far less than major changes that could be forced by late feedback. Additionally, developing in vertical slices does not preclude you from using proven design principles. Design to accommodate change so that making changes later is easier. Although you don't want to anticipate future changes in successive slices and build functionality that may never get used later, you want to make your design easy to change and extend.
Motley: So I build a small snippet of the UI and just enough infrastructure to make that UI go. I am going to be left with some incomplete functionality by the end of the sprint.
Maven: Yes, but that's okay. It is usually enough to get going with feedback and validate your overall direction and approach. The customer can much more easily grasp a demo of working software than pictures in documents. Give them something they can touch.
Motley: And from the engineering side, we have some fairly incomplete layers at the end of every sprint.
Maven: Yes, sort of. You have layers of minimal complexity that support only the core scenarios. This helps keep the design and code simple. Think of this as adhering to YAGNI, or "You Ain't Gonna Need It". The gist of that principle is that you avoid implementing stuff until you actually need it, and you never try to anticipate future change. You avoid wasting time creating that functionality, testing it, debugging it, supporting it, and you keep things simple. You build enough to support the scenario. Over time your layers emerge.
Motley: I guess that makes sense. We end up incrementally building the product over time with tangible functionality and integrating features piecewise. I would have to try it before being convinced.
Maven: Absolutely. It takes some practice to chunk up the work into vertical slices, but if you focus on user scenarios/user stories instead of building technology, you'll end up on the right side of the fence.
Maven's Double Pointer Indirection: On my team at Microsoft, we try to break up work into vertical slices as much as possible. Take an address bar in a web browser. Instead of building the data providers that provide auto-suggest functionality and then tacking the UI on top of it, we try to build a basic UI with one suggestion (maybe even hard-coded) and then incrementally tack on from there. Okay - it doesn't always work out that way in terms of work chunks, but that's our goal.
- YAGNI, "You Ain't Gonna Need It" - http://en.wikipedia.org/wiki/You_Ain't_Gonna_Need_It
- Iterative and Incremental Development (IID), by Robert Martin, http://www.objectmentor.com/resources/articles/IIDII.pdf