tag:blogger.com,1999:blog-51221014826008250692024-02-07T03:07:05.178-08:00ConsiderTheAntAnthony Israel-Davishttp://www.blogger.com/profile/01726702236067369761noreply@blogger.comBlogger11125tag:blogger.com,1999:blog-5122101482600825069.post-12627173383809488262010-12-12T14:29:00.000-08:002010-12-12T14:54:23.727-08:00Real World Agile - Finding Some RhythmIt's been a few weeks since my last post - November seems to have come and gone and I was knocked sideways a bit by a nasty cold and a couple of weeks of unplanned work. We're still practicing Agile, though (or at least trying out best) and I wanted make an observation about how things are going in relation to rhythm. This is a bit of a ramble, but I wanted to get my thoughts out before too many weeks had gone by.<div><br /></div><div>In music, the beat is key - it doesn't matter if it's four-on-the-floor dance music or experimental jazz, without rhythm it's just very hard to follow along. Rhythm provides predictability and stability as well as a routine. It is a pattern that makes it possible for anyone to follow along and jump in - even in the middle of a iteration.</div><div><br /></div><div>We've been experimenting with one-week iterations, just to get our routine and rhythm down. Each week starts with a retrospective from the last week, moves into planning and then execution until the end of the sprint. In between we complete stories, deal with business as usual support and maintenance and start it all over again the next week.</div><div><br /></div><div>The pattern is simple, but getting a consistent beat for the iterations has not been. We've had sickness, unplanned work, PTO and holidays to disrupt the cadence. Our velocity has been highly variable (which is not unexpected when first starting Agile) and the focus of our stories has been less defined than I'd like. </div><div><br /></div><div>I think, however, that we are starting to hit our stride. The repetition, despite the variability, has brought predictability to the week, if not the results. We're finally starting to see a flattening of the velocity line and the way we approach the work is starting to gel. </div><div><br /></div><div>The one thing we've noticed is that one week iterations seem a bit short for us - especially with a three-hour retrospective and planning block in the middle of it. Starting in January, we're going to experiment with a two-week iteration making the three hour block much more tolerable since it only occurs every other week.</div><div><br /></div><div>Agile is definitely a process worth keeping, but it's hard work and not a silver bullet - especially if you're in an organization pulling you in several directions at once. It's something that takes time and commitment. Having a champion to drive the process and team buy-in is key. I've found that, so far, focusing on the basics and making small incremental improvements week-after-week has been the key to keeping the momentum. I look forward to finishing out the year and seeing our improvements in the next one!</div>Anthony Israel-Davishttp://www.blogger.com/profile/01726702236067369761noreply@blogger.com0tag:blogger.com,1999:blog-5122101482600825069.post-46633497984006578872010-11-07T08:35:00.000-08:002010-11-07T20:45:33.140-08:00Real World Agile - Week 3: How I Learned to Stop Worrying and Love the Story Board<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://positivity.files.wordpress.com/2010/02/image-scene-from-dr-strangelove.jpg"><img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 239px; height: 168px;" src="http://positivity.files.wordpress.com/2010/02/image-scene-from-dr-strangelove.jpg" border="0" alt="" /></a><br /><div><span class="Apple-style-span" style="font-size: 15.8333px; ">Ever have one of those weeks where you were only working on one project, no support or maintenance calls came in and all your customers and stakeholders got exactly what they wanted?<div><br /></div><div>Me neither.</div><div><br /></div><div><b>Business As Usual</b><br />Without any system to handle customer requests, they just come in as they pop up. One week it's a feature on a product another week, a different feature and maybe in that same week a different customer has a feature she wants added on a different system altogether. Meanwhile, we are also handling bug fixes and regular maintenance requests, answering email and going to meetings.</div><div><br /></div><div>In this chaotic system estimating how long a feature or product will take is difficult to impossible as we succumb to the tyranny of the urgent or whomever is most vocal and are left with a trail of half finished features, frustrated customers and only the most urgent (but not necessarily most important) things done.</div><div><br /></div><div><b>Enter the story board</b><br />Under our current Agile experiment, things are a bit different. We still have the requests coming in week after week, we still have requests to handle, bugs to fix and meetings to attend; but we have something else as well - the story board.<br /></div><div><br /></div><div>If our previous take-it-as-it-comes system was chaotic, the story board is order. It is deceptive in its simplicity: a white board with rows of sticky notes. Green sticky notes on the left representing our stories, or major objectives, for the week and <span class="Apple-style-span" style="font-size: 15.8333px; ">next to each story, </span><span class="Apple-style-span" style="font-size: 15.8333px; ">a row of yellow sticky notes representing the tasks needed to complete the story. </span></div><div><span class="Apple-style-span" style="font-size: 15.8333px; "><br /></span></div><div><span class="Apple-style-span" style="font-size: 15.8333px; ">The board is an artifact of our weekly planning session. We look at all the things that need to get done and choose up to ten stories for the week. But there's a catch - we've allocated a number of points to each story depending on how big or complex we thing it is. We can only choose stories that add up to the amount of points we completed last week; that's our budget. That's the general idea anyway - it's a bit more complicated than that since we're new at this and still trying to figure out what our weekly budget, or velocity, is.</span></div><div><span class="Apple-style-span" style="font-size: 15.8333px; "><br /></span></div><div><span class="Apple-style-span" style="font-size: 15.8333px; ">There is one more thing that makes this system work. We have an agreement to only complete the stories on the board. New feature requests can come in during the week, but they won't be started until they get on the board, which could happen during the next planning session. The product owners decide what the most important features are for the week, prioritize the backlog and pick out as many stories as fit the budget.</span></div><div><span class="Apple-style-span" style="font-size: 15.8333px; "><br /></span></div><div><span class="Apple-style-span" style="font-size: 15.8333px; "><b>The payoff: getting stuff done<br /></b>The story board doesn't change the amount of things we need to get done, but it does help us get the most import things (as defined by the product owners) done. During the week we can see tasks and stories moving into the done column. The developers know that new requests will not interrupt the flow of the current work and requesters know that if it's important enough we'll be working on the story in less than a week. That means we're becoming more predictable, which managers and product owners like, even if they don't necessarily like waiting. </span></div><div><span class="Apple-style-span" style="font-size: 15.8333px; "><br /></span></div><div><span class="Apple-style-span" style="font-size: 15.8333px; ">There is another intangible element to this that can't be understated - being energized by success. Seeing tasks and stories move into the done column is a good feeling. The visible indicator that we're actually accomplishing what we said we would is an affirmation that the Agile experiment is working. This is my favorite part of Agile so far - the cats are being herded.</span></div><div><span class="Apple-style-span" style="font-size: 15.8333px; "><br /></span></div><div><span class="Apple-style-span" style="font-size: 15.8333px; "><b>Final thoughts<br /></b>The story board isn't a silver bullet; we still have challenges. For instance, we've had to plan without the product owners present, making our best guess as to the priorities for the week. We also had to move our planning session a day later for one of the iterations, which throws off the rhythm of the week and made a bit of a hash of the point budget.</span></div><div><span class="Apple-style-span" style="font-size: 15.8333px; "><br /></span></div><div>Along with the story board, we also use software to track story and task progress. The reason for this is we have a bit of a distributed team. Ideally, we'd all be able to sit where we could see the board and collaborate on the stories face to face. Unfortunately, we have one developer in a different time zone and some organizational distribution that makes true co-location impossible. Software is a good solution, but really isn't a substitute for a white board and sticky notes.</div><div><span class="Apple-style-span" style="font-size: 15.8333px; "><br /></span></div><div><span class="Apple-style-span" style="font-size: 15.8333px; ">Even with these challenges, the story board has been a huge success in my mind. It gives me focus for the week, helps me prioritize my work and breaks big features down into bite size chunks.<br /><br /></span></div><div><span class="Apple-style-span" style="font-size: 15.8333px; ">Does this resonate with your experience? What are the challenges you've had with planning and completing stories and how did you overcome them? Share your thoughts - I'd love to hear them and I'm sure others would as well. </span></div></span><br /><br /></div>Anthony Israel-Davishttp://www.blogger.com/profile/01726702236067369761noreply@blogger.com0tag:blogger.com,1999:blog-5122101482600825069.post-76831677341035568932010-10-30T14:17:00.000-07:002010-10-30T16:09:26.963-07:00Real World Agile - Week Two - The RetrospectiveIn my last post, I wrote about our first week of using Agile planning and delivery techniques to better deliver value to our customers quicker. I mentioned a few of the things we started doing, a few we chose to forgo and where we met successes and challenges. One of the key disciplines that we did this iteration that we didn't do last time was the retrospective. <div><br /></div><div>The retrospective is the time the team spends examining the last iteration, release or project to find what is working well, what are areas of improvement. The retrospective exposes strengths and weakness in the team's processes, interpersonal dynamics, technologies and out of it comes a continuous improvement plan. This week was my first official retrospective and in the spirit of retrospectives, I thought I'd do a retrospective on the retrospective.<br /><br /><b>The Process<br /></b>Before I dive in to the specifics of our retrospective, I want to share the process that I'm trying to follow for our meetings. Much of the process comes <a href="http://www.pragprog.com/titles/dlret/agile-retrospectives">Agile Retrospectives: Making Good Teams Great</a> by Esther Derby and Diana Larsen.<br /><br />It's actually a very simple progression:</div><div><ol><li>Set the stage</li><li>Gather data</li><li>Analyze the data</li><li>Decide what to do</li><li>Close the retrospective</li></ol></div>This is how brains are wired to make decisions, so it makes sense that the meeting would be structured this way. However, I found that it isn't quite as easy as it looks. We're problem solvers and we want to jump right into solving and deciding without the thorough data gathering and analysis needed.<br /><br />This is where the book is really helpful for me. At least half the book is dedicated to activities a retrospective leader can use in each portion of the retrospective. The activities provide focus and keep the meeting both on topic and progressing toward its desired end. This is not easy to do and it is both an art and a skill. I'm hoping to improve as a leader the more I practice - having ideas and inspiration helps.<div><br /></div><div><b>Our Focus<br /></b>Since we had just come from Agile training, I wanted to focus on getting better at what we had learned and find the areas where we could reinforce our strengths and improve on our weaknesses. I was surprised at how well this set our agenda and direction for the coming weeks and led to some concrete improvement experiments which are already paying off.</div><div><br /></div><div><b>Setting the Stage</b><br />In a retrospective, it's important to get everyone engaged early as the input of all team members is vital for success. This is particularly challenging for us as we have a member of the team, Erwin, who is not co-located and must participate via web conferencing. </div><div><br /></div><div>After introducing the meeting's focus and going over the agenda, I asked each team member to share their thoughts from the Agile training or, for Erwin, his thoughts on our first iteration. This led to a frank discussion of the training which was valuable for me, especially since their experiences were much different than mine. We spent about ten minutes on this activity.</div><div><br /><b>Gathering the Data</b><br />Once we finished the stage setting exercise, it was time to move into data gathering. It is counterintuitive, but most of the meeting is spent in the data gathering and analysis portions. Since our focus was our implementation of Agile, I had the team list every Agile practice they could think of. This seemed like a fairly non-threatening activity that allowed us to throw a bunch of terms and phrases on the board and also pull out what things most "stuck" from our training. This took five or ten minutes before we ran out of things to add.<br /><br /><i>Areas of Improvement:</i></div><div><ul><li><i>I should have limited the activity to five minutes and time-boxed it. This keeps things moving along and helps compel people to contribute because of artificial urgency.</i></li><li><i>I should introduce each activity and its purpose. Team members need to know why they are doing something and what the intended outcome is.</i> </li></ul></div><div>This activity was foundational for the next one, which was to vote on those terms on the board (actually a list in a Word document we were sharing online) that were most important to focus on for the week. Everyone had four votes to use as they desired - four on everything, one spread across four items or any combination they wanted. My goal was to identify those areas most important to the team and begin to narrow down where our improvement would be focused for the week.<br /><br />I placed asterisks next to each item a person voted for until we had all voted. We now had several ideas with one or more vote. Looking at the list we noticed that we had about five items with two or more votes, so we decided to take those as our focal areas. This activity took about five minutes.</div><div><br /></div><div><i>Areas of </i><i>Improvement:</i></div><div><ul><li><i>Ideally I would use sticky dots on a flip chart or marker on a board, but having a remote member makes this challenging. The phone works but it would be better to find creative ways of engaging everyone.</i></li></ul></div><div><b>Analyzing the Data</b><br />Now we had some data to look at and I wanted to go deeper so that we could find which area would give us the most value as a focus of improvement. We took our five items and put them on the board in a radar graph which looked like the spokes of a wheel. I asked each team member rate the items from zero to ten in two areas: how are we doing in this area and how important is this area to our success for the coming week. Everyone placed a green dot on the spokes for the former and a red dot on the latter. Obviously, Erwin couldn't do this, so he put a colored number next to each item in the shared Word document. This took about five minutes.</div><div><br /></div><div>Looking at the board, it was clear that two areas were most prominent: communication and defining "done done". I asked the team which item we should focus on first and we all agreed that communication should be first. I then moved on to my next activity which was designed to give us improvement actions for the next iteration. This was a rookie mistake.<br /><br /><i>Areas of Improvement:</i></div><div><ul><li><i>I used the radar graph to move us into the decision-making activity. This kept the meeting moving toward its intended conclusion, but missed an opportunity to go deeper on the topic of communication. I should have spent time asking questions about why communication was most prominent, where were we falling short and communication techniques were working. This would have been useful in exposing healthy or harmful team dynamics, areas where the team felt we were lacking and given us a much stronger improvement plan. </i></li><li><i>Be sure to take time to go deep and really analyze the data. There is a healthy balance between keeping the meeting moving and making it truly valuable. Don't sacrifice the latter for the former.</i> </li></ul></div><div><b style="font-size: 15.8333px; ">Deciding What To Do</b><br />The next activity was a brainstorming activity. I liked this one because I could easily time box it, it could be done individually and out of it we could gather an actionable list of items. I set a few ground rules (aim for quantity, don't filter, don't judge, be wild and creative), gave everyone ten minutes and told them to write as many ideas about communication as they could. Ten minutes seemed long, but I wanted to give people time to think and write (or type).<br /><br />At the end of the ten minutes I gathered up all the ideas on a shared spreadsheet so we could look at them and begin filtering. I didn't anticipate how difficult it would be to come up with filters, but the team did a great job coming up with a few such as: provides value to team and is no (or little) work (e.g. simple to implement).<br /><br />It was difficult to filter our list but in the end after a discussion we came up with four things we could do this week to improve communication: use IM (we're mostly an email shop), look into better co-location of team members, a weekly informal lunch and end-of-day check-outs. After two days, I can say we've implemented two of the four (IM and check-outs) and it has definitely improved communication. This activity took about twenty minutes.<br /><br /><i>Areas of Improvement</i><i><br /></i><ul><li><i>The brainstorming and filtering activity needed to be better focused. Introduce what we're doing, why we're doing and what we hope to get out of it</i></li><li><i>Brainstorming activities need to be focused. I should have said "brainstorm ways we can improve communication". It was implicit, but should have been explicit</i></li></ul></div><div><b>Closing the Retrospective</b><br />Closing is important. It allows the team to commit to the decisions made, celebrate accomplishments and do a mini-retrospective on the retrospective. That last item was very important for me. I am fortunate to have members on the team candid enough to let me know what can be improved and some of the notes above came out of those comments. </div><div style="font-weight: bold; "><b><br /></b></div><b>Conclusion</b><br />Retrospectives are hard. They are hard to do well and hard work for the participants. For a first go I felt this went very well, but there are obviously areas of improvement to be made. I think practice and feedback will improve the retrospectives as we continue to do them. This applies both to me as a leader and participants. The real value of the retrospective, however, isn't in the meeting itself but the results it achieves. I'm looking forward to the continuous improvement that comes out of this regular meeting.Anthony Israel-Davishttp://www.blogger.com/profile/01726702236067369761noreply@blogger.com0tag:blogger.com,1999:blog-5122101482600825069.post-59387666716296194462010-10-23T14:30:00.000-07:002010-10-30T16:16:12.517-07:00Real World Agile - Week OneTwo weeks ago, I had the privilege to participate in an <a href="http://jamesshore.com/Training/Art-of-Agile-Delivery.html">Agile Planning and Delivery</a> training with <a href="http://jamesshore.com/">James Shore</a> and <a href="http://futureworksconsulting.com/what-we-know/who-we-are">Diana Larsen</a>. This week we had the chance to put that training into practice. While the training was very hands-on and interactive (we actually did four iterations and built working software the last three days), it was also in an artificial environment. In the real world, things didn't quite fit into the neat patterns we practiced in class. Here's I present what we did, what we didn't do, what worked and what needs improvement after week one.<br /><br /><div><u>TL;DR Version</u><br /><ul><li>Task Board and Test Driven Development (TDD) are Very Good Things.</li><li><span class="Apple-style-span" style="font-size: 15.8333px; ">Software tracking tools, not as useful as a rolling white board and post-it notes.</span></li><li>Early practice shows promise and we'll continue to build on what we've learned.</li></ul></div><div><br /><b>Our Early Attempts<br /><br /></b><div>There's a lot more to Agile than the ceremonies and tools - or maybe a lot less. In the past we focused on story planning, iterations and a software tool to help us keep track of what was going on, but all we were really doing was cramming a waterfall methodology into one week sprints. Needless to say, that didn't work. We didn't gain much from daily stand up meetings, putting all the stories, tasks and estimations into a tracking tool or having a scrum master. We still ended up trying to cram too much scope into too little time with the added complexity of a new methodology run by an inexperienced coach. It could have gone better.</div><div><br /></div><div><span class="Apple-style-span" style="font-weight: bold; ">What We Did This Time</span></div><div><br /></div><div style="text-decoration:underline;">Fewer Stories So Could Confidently Commit</div><div>One of the key points that I brought away from our training was to deliver value with each story. Even if the value is small, it's still an incremental gain for our customers. Rather than plan a project up front and stuff all the stories into iterations several weeks into the future, plan the week's stories and only commit what can actually get done.</div><div><br /></div><div>That last point is worth reiterating - only commit to what can actually get done. Completing stories energizes the team and gives us a real sense of accomplishment toward our end goal. We had previously guessed wrongly and over-committed and got farther and farther behind with our stories. This week, we took a look at all the possible stories, prioritized them and only committed to a handful (no more than 6-10 is a good rule). The rest went into the backlog.<br /><br /></div><div>What we knew intuitively, but failed to account for in our previous attempts was a buffer for technical debt, regular support and maintenance of other software and administrative overhead (meetings, email, interruptions, etc.). This time we left plenty of buffer and committed to paying down technical debt if there was buffer time we could use. </div><div><br /></div><div style="text-decoration:underline;">Test Driven Development (TDD)</div><div>I had previously advocated Test Driven Development to the team, but it was new, seemingly complicated and I wasn't very good at it myself. I was familiar with the concept and had done it myself, but didn't do a good job at explaining the technique or the value to the team. Luckily the training spent a fair amount of time on this concept with real-world examples and practice. And as fortune would have it, this week an excellent online meetup, "<a href="http://www.meetup.com/coldfusionmeetup/pages/Recordings%20of%20the%20ColdFusion%20Meetup-2010">Test Driven Development Demystified</a>", occurred and we could all listen in to help reinforce our learning. With that baseline established, we are committing to TDD as a regular practice for our coding.</div><div><br /></div><div>One challenge we face with TDD is that we have piles of legacy code. We chose not to try to do any retro-testing of legacy code, but rather write unit tests for all new code and test old code as we end up working with it. Part of paying down our technical debt will be refactoring old code with tests, but only as the system and time demands. Our rule is "make the code better than it was before". Small improvements add up and eventually we will be fully covered. </div><div><br /></div><div><b>What We Didn't Do</b><br /><span class="Apple-style-span" style="font-size: 15.8333px; "><div style="text-decoration: underline; display: inline !important; ">Demonstrations</div></span></div><div>We are committing to one day a week (we chose Wednesday) as our demonstration, retrospective and planning day but since we only had three days before base-lining our iteration schedule we chose to skip the demonstrations this week. Next week will be a different story.</div><div><br /></div><div style="text-decoration:underline;">Retrospective</div><div>For the same reasons we didn't do any demonstrations, we skipped a formal retrospective. Instead, we chose to talk about what we learned in the training and commit to a few key concepts (TDD and story planing being the most prominent). We also used this time to estimate stories and add stories them to our task board.</div><div><br /></div><div style="text-decoration:underline;">Use a Software Tracking Tool</div><div>Speaking of a task board, we chose to skip a software tracking tool for our iteration planning and use sticky notes and a rolling white board instead. The board is visible to everyone in a communal area and it's very nice to interact with something tangible for planning and doing stories and tasks. The board did eventually get translated into the software tool, but that is only because we have a developer who isn't co-located and we need a way of sharing the task board across time zones. </div><div><br /></div><div><b>What Worked</b></div><div style="text-decoration:underline;"><span class="Apple-style-span" style="font-size: 15.8333px; "><br /></span></div><div style="text-decoration:underline;"><span class="Apple-style-span" style="font-size: 15.8333px; ">The Task Board</span></div><div>Of all the things that are really working this week, the physical task board has to be the winner. Prominently displayed stories and tasks (completed and in progress) is a great reminder of what we're working on and what we got accomplished. Planning using the board was also much nicer as we could move stories around in priority order and drop them into the iteration much quicker than fumbling with a software tool. This is definitely a keeper and I'm actually excited about planning next week's stories.<br /><br /><div style="text-decoration:underline;">Daily Stand Ups</div><br />We went back to a five minute stand up - one minute per team member. We can check in, get a level set for the day and move into planning and clearing road blocks immediately afterward. We are using Scrum's "did, doing, impediments, confidence" questions which is working for us. When it becomes tedious or boring, we'll switch it up to something that works for us. </div><div><br /></div><div><b>Areas of Improvement</b><br /><br /><div style="text-decoration:underline;">TDD</div><div>We're all practicing TDD now, but I didn't feel I was able to really get in and write the tests I wanted to for the week. I saw plenty of room for refactoring, but a couple of in-progress stories that had hard deadlines meant I only had time to do some incremental improvements to code, rather than create fully tested objects. That being said, we spent a lot of time learning the process and tools, so it wasn't a failure, just an area for improvement.</div><div><br /></div><div style="text-decoration:underline;">Planning</div>Our planning was a bit rushed this week. Impending deadlines and being short-handed due to illness and planned PTO meant we had to crash through our planning session. We were missing our primary product owner since he was at a conference, so we did the best we could with the people we had. Like TDD, not a total failure but I'm confident we will be better next week.</div><div><br /></div><div><b>Summary</b></div><div>Agile in a classroom and Agile in the real world are two different animals. In the classroom there aren't meetings, email and support calls to take and everything works (almost) according to the book. As a way of building software, it's incredibly useful, but we're going to have to slowly incorporate all the best practices as we're able to absorb them. I would say the first week was a huge success at small improvements - each of which will add up to better efficiency, better code and better value for our customers. It might just take a few months to get there.</div><div><br /></div><div><b>Additional Resources</b><br /><div style="text-decoration:underline;">Test Driven Development</div><div><ul><li><a href="http://mxunit.org/">MXUnit </a>- This is a unit testing framework for ColdFusion. If you do CF, I highly recommend it.</li><li><a href="http://jamesshore.com/Blog/Lets-Play/">James Shore's Let's Play TDD </a>- Jim goes through an actual Java software project from scratch using TDD. You get to see it built up warts and all. It's incredibly useful to see it in action.</li><li><a href="http://www.meetup.com/coldfusionmeetup/pages/Recordings%20of%20the%20ColdFusion%20Meetup-2010">Test Driven Development Demystified</a> - this online meetup was an excellent one hour presentation on TDD and Katas. Like the Let's Play, a demonstration of TDD happened live (it's now recorded and available).<br /><a href="http://blog.bittersweetryan.com/2010/10/presentation-materials-from-my-cfmeetup.html">Slides and Code</a></li></ul><div style="text-decoration:underline;">Agile</div>There are a ton of resources on Agile out there. Here are a couple to get you started.<br /><ul><li><a href="http://jamesshore.com/Blog/">James Shore's Blog</a></li><li><a href="http://www.futureworksconsulting.com/blog/">Diana Larsen's Blog</a></li></ul></div></div><div><b>What Do You Think?</b><br />Do you have a question or comment about Agile? Have you tried it or are currently doing it? I'd love to hear your experiences and what worked and didn't work for you. I'd also like to know if you have additional resources I should add to my list. Thanks!</div><div><br /></div></div>Anthony Israel-Davishttp://www.blogger.com/profile/01726702236067369761noreply@blogger.com0tag:blogger.com,1999:blog-5122101482600825069.post-8612668978944898512010-06-25T21:21:00.000-07:002010-06-25T21:31:32.510-07:00And So It Begins...World Cup Knockout Rounds!This is a decidedly off topic post, but given Team USA's game against Ghana tomorrow, I just can't help myself. The knockout rounds are upon us and we've got a great chance to advance quite far coming out of the group stages on top. And so here I offer my video support for the home team.<br /><br /><span style="font-weight: bold;">Weezer - Represent</span><br /><br /><object height="385" width="640"><param name="movie" value="http://www.youtube.com/v/b7nCt6vWOxQ&color1=0xb1b1b1&color2=0xd0d0d0&hl=en_US&feature=player_embedded&fs=1"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed src="http://www.youtube.com/v/b7nCt6vWOxQ&color1=0xb1b1b1&color2=0xd0d0d0&hl=en_US&feature=player_embedded&fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" height="385" width="640"></embed></object><br /><br /><span style="font-weight: bold;">Video Montage of Crowd Reactions to Victory Over Algeria</span><br /><br /><object height="385" width="640"><param name="movie" value="http://www.youtube.com/v/jbn3rOPmR9w&color1=0xb1b1b1&color2=0xd0d0d0&hl=en_US&feature=player_embedded&fs=1"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed src="http://www.youtube.com/v/jbn3rOPmR9w&color1=0xb1b1b1&color2=0xd0d0d0&hl=en_US&feature=player_embedded&fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" height="385" width="640"></embed></object><br /><br />We'll be watching tomorrow - I hope to be celebrating!Anthony Israel-Davishttp://www.blogger.com/profile/01726702236067369761noreply@blogger.com0tag:blogger.com,1999:blog-5122101482600825069.post-60498338480933930822010-05-15T10:34:00.000-07:002011-06-03T14:44:04.736-07:00Using WS Security for SOAP Requests in ColdFusion<span class="Apple-style-span" >UPDATE: I've posted the source on GitHub: <a href="https://github.com/anthony-id/cfWSAuthenticator">https://github.com/anthony-id/cfWSAuthenticator</a><br /><span class="Apple-style-span"><span class="Apple-style-span" style="font-size: 100%;"><div><span><span><span class="Apple-style-span"><span class="Apple-style-span" style="font-size: 100%;"><br /></span></span></span></span></div>Late last year, I had need to use a third party API that required WS Authentication. I had the WSDLs, I could get it to work in </span></span><a style="font-size: 100%; " href="http://www.soapui.org/">SOAP UI</a><span style="font-size: 100%; "> but when I tried to get it to work in my code it just wasn't happening. It turns out that WS Authentication works out of the box with Axis 2, but ColdFusion creates all its web services with Axis 1, so I had to create the client myself.</span><br /><br /><span style="font-size: 100%; ">After quite a bit of research, it turns out this is quite easy using a couple of Java libraries and ColdFusion's "CreateObject" function. Here's how I got it to work:</span><br /><br /><span style="font-size: 100%; ">First download the following libraries:</span><br /><br /><a style="font-size: 100%; " href="http://www.aleksey.com/xmlsec/">xmlsec-1.4.2.jar</a><span style="font-size: 100%; "> - http://www.aleksey.com/xmlsec/</span><br /><br /><span style="font-size: 100%; ">An updated version is available, but this is the one I have working</span><br /><br /><span style="font-size: 100%; "><a href="http://ws.apache.org/wss4j/">wss4j-1.5.8.jar</a> - http://ws.apache.org/wss4j/<br />This is the library that does most of the work - Rampart is the portion that Axis 2 uses for this, but we needed to just utilize the signing portions for our purposes.</span><br /><br /><span style="font-size: 100%; ">The libraries need to go to [cf_home]/lib or be added to your classpath. A server restart may be necessary for ColdFusion to be able to see them.</span><br /><br /></span><cffunction name="addWSAuthentication" access="public" output="false" hint="I sign SOAP envelope using WS Authentication"><cfargument name="soapEnvelope" type="string" required="true"><cfargument name="username" type="string" required="true"><cfargument name="password" type="string" required="false"><cfscript><span class="Apple-style-span" ><span style="font-size:100%;"><br /><span>Now the jars are available for use. I created two functions to get these to work - one to do the signing and one to send the request. I have a component in which these live, but you could do the whole thing inline if you wanted to.</span><br /><br /><span>The one downside to this is that you'll need to construct the SOAP requests manually. This isn't hard if you use something like SOAP UI - I just grab the XML from there and modify as necessary. I place the SOAP request inside a cfxml block.</span></span><br /><br /><span style="font-size: 85%; "><cffunction name="addWSAuthentication" access="public" output="false" hint="I sign SOAP envelope using WS Authentication"><br /> <cfargument name="soapEnvelope" type="string" required="true"><br /> <cfargument name="username" type="string" required="true"><br /> <cfargument name="password" type="string" required="false"><br /> <cfscript><br /> // Create Java Objects from xmlsec and wss4j<br /> var WSConstants = CreateObject("Java","org.apache.ws.security.WSConstants");<br /> var msg = CreateObject("Java","org.apache.ws.security.message.WSSAddUsernameToken");<br /> // Get Soap Envlope document for Java processing<br /> var soapEnv = arguments.soapEnvelope;<br /> var env = soapEnv.getDocumentElement();<br /> var e = "";<br /> // Set Password type to TEXT (default is DIGEST)<br /> msg.setPasswordType(WSConstants.PASSWORD_TEXT);<br /> // Create WS-Security SOAP header using the build method from WSAddUsernameToken<br /> e = msg.build(env.GetOwnerDocument(),arguments.username,arguments.password);<br /> // Add the Nonce and Created elements<br /> msg.addNonce(e);<br /> msg.addCreated(e);<br /> // Return the secure xml object<br /> return soapEnv;<br /> </cfscript><br /></cffunction></span><br /><br /><span style="font-size:100%;"><span>This function sends the soap request and returns the result. The endpoint and SOAP Action can be found in the WSDL or by using SOAP UI. In SOAP UI, look at the raw post, the SOAP Action is in the headers. Also note the additional headers in the cfhttpparams - these are necessary to make the WS Authentication work. </span></span><br /><br /><span style="font-size:85%;"><cffunction name="sendSoapRequest" access="public" output="false" hint="I send the SOAP request off retrun the SOAP response"><br /> <cfargument name="endpoint" type="string" required="true"><br /> <cfargument name="soapEnvelope" type="any" required="true"><br /> <cfargument name="soapAction" type="string" required="false" default=""><br /> <cfset result=""><br /> <cfset soapenv=""><br /><br /> <cfhttp url="#arguments.endpoint#" method="POST" result="result"><br /> <cfhttpparam type="Header" name="Accept-Encoding" value="deflate;q=0"><br /> <cfhttpparam type="Header" name="TE" value="deflate;q=0"><br /> <cfhttpparam type="header" name="SOAPAction" value=""><br /> <cfhttpparam type="xml" value="#toString(xmlParse(arguments.soapEnvelope))#"><br /><br /> <cfreturn><br /></cfreturn><br /></cffunction></span> <br /><br /><span style="font-size:100%;"><span>Hopefully this will save you some time if you ever have to do WS Security in ColdFusion. It took me a couple of weeks of trial and error to get this working, but I'm now using it for two different third party APIs without a hitch.</span><br /><br /></span><span style="font-weight: bold; font-size: 100%; ">Acknowledgments</span><span style="font-size:100%;"><br /><span>The following were critical in helping me get this solved:</span><br /><span>Ben Nadel's Blog - </span><a href="http://www.bennadel.com/blog/1373-Listing-All-Classes-In-A-Jar-File-Using-ColdFusion-And-CFZip.htm">Listing All Classes In A Jar File Using ColdFusion And CFZip</a><br /><span>Steven Erat's Blog - </span><a href="http://www.talkingtree.com/blog/index.cfm/2004/7/28/20040729">Workaround for CFHTTP and Compressed HTTP Response from IIS</a></span><br /></span><br /></cfscript></cfargument></cfargument></cfargument></cffunction>Anthony Israel-Davishttp://www.blogger.com/profile/01726702236067369761noreply@blogger.com42tag:blogger.com,1999:blog-5122101482600825069.post-7650826760355284042010-05-02T22:11:00.001-07:002010-05-03T14:50:54.645-07:00CF.Objective() Pecha Kucha PresentaionHere is my <a href="http://www.pecha-kucha.org/">Pecha Kucha</a> presentation from CF.Objective().<br /><br />What is Pecha Kucha? In a sentence, it's a talk about anything you're interested in that lasts six minutes and forty seconds. Why 6:40? Because that's 20 slides for 20 seconds each that automatically advance. <a href="http://ignite.oreilly.com/">Ignite</a> is based on Pecha Kucha with the primary difference being those slides advance every 15 seconds.<br /><br />I hope to get the slides up here as well. Until then, enjoy and let me know what you think. I had a great time presenting and hope to get a chance to do it again!<br /><br />Head over to <a href="http://www.silverwareconsulting.com/index.cfm/2010/5/3/View-the-Presentations-from-the-cfObjective-Pecha-Kucha-BOF">Bob Silverberg's Blog</a> to see all the PK talks. <br /><br />All the talks in succession are <a href="http://www.youtube.com/view_play_list?p=058A5D4E2B4C4652">also posted on YouTube</a> as a playlist.<br /><br /><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/50XC-spx2Yw&hl=en&fs=1"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/50XC-spx2Yw&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>Anthony Israel-Davishttp://www.blogger.com/profile/01726702236067369761noreply@blogger.com0tag:blogger.com,1999:blog-5122101482600825069.post-20980591208404832212010-04-29T21:14:00.000-07:002010-05-01T16:23:05.346-07:00Catching the Disease - Test Driven Development with MXUnitI had the pleasure of attending <a href="http://www.cfobjective.com/">CF.Objective()</a> 2010, my first, and it was a great experience. One of the sessions, led by <a href="http://twitter.com/marcesher">Marc Esher</a>, was about integrating <a href="http://hudson-ci.org/">Hudson</a>, <a href="http://www.mxunit.org/">MXUnit</a> and <a href="http://ant.apache.org/">Ant</a>. I later attended a BoF facilitated by Marc on Test Driven Development (TDD). In that session there was discussion of becoming "Test Infected"; that is, having unit testing be so ingrained in the development process that one wouldn't think of writing a line of code without it.<br /><br />I wouldn't say I'm infected yet, but I'm starting to feel some symptoms.<br /><br /><span style="font-weight: bold;">Innoculation</span><br />A couple of years ago, I read about this TDD thing and it sounded like a good idea so I downloaded a test harness and started playing around with it. I even began writing my tests <span style="font-style: italic;">before</span> writing my objects just like the process described. It was a miserable failure.<br /><br />I wrote the tests, got little green "pass" bars and created my objects. Woohoo! But what did all those extra lines of code get me? At the time it seemed like I spent way too much time trying to figure out what to test and how to test it and not enough time actually building functioning code. In short, I just didn't get it - I must have been immune to the infection.<br /><br /><span style="font-weight: bold;">Catching the Disease</span><br />A few years passed and I began reading about this testing thing again. I had need to test some objects against a third party integration that was being upgraded and decided to try out MXUnit to write the tests; I figured it would be a better way to go than just manually executing the functions and dumping the results. I was right - it was better. Way better.<br /><br />Not only did I get little green bars (woohoo!) I also had a test that I could execute every time there was an upgrade or I wanted to change a bit of code for this object. I was getting warm - could that be a slight fever coming on?<br /><br /><span style="font-weight: bold;">Tests are NOT TDD</span><br />I was beginning to see the value in scripted testing but writing tests isn't the same as Test Driven Development. The process of TDD means writing your tests before your objects. The idea is that you know what you want your object to do or return, so write a test for it. These tests will fail because...the object doesn't exist yet. Our job as developers is to make the tests pass and in doing so writing an object that does what it's supposed to do.<br /><br />Recently I needed to create an object to return a list of courses from an online learning service. The object would return both a list of courses and an individual course by ID. It was a web service, so it needed to create the web service object which I would use to return my results. I knew what I wanted the object to do and return, so now I could write the tests.<br /><br />I started with a basic test - testCourseService.cfc. I wrote a test for the first function which I called "testGetCourses". I expected the function to return an array of courses so I needed to a) invoke the web service and b) execute the web services function to return results. I realized at this point, I would need to test that the web service returned the expected object. I continued to write tests and add functionality in tandem until I got the tests to pass. In the process, I got more than a functional object - much more.<br /><br /><span style="font-weight: bold;">Order Now and We'll Throw in the Documentation...For Free!<br /><span style="font-weight: bold;"><span style="font-weight: bold;"><span style="font-weight: bold;"></span></span></span></span>Aside from the comfort of knowing my object functions in the desired manner, I also get a host of other benefits:<br /><ul><li><span style="font-weight: bold;">Tests document the desired behavior for the object</span><br />By recording the expected behavior of each function, I can now look at the tests and see the intent. For the CourseService mentioned above I wrote a test for a getCourse method that included a test for a bad ID, no ID and a valid ID being passed into the function. In each case the expected behavior was indicated in the test.<br /><br /></li><li><span style="font-weight: bold;">Tests Illuminate Architectural De</span><span style="font-weight: bold;">cisions</span><br />In my head, I had assumed I would need a DAO for my CourseService to abstract the data access functions. I was thinking that the service would be the public interface and I would hide the internals in another object. The tests led me to drop that idea and keep everything in one object. This was a very simple component - in more a complex situation, the tests would help me understand how to design the package and dependencies before actually getting too far into the code an realizing the architecture needed a refactor.<br /><br /></li><li><span style="font-weight: bold;">Speaking of Refactoring...Tests Make Refactoring Easier</span><br />It's inevitable. You'll want or need to refactor your code eventually. Either there's a better algorithm, redundant code or new technology you want to take advantage of. Regardless of the changes you make, <span style="font-style: italic;">the</span> <span style="font-style: italic;">tests should still pass</span>. If they don't, then that tells you something about your changes. Of course, you may need to write additional tests to accommodate those changes, but when you get those green bars, you're good to go.<br /><br /></li><li><span style="font-weight: bold;">Serendipitous Decoupling</span><br />Not only would it make a great band name, it's also an additional benefit of unit testing. Objects need to be tested as <span style="font-style: italic;">units</span>, meaning each individual unit is tested apart from any of its dependencies or objects dependent on it. Because of the need to test our objects in isolation, we end up with a more flexible design that tends to follow proven design patterns.<br /><br /></li><li style="font-weight: bold;">What Am I Missing?<span style="font-weight: bold;"><br /></span><span style="font-weight: normal;">I'm sure my list is incomplete - and maybe inaccurate. What am I missing? What did I get wrong? I'd love to hear your comments<span style="font-weight: bold;">!</span></span><br /></li></ul><span style="font-weight: bold;">Much Still to Learn</span><br />So would I say I'm "test infected"? Yes, I think I've got the disease. I understand the principles behind TDD, I find testing valuable and have started to make it a regular part of my coding, but there is still much to learn. I think writing tests is as much an art as a science. Trying to figure out what to test and how to test it is a challenge and, let's be honest, it takes time to write tests.<br /><br />Luckily, there are a lot of great resources out there to help us out, some of which are listed below, and like any new skill it takes practice - a lot of practice. I'm planning on making this an ongoing series to help document my trials and tribulations in the world of unit testing and TDD. If you have any suggestions or hints or think I've just gotten it wrong - let me know! I'm new to this TDD and I know others out there are too.<br /><br /><span style="font-weight: bold;">Further Reading<br /></span><ul><li><a href="http://wiki.mxunit.org/display/default/MXUnit+Documentation">MXUnit Wiki</a> - Start here for a good overview on testing. Don't be intimidated by the "Advanced" section, either. It's worth wading into.<br /><br /></li><li><a href="http://blog.mxunit.org/">MXUnit Blog</a> - A lot of good information here - it's a blog, though, so you'll need to just browse through to find what you're looking for.<br /><br /></li><li><a href="http://groups.google.com/group/mxunit">MXUnit Google Group<br /></a><br /></li><li><a href="http://www.adobe.com/devnet/coldfusion/articles/testdriven_coldfusion_pt1.html">Test Driven Development with ColdFusion – Part 1: Driven by the cold<br /><br /></a></li><li><a href="http://www.adobe.com/devnet/coldfusion/articles/testdriven_coldfusion_pt2.html">Test Driven Development with ColdFusion – Part 2: Designing components for easy testability<br /><br /></a></li><li>Chapter 4 of <span style="font-style: italic;">Agile Software Development</span> by Robert C. Martin - It's a <a href="http://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445/ref=sr_1_3?ie=UTF8&s=books&qid=1272755245&sr=1-3">dead-tree</a> version, but worth the read. Really good overview of agile, design and UML as well. It's spendy, so I checked it out from the library.<br /></li></ul>If you have other favorite resources, let me know. Happy testing!Anthony Israel-Davishttp://www.blogger.com/profile/01726702236067369761noreply@blogger.com0tag:blogger.com,1999:blog-5122101482600825069.post-89755310102670606832009-03-08T16:03:00.000-07:002009-03-14T17:11:22.262-07:00Don't Just the Write Code, Solve the Problem<span style="font-weight: bold;">Curse of the 18 Inch Stonehenge</span><br />In the classic mockumentary "<a href="http://www.imdb.com/title/tt0088258/">This is Spinal Tap</a>", a designer is asked to build one of the Stonehenge triptychs based on designs drawn on a napkin. She builds the triptych according to the specifications and delivers the replica - but the result wasn't what the client wanted: (language warning)<br /><br /><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/WXGbwIkvh38&hl=en&fs=1"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/WXGbwIkvh38&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object><br /><br />As a web developer for a medium-sized software company, I get requests to build all kinds of things. Sometimes it's simply a process to move data from one place to another, other times it may be a full-blown application. It's easy to fall into the trap of fulfilling requests as they come in, but I've learned over the years that it will save me time and effort as well as please my internal clients if I ask an important question first - what is the problem you're trying to solve or the outcome you're trying to achieve?<br /><br /><span style="font-weight: bold;">The Doctor is In</span><br />When I go to the doctor, I don't tell her what medicine to prescribe or action to perform. I describe the symptoms, answer her questions and possibly submit myself to some tests. Developers should see themselves in the same role as the doctor - we help solve problems. Before you write that first line of code, take a step back and think about what the client is trying to accomplish. You may be surprised to find that code can't actually solve the underlying problem. You may also come to the conclusion that the original request is exactly what is needed. Regardless of the decision, the process will help you consider why it is you code what you code.<br /><br /><span style="font-weight: bold;">Code Can't Solve Everything</span><br />It's great to feel like an MVP but, let's face it, some problems just can't be coded around. As we look at the problems we're trying to solve we may discover that the problem is actually a bad business process or an outmoded way of doing things. Sometimes we are able to code around those things, but perpetuating bad business habits is in nobody's best interest. Get to the root cause and solve that problem first. Code may help, but often it's a combination of business processes, business logic and even UI inefficiencies.<br /><br />Sometimes, though, code is the answer. It's certainly part of many solutions. Well designed code can help automate manual processes, ensure data consistency and integrity and make the entire operation more efficient. Like any good machine, code should help the users be more efficient and make their work easier. If you've done that then it's a job well done.<br /><br /><span style="font-weight: bold;">Solve Tomorrow's Problems Today</span><br />It's one thing to solve an immediate problem and move on with the next project. Sometimes, that's what we have to do. But it's even better to solve tomorrow's problems before they occur. I try to make my code as future-proof and extensible as possible to avoid having to revisit it six months down the road because business needs changed. By thinking ahead we will save ourselves headaches and make our code more reusable and maintainable. A few things I've done to this end are:<br /><ol><br /><li><span style="text-decoration: underline;">Be a Detective</span><br />When a request comes in ask questions to understand what you're being asked to do. Not only will that help you code the right solution, it will give you understand business processes outside your core domain. It's amazing how much you can learn about marketing, sales and finance if only you take the time to understand the purpose behind the process.</li><li><span style="text-decoration: underline;">Offer Solutions</span><br />When you see a problem, offer a solution. It's easy to wait for a client to come to you, but you make yourself more valuable by identifying problems early and solving them when you can. It may not be possible to implement a solution right away, but if you have identified a problem and have a potential solution, it will help you code for the future as well as the present.<br /></li><li><span style="text-decoration: underline;">Solve a common problem</span><br />Things you do over and over again should be a library or class. It may entail adopting a framework from which to build or simply having snippets of code to refer back to. You shouldn't write the same code over and over, though. Reduce, Reuse, Recycle<br /></li><li><span style="text-decoration: underline;">Know your systems</span><br />Strive to understand the APIs for your CRM, financial and reporting software or the marketing systems that may be in place. Often the coder has more intimate knowledge of what <span style="font-style: italic;">CAN</span> be done than anybody else. You also know the idiosyncrasies and pitfalls of those systems. Use that knowledge to make things better.</li><li><span style="text-decoration: underline;">Maintain Your Code</span><br />Just like any machine, web code needs to be maintained. It's the most difficult part of coding for me, especially when the code is working just fine. The problem is that new technologies, design patterns and needs come along. The code you built last year may work until it needs to be extended to do one more thing. Constant refinement makes updates quicker and easier and ensures that new requirements don't cause a complete system overhaul. </li></ol>These are some of the ways I end up avoiding the Curse of the 18 Inch Stonehenge. What are your strategies for delivering what the client wants, not just what they ask for? Share them here, I'd love to know what works for you!Anthony Israel-Davishttp://www.blogger.com/profile/01726702236067369761noreply@blogger.com0tag:blogger.com,1999:blog-5122101482600825069.post-17857292312256709082009-02-27T07:48:00.001-08:002009-02-27T10:45:38.673-08:00Quick Tip: Apache, mod_deflast and JavaScriptWe've been compressing the content we serve with Apache's mod_deflate for a while, but we weren't seeing the performance gain we would like and recently found out why - our JavaScript wasn't being compressed.<br /><br />I was sure I had told Apache to compress JavaScript and sure enough there was the line in our httpd.conf file:<br /><br /><span style="font-family:courier new;">AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript</span><br /><br />So why wasn't it compressing? It turns out there is some (very understandable) confusion around the MIME type. In our HTML declaration we use <script type="text/javascript"> but that's html. The MIME specification for JavaScript - and this is what is defined in /etc/mime.types - is application/x-javascript.<br /><br />We modified our AddOutputFilterByType declaration and saw a noticeable increase in load times:<br /><br /><span style="font-family:courier new;">AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript</span> <span style="font-family:courier new;">application/x-javascript</span><br /><br /><span style="font-weight: bold;">Any Other Optimization Tips?</span><br />If you have any other optimization tips or gotchas please share them here. I'd love to hear how you've increased site performance.<br /><br /><span style="font-weight: bold;">Further Reading</span><br />JavaScript MIME Type:<br /><a href="http://annevankesteren.nl/2005/02/javascript-mime-type">http://annevankesteren.nl/2005/02/javascript-mime-type</a><br /><br />Apache Docs on mod_deflate:<br /><a href="http://httpd.apache.org/docs/2.0/mod/mod_deflate.html">http://httpd.apache.org/docs/2.0/mod/mod_deflate.html</a><br /><br />How To for mod_deflate:<br /><a href="http://www.howtoforge.com/apache2_mod_deflate">http://www.howtoforge.com/apache2_mod_deflate</a>Anthony Israel-Davishttp://www.blogger.com/profile/01726702236067369761noreply@blogger.com0tag:blogger.com,1999:blog-5122101482600825069.post-82148009295143926332009-02-05T21:30:00.000-08:002009-02-26T12:02:12.426-08:00The Power of Constraint: Why Twitter Works (For Me)<a style="" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5e6HRub6nIDtZ2QRZTaAv6R25GP-hDSegzaus5NSX9d269OCpXpUt9pfbUxYAbHMfPUjPGNJvjRgQ4VU9fNhsTyEWlDuwBZlv-NYSPNhQxlqm0UobMYtpTZGAGekDgdndRQK8OXQkvGlU/s1600-h/twitter_logo.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 100px; height: 23px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5e6HRub6nIDtZ2QRZTaAv6R25GP-hDSegzaus5NSX9d269OCpXpUt9pfbUxYAbHMfPUjPGNJvjRgQ4VU9fNhsTyEWlDuwBZlv-NYSPNhQxlqm0UobMYtpTZGAGekDgdndRQK8OXQkvGlU/s320/twitter_logo.png" alt="" id="BLOGGER_PHOTO_ID_5303565766909480418" border="0" /></a><br />I admit it - I didn't get <a href="http://www.twitter.com/">Twitter</a> at first. I don't really update my Facebook status all that often and I couldn't figure out why anyone cared what I was doing at any given time. The truth is most people don't. So I ignored Twitter, letting all the cool kids have their fun telling each other what they were doing that weekend.<br /><br /><span style="font-weight: bold;">Then it happened.</span><br /><br />My coworker, who did the bulk of the work on <a href="http://www.thevirtualblackhole.com/">The Virtual Black Hole,</a> was in China and the writers wanted to add Twitter icons and "Follow me on Twitter" links to the blog. So I dug in and got the templates updated and in the process ended up with a Twitter account of my own (<a href="http://www.twitter.com/anthony_id">www.twitter.com/anthony_id</a> - You can see the feed on the right.) I followed a few people, began posting and suddenly I began to see why Twitter was so interesting:<br /><br /><span style="font-weight: bold;">It's not about what I ate for breakfast. </span><br /><br />Twitter lies. It says right at the top of the page "What are you doing?" but people don't want to know what I'm doing. They want to know if I have any interesting ideas, links or insights. They may be interested in my response to their ideas or blog posts or simply to inform me of events that interest me. The point is that it's about bringing together like-minded people to share their interests and interact. It's about following a wide range of people and finding out what others think. And it's about interacting with those ideas and people.<br /><br /><span style="font-weight: bold;">The Power of Constraint</span><br /><br />Twitter isn't a forum, a blog or a massive social networking application like Facebook, MySpace or LinkedIn - all of which bring people together and allow interaction. But they do so in a noisy, chaotic and unbounded fashion. Which brings me to the key point of why Twitter works for me - It is constrained. It's constrained in two ways:<br /><br />1) It does one thing and does it well<br />2) Each post is limited to 140 characters<br /><br />Twitter doesn't have hundreds of applications you can add to your profile and it isn't cluttered with things all over the page. It is simply a feed of posts ("tweets") There are an increasing number of applications that use the Twitter API and expand its functionality, but Twitter itself is a simple, elegant application. It's easy to use and it's easy to understand - I read tweets and I write tweets. Advanced users may direct message, reply or retweet, but even the advanced functions are simple to use. Ease of use and application focus aren't the things that make it really useful, however.<br /><br />The thing that makes Twitter really useful for me is the character limitation. With a blog post there is this great unbounded white space waiting to be filled. It can be rather daunting. There is the pressure to not only write meaningful posts, but write them with some regularity. It takes time, planning and discipline to keep up a blog.<br /><br />Twitter has none of that. In fact, I don't have to write at all if I don't want to. However, when I do write, I can simply post a statement, link or question and not worry too much about spelling or grammar or even a general theme. I'm just myself and there is a great deal of freedom in that. I can reply to a tweet or even ask a question and anyone who is following me may answer. It's also a connection I may never have made otherwise. That's powerful.<br /><br /><span style="font-weight: bold;">But Wait, There's Less<br /><br /></span><span>From a reader's perspective, the brevity of the posts in Twitter also make it work very well. I know that I'm going to dedicate about 30 seconds to a tweet. If it contains a useful link (many do) I can follow it. I've actually seen a huge amount of useful information come from Twitter in the form of references. Using a tool like <a href="http://www.tweetdeck.com/">TweetDeck</a> I can mark tweets as favorites, categorize people I follow and filter tweets to easily find what I'm looking for.<br /><br />It's also interesting to note trends among the people you follow, find out what they're interested in and begin to make links between topics I never would have made before. And it's all (for the most part) personal. It's actual people posting actual thoughts. Yes, there are ways to automate posts, "retweet" and become simply a marketing machine. That has its place as well. But it's not what makes Twitter work (for me). It's the less is more principle and it's working pretty well so far.<br /><br />Oh, and I often eat corn flakes for breakfast.<br /><br /><span style="font-weight: bold;">What About You?</span><br />So that's (some of) why Twitter works for me. Why do you use it? Or don't use it, for that matter? How do you use it and what are your favorite tools? I use TweetDeck almost exclusively and the mobile site on my Q. Below are some other people's reason why Twitter works.<br /> <br /><span style="font-weight: bold;">Further Reading</span><br /><br /><a href="http://www.thevirtualblackhole.com/virtual-marketing/five-things-ive-learned-about-twitter">Five Things I've Learned About Twitter</a> - Karen over at <a href="http://www.thevirtualblackhole.com/">thevirtualblackhole.com</a> posted a similar article. More reasons why Twitter works.<br /><br /><a href="http://twitter.com/about#about">Isn't Twitter Just Too Much Information</a> - Twitter's own succinct reasons why less is more.<br /><br /></span>Anthony Israel-Davishttp://www.blogger.com/profile/01726702236067369761noreply@blogger.com0