Search This Blog

Sunday, June 13, 2010

Ship It! - 4.7 Refactor and Refine

As your teams add real functionality to their stub code, they will discover that one interface needs an extra variable passed in or that another interface was missed entirely. You can add this functionality at any time. When you make these changes, publicize them so that other teams that use the same interfaces won’t be surprised. If need be, just add a new interface with the extra variable instead of pulling one out from under another team. Remember that you never break the builds in a tracer bullet project. Any code that you add should extend the system, not break it.  You will also realize at some point that code you’ve written needs to be thrown out. Maybe the code is too slow or it returns the wrong results. Any one of a thousand things may be wrong with it. Feel free to completely refactor or rewrite code, as long as the interface still works the same way. You can make these changes at any time in a Tracer Bullet Development project. The rule is that you can’t change the interface that the other teams use without consent, but you can change the code behind those routines at will. As long as the interface works the same way, the other teams won’t be aware that you’ve changed the code. Their code should still use your interface the same way, only now it runs faster or returns the correct data.

Tip 23: An encapsulated architecture is a scalable architecture

I'm thinking that the term "scalable" refers to the number of developers that can productively work on a system, not how much additional load it can handle.  If the touch points are well defined you can have one or many developers working on a layer and the other parts of the system won't know or care.

Saturday, June 12, 2010

Ship It! - 4.6 Fill In the Stubs with Fuctional Code

You now have an end-to-end working system. Every piece can talk to each other, and all the code compiles and runs. It’s time for you to start making it do real work. Even as good fences make good neighbors, good interfaces make for good team interactions. Each team can now work in complete isolation if necessary and can start to fill in the logic behind each interface. Each of your teams now has a basic framework that they can begin to fill out. You can do whatever you like, as long as you don’t break the existing interfaces. No one can change APIs between layers unless both teams agree.  Don't implement the simple stuff first. Instead, target any area that contains new technology, is inherently difficult, or is core to your product.

Tip 22: Solve the hardest problems first

Use The List to prioritize.  Do not let the system break aka Don't leave Broken Windows

It seems to me that in order to prevent breakage of the system, you need to have automated builds and tests in place.  If you have notifications of when people check stuff in, you can probably get an idea of what the "other guys" are doing without requiring lengthy status meetings.

Friday, June 11, 2010

Ship It! - 4.5 Make Your Layers Talk

Now that you have completed your stubs, you’re ready to start making them talk to the other layers in your system. That may not sound important, but you’ll be surprised how many seemingly insignificant details will not work together the way everyone thought they would. Once you start adding callbacks, using different CORBA vendors, and trying to use Java RMI on different network subnets through firewalls and the like, it’s a whole different ballgame from “Hello, World!” As every team puts code into their stubs to access the other layers, they are proving that every technology involved actually can inter-operate. Will the customer run part of the system behind a firewall? Then you should too!

Tip 21: If production uses it, you should too

Be sure that your hollow shell works end to end before you invest time to make it do the real work.

Your project now has the following:
  • a complete, documented architecture
  • a POC that shows your architecture works.  You can make a client invocation and see it run, end-to-end.
  • clear boundaries between teams
  • clear demarcations between areas of product functionality
  • experience meeting with the teams responsible for adjacent code layers. 
Having all your teams talking with each other is a huge benefit and getting the layers to talk is one way of doing that.


I've experienced first hand the pain that integrating layers that should "just work" can be.  I think the idea of wiring up the layers early is a good one.

Thursday, June 10, 2010

Ship It! - 4.4 Write the Interface Stubs

This is the easiest part of the project. Remember to keep everything as simple as possible. The goal of an interface is to be just thin enough to compile and be used. Be sure to finish one pass at all your interfaces before you insert code that adds functionality. Resist the temptation to start coding something easy.

I'm wondering if they advocate Test First development here?  I'm thinking that part of defining a workable interface is defining a testable interface.  Hmmm....

Wednesday, June 9, 2010

Ship It! - 4.3 Collaborate to Define Interfaces

The teams working on adjacent layers meet, and together they flesh out the interfaces that their layers share. If you know that the client application needs to log in, then you know that a log in call must exist in the web server layer. The teams collaborate and come to an agreement on the method names and signatures. You then code each method but return only canned data. In these meetings, you begin to define how the layers will communicate with each other. Your teams flesh out such details among themselves so that after this meeting (or as many meetings as it takes), everyone involved knows and understands the interface points between each layer. The best architectures aren’t defined by an “architect” in an ivory tower; they are collaborative efforts. Instead of having a guru drive by and drop a completed architecture document in your lap, your team works together, leveraging and increasing everyone’s experience.

Tips:
  • Always have a single person lead your meetings. This person always has the floor and must “give permission” before anyone can speak. Having a single person lead the meeting will help prevent the meeting from turning into a shouting match.
  • Record notes on a white board throughout the meeting. With the information on a white board, everyone can see what method signatures you’ve agreed on in real time. If you take notes on paper, inevitably someone won’t see what you’ve written.
  • Andy Hunt suggests trying using LEGOs or wooden building blocks for the objects in your system. You help the more junior members understand the system and the relationships between the different objects when you give them something tangible to see and touch. Sometimes the intangible nature of our work makes the system components difficult to visualize and understand. Whether you draw objects on the white board or move blocks on the table, have a visual or tactile representation of your system.
  • Record the interfaces and publish them. You can use a printed document, a web page, or a wiki, but regardless of what medium you use, you must make the information publicly available. The last place you want to keep secrets is an object’s interface.
  • Hold your meetings where you won’t be interrupted. You want to minimize the number of times you have to shift gears and answer questions.
Tip 20: Architect as a group

I'm thinking that a poor man's CASE tool, aka cheap digital camera, is a nice way to document the group's thinking.  I can't picture in my head, however, how I could use blocks to convey a software architecture.  I must do a bit of digging to see what I can find on the topic.

Tuesday, June 8, 2010

Ship It! - 4.2 Define Your System Objects

Your first step is to identify the layers into which your application can be divided. You want to be careful not to define lower-level objects. Be sure that each system object you define can stand alone. If you can create an object with clean lines of separation from other parts of the system, then it can be a system object. By keeping these objects as large as you can, your teams will be able to work independently for longer stretches of time. A system object must be large enough to justify a person or team working alone for some length of time. You also must be able to create a clean line between each system object. Think of your server objects as pots and your development teams as cooks. Sure, if the pot is big enough, everyone can stir in the same pot. It’s a lot easier if everyone has their own pot. A different development team works on each layer, and each team assumes that their layer exists on a different computer. This means that all communication between layers is over the network. Prevents "cheating" by accessing the implementation directly and allows for scaling because you can move a layer to a larger machine.

I like the idea of defining layers early but I've become comfortable of thinking in terms of the Port and Adapters architectual model.  Can that be used in TBD? I'm thinking yes because each Port is a layer in TBD.  I do think you might have to temper the "assume each layer is on a different computer" rule.  For example, many systems I've worked on had the persistence layer baked into the core.  One reason is to more easily allow for database transactions to span all the logic it needs to.  I'm not sure it makes sense to place additional complexity into the system to make transactions span processes.  

Monday, June 7, 2010

Ship It! - 4.1 Defining Your Process

This chapter is about a development process based on the Tracer Bullet idea put forth in The Pragmatic Programmer: From Journeyman to Master.  I look forward to exploring their ideas.

The practice of Tracer Bullet Development (TBD) lets you see where things are headed as soon as you start and helps you aim continuously long before you’re done.

A process must answer the following:
  • Does it work for you?
  • Is it sustainable?
Beware any process or methodology that claims to be the exclusive solution to every problem for all projects. This magic cure-all is just modern snake oil. Embrace a methodology that encourages periodic reevaluation and inclusion of whatever practices work well on your project. Be sure your process is a flexible one—don’t be afraid to change or adjust your process to see if a new, better practice can fit in. If you have a new idea, drop it in for a few weeks. If it works out, great! Make it a permanent addition. Otherwise, revise it or get rid of it. This experimentation is how you’ll find out what fits your shop the best. There are no sacred cows in a good process. Anything that works well can stay; anything that isn’t working must be removed or revised.

Tip 19: The goal is software, not compliance

How Does It Work?
You create an end-to-end working system when you use TBD, but the system components are all hollow objects. You write code for all the big pieces of your system, but the objects aren’t doing any work. Your database access layer returns data, but it’s really returning canned data, not data from a database.

Identify the major parts of your project, and divide your product into blocks of related functionality. For example, you might have blocks called client, web server, and database layer. Define the information that the blocks need to exchange and document the information with method signatures. These areas of layer interactions are called interfaces. Give each block to a different developer, team of developers, or corner of your mind (if you’re working solo). Write just enough code to make everything look as if it works. Think of it as an entire application of Mock Objects. With this thin, skeletal framework in place, you can begin to fill in the real logic inside each block. Finally, and most importantly remember that interfaces will change and evolve throughout the project. Your first shot will always miss the target, so be flexible and adjust your aim at any point. When another team approaches you for new interfaces, or to make changes to existing ones, go ahead and make the change. This is software, after all.

I've done a form of this and we called it "spiking the architecture".  I found it to be useful because you can't anticipate some issues until you starting manipulating code.  I don't think "big bang" development works so TBD might be a useful tool for me.