Showing posts with label architecture. Show all posts
Showing posts with label architecture. Show all posts

Wednesday, September 8, 2010

Selling Software Design

There's a new software project starting up and you are assigned as the architect or technical lead on the team. Your first task is to plan and design the overall architecture to best address the requirements and the risks. To do this you rely on best practices, design patterns and past experience. After bouncing a few ideas off of some peers, you come out with an architecture that you are proud of.

Your second task is to present it to the rest of the team.

Depending on how your office operates, this part can sometimes be harder than the first especially if you have team members that you haven't worked with before. The success of any up front design depends largely on team buy-in. If they don't believe in the design, then it will come out half baked and fall apart in no time.

Ideally, you would engage your teammates early on in the design process. You obviously shouldn't go design in a dark corner and come out swinging diagrams and specifications at everyone in a command and conquer fashion. You are part of a team after all. But, on the flip side, you don't want to have ten people arguing about minor details endlessly. In software, very few things are black and white and in the end you still need someone to stop and make a decision.

At first, when someone shows some resistance to your design, they might come off as being lazy or cowboy coders. This is not necessarily true. You spent hours thinking of different ways to bring all the pieces together and formed an extremely detailed picture in your head. It's often difficult to step back and remember that others do not automatically get that big picture handed over verbatim. I bet most of the time the resistance comes from failing to properly communicate that big picture. In those cases, resistance is your friend. Encourage it. Get your team talking and challenging your design. Their questions and criticism will result in one of two things:
  1. they found a flaw in your design and it can now be addressed before a single line of code is written
  2. they misunderstood or missed something and you have the opportunity to clarify
Expect these conversations from the start and come prepared. Some of the design decisions that you'll make will appear to mean "more work". Whether it's more boilerplate code, or figuring out how to preserve context across decoupled layers, or just doing things in a way that is not obvious; implementing these decisions takes time and diligence. If it came for free, it wouldn't be a design decision, it would just be how you do things. So, if you are going to ask that of your teammates, you need to make it clear how these short-term pains will pay them back in the long run. After all, that is why those decisions were made, right? If you can't come up with a better reason than "The GoF said so", then you are over engineering.

Be prepared, but be flexible. You are not perfect. You work with smart people who have their own experience and creativity to contribute. Use it. Mix it in with yours and everyone else's and see what kind of soup you end up with. Not only will you improve the design but you'll make it a product of the entire team. Your teammates will be more likely to appreciate and respect the design if its their baby too.

Test drive your design. This is especially important if you're the only one on the team during the initial design phase. Boot strap the project and write some code. Pick a depth-first feature as opposed to breadth-first. What I mean is write a component that will drill deep into the layers of the architecture. A good candidate for this is usually something like the login/authentication component since it requires code to that goes from the GUI to the backend effectively traversing a good chunk of your design. Try implementing this in a TDD fashion using unit tests with stubs and mock data. Not only will you be validating your design, but you'll be setting a pattern. When the rest of the team jumps in, they'll have something to work from. They'll have working examples of how to create their model classes, make services calls and even how to capitalize their variable names.

Getting those doubts and concerns articulated right from the start will help get the project started on the right foot. It will set the mood for the remainder of the project and help implement the design so that it can be maintained in the long run. Of course it doesn't mean that it will maintain itself, but I'll leave that topic for another blog post.

Wednesday, July 21, 2010

Scalable Internet Architectures

Yesterday was the second and last tutorial day at OSCON.  My morning session was on scalable internet architectures which was presented by Theo Schlossnagle.  This session was excellent.  It's hard to put together a meaningful summary as there was so much covered in the three or so hours.  Some of the topics that were covered include:
  • proper configuration of static resources such as javascript files and images in order to maximize your bandwidth and make the most out of browser cache
  • traditional and less traditional databases and other persistence solutions
  • sharding, and why you want to avoid it when possible
  • network routing with dos and don'ts
  • concurrency and multi threading models
  • staffing
  • programming practices
  • ..and much more that I didn't have time to jot down.
Here are some of the take-aways that come to mind:

Cache or Accuracy?
Proper caching can usually drastically improve performance but the drawback is information accuracy.  If information is cached for 5 minutes, when that information changes, it can be reported inaccurately for 5 minutes.  The proper balance will depend on the application.  You'll often see accuracy as a requirement, such as System Xyz must be accurate.  Period.  As if you would ever assume the opposite, but still, it needs to be explicit.  Your peers in fancy suits will tell you that you can't cache during a particularly expensive task because it needs to be accurate.  But if that certain operation takes 100 hits per second and you can show that implementing a 30 second cache can avoid the need to purchase more hardware, mr. fancy suit might decide that it's a reasonable trade off.  Better yet, 30 seconds may have been reasonable by his definition the entire time.

Premature Optimization
"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.  Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified."
   -- Sir Tony Hoare (popularized by Donald Knuth)

This famous quote is stating that a good developer will know when time is worth spending on micro-optimizations.  Some developers will use optimization methods such as caching as a cop out for not spending the time it takes to design more efficient routines and algorithms.  You should design and write code to be as efficient as possible
 but really only worry about optimization techniques once you can prove that a part of the code is inefficient.  You will then be in a better position to properly analyse the problem and find a suitable optimization technique.  Of course this doesn't mean you should always ignore possible bottlenecks and performance issues, but a good developer will know when that premature optimization is appropriate.  

Mind your URL
This is usually not a proper URL:
http://www.domain.com/super_promo 
this is:
http://www.domain.com/super_promo/
and that trailing slash that your marketing team might forget to add to the URL that will be printed in flyers and typed into emails that will fill up people's spam folder could be a killer for your system.  This is extremely subtle, but most web servers will return a 302 "Object moved" response to redirect the user to the same address but with a trailing slash. That extra noise on the network could be expensive on a busy site.  It's not exactly practical to try to avoid it, the point is to plan for it.  If you load test your system using the trailing slash and think your system can handle a reasonable load with room to spare, you might be in a world of hate when your site gets Digg'ed with a URL that doesn't have a trailing slash.

A few other drive-bys:
  • Your solution will never be perfect.  You can spend an extra two weeks or month on it and it will still not be perfect.  You are often better off to implement a solution and instrument the heck out of it so that you can analyse, learn and improve.
  • Architectures are without specification of a vendor.  People tend to stick to what they know, it's in our nature.  It's important to put those personal biases aside to propose the best tool for the task.
  • Decouple your services.  This doesn't just make your code easier to maintain, it makes it easier to deploy and scale.  But most importantly, if implemented properly, it will isolate failures.
There was so much more that was discussed during this presentation, this is just what comes to mind (and what I can make out from my digital scribbles).  The presentation was recorded, but that may only have been for the live feed.  If the video is made public, I strongly suggest you grab some popcorn and sit through the entire 3 hours.  In the least, the slides for this presentation (and others) should appear on this page shortly.