in

 

Evan Hoff, Professional Code Junkie

April 2008 - Posts

  • Sun Votes for Open Source

    I managed to miss the acquisition in February, but this is really cool nonetheless.  Sun Microsystems paid $1 Billion for the commercial support vendor behind MySql (yes, the open source database).

    What was the  reaction?

    Sun Microsystems's acquisition of MySQL was "a billion-dollar vote for the LAMP stack." That's how former MySQL CEO Marten Mickos, now senior vice president in Sun's Database Group, characterized the deal during his keynote speech at this week's MySQL Conference and Expo.

    A billion dollar vote?  Daaang.

    And what did Sun's CEO have to say?

    Sun CEO Jonathan Schwartz was on hand to confront critics of the merger. "Do you all want to know our secret agenda?" Schwartz asked the crowd. "It's to serve the [open source] community. Each one of those folks represents an opportunity for Sun."

    You can read a better recap of the story here.

    If embracing open source means standardizing on high quality ways of developing software, I wonder what the impact will be on the enterprises represented in the community.

    They just might shift from competing on being able to build software (on time, on budget, etc) and instead focus on building innovative software for their business.  The difference is subtle, but the results could be profound.

  • Test First Development

    This is my attempt at sharing some of my personal reasoning around the topic of test-first development.

    Let me first sum up my thoughts in one shot:

    At the class level, form and function are significantly more important than implementation.

    Test-first development forces me to focus on the usage and external structure of the class before allowing me to create an implementation.  Within the context of a specific behavior or piece of functionality, there are an infinite number of implementations which will work.  Given the infinite number of ways to implement the piece of functionality as a class, it's the class' form that is the key differentiator.  Specifically, each form exhibits a unique set of qualities.  It's by these qualities that each implementation can be judged.

    Test-first development (as it was intended) forces me to focus on selecting the highest quality form from all designs that will meet the functional requirements.  Implementation is easy.  Design is tricky.  I choose to let that which is most important drive my development process.

    On the contrary, if the structure of the classes in your application are accidentally created as a side effect of their implementation, the system's nonfunctional properties, such as maintainability, will also be accidentally affected.  This is because the external structure of your classes are the knobs for such nonfunctional qualities as maintainability, modifiability, and testability.

    Given the importance of these nonfunctional properties, this is to be avoided at all costs.  Failure to meet nonfunctional requirements is the primary technical cause of catastrophic project and/or application failure.

    Test-first development is a risk mitigation activity for key nonfunctional system properties and a defect-prevention process.

    This ties heavily into my knowledge of system and class design--issues such as coupling and modularity.  By preselecting the form and use of the classes in my design, it forces me to think up front about the nonfunctional knobs of this cog in my system--knobs such as coupling, testability, maintainability, and modifiability.

    By preselecting the structure and functionality of the class, I constrain the implementation.

    Gold-plated code is a bit of an epidemic in the software development industry.  By constraining the implementation with form and usage, I become focused on implementing exactly what's needed--nothing more.

    Test-first development is neither a panacea nor a silver bullet.

    It doesn't guarantee I will select the best design.  It doesn't even mean my selected design is implementable.  But if and when I recognize either case, I can quickly throw away the old design and start fresh. 

    Or at least that's a side effect of having a maintainable, modifiable system.

    And lastly..

    It's about having a tight, automated feedback loop on the health of the implementation.

  • [Book Review] Software Architecture in Practice

    Having stumbled onto some of the SEI's material on software quality attributes, I decided I had to know more.  That was the motivation that drove me to read Software Architecture in Practice.  It didn't hurt when the book was shortly thereafter recommended to me by Arnon.

    On the Amazon scale of rankings, I'd give this book 5 stars (of 5).  Not only did it contain a wealth of information on software quality attributes, but it also contained a goldmine of other information as well.

    Here's a very short list:

    • Software Quality Attributes - a through introduction to software qualities (often referred to as nonfunctional requirements)  In particular, the book has a strong focus on a particular core set: availability, modifiability, performance, security, testability, and usability.  You might wonder why some other obvious qualities weren't on that list, and that's covered in the book as well (ie..scalability falls under the combination of performance and modifiability).
    • Tactics - a tactic is an approach you can use to tweak a particular software quality attribute.  Localize Changes is an example of a tactic that's described for increasing modifiability.  Generally speaking, tactics involve compromise.  As an example, using a security tactic often involves a negative tradeoff in performance (actually, almost everything involves a negative tradeoff in performance).
    • Case Studies - the book is not short on case studies, and it has some really interesting ones at that.  If you've ever wondered what the architecture of a group of networked flight simulators (military grade) might look like, a good case study is included.  Others include a study of the US air traffic control system and a software product line used to build submarines.
    • Architecture evaluation - the book serves as an introduction to the topic of architecture evaluation (through the lens of quality attributes and scenarios).  It introduces two formal frameworks for evaluation, the ATAM (the Architectural Tradeoff Analysis Method) and the CBAM (the Cost-Based Analysis Method).  While the two formal methods are too heavy for me to use practically, they serve as a good background for learning LAAAM (the Lightweight Architecture Alternatives Analysis Method).  While I'm sure several people are snickering at the thought of doing architecture evaluations, I'll just point out two facts: 1) they are practiced by ThoughtWorks (they are not anti-agile) 2) when applied appropriately, they have been known to save large amounts of money (Figures from AT&T were roughly $1M per 100k LOC - IEEE Software Apr-May 2005).
    • Real-Time Systems - This is a bit of a double edged sword.  I really like the fact that the book had quiet a bit to say about real-time systems, but in practice, most of us don't build real-time systems.  This was due to the fact that the SEI is funded by the DoD and deals heavily with military systems.
    • Software Product Lines - the book briefly introduces the concepts (there's another volume dedicated to SPLs) and provides a very nice case study.  Software Product Lines is definitely a topic I'm interested in and I hope to expand myself in this area in the future.

    Overall, I would highly recommend this book to developers who have honed their OO design skills and are looking to expand their horizons.  This book sticks to fundamentals and covers quite a bit of breadth.  I will warn you though, it's quite thick (almost 500 pages) and can be dense in spots.

  • [Book Review] The Power to Predict

    The Power to Predict is one of a series of books I'm currently sloshing through on event-based programming.  It's author is none other than the CEO of Tibco, Vivek Ranadive.  Noticing that and the forward by Frederick Smith, the FedEx CEO, it definitely caught my eye.

    The book is loosely based on the concept of Complex Event Processing (CEP), a technique that's an evolutionary step above Event Based Architecture (EDA).  The author's earlier book, the Power of Now, which I haven't read yet, is apparently more about event-based architecture (or so I picked up from the book).

    Generally speaking, the book appeals more towards the business oriented than the technical.  You won't find any code inside (not a bad thing), however, it was an interesting read to hear how real-time pattern recognition and reaction can be applied to so many industries (his examples included oil rig management, defense/military, telco, financial services, and health care).

    While CEP is pretty far from being mainstream (in the MS ecosystem anyway), it's definitely an interesting study.  Given that industry heavies (such as Google and Amazon) have been applying this quite successfully for some time, I think it's mostly a matter of time (and tooling) before it goes mainstream.

    Overall, I did like the book, however, I would probably recommend you focus your energy elsewhere--especially if you are just trying to learn about EDA and CEP.  This book has good content, but ultimately, it won't help you make the paradigm shift in thinking that EDA represents.

  • The Great OOP Misnomer

    What's the biggest minomer with OOP?

    Object-oriented programming is all about objects.

    False.  Objects are instances of classes and only exist at runtime.

    Object-oriented programming is all about class design.  It should have been named Class Oriented Programming (COP).

    Bertrand Meyer asked this question in his classic tome on object-oriented design:

    Do we design for runtime or design time?

    Answer:

    Object-oriented programming is about design-time constraints.  Concepts such as reuse, maintainability, encapsulation, information hiding, and inheritance are all design-time constructs.

    In fact, there are multiple designs that end up with the same runtime layout (objects) but that aren't all considered good object-oriented design (you can't judge the class design by what the object looks like at runtime).

    The lack of focus on runtime issues is, in my opinion, the greatest weakness of OOP.

    This was one of the issues that the Component-Orientation crowd, such as Szyperski, capitalized on.

  • What's a Transaction?

    It's an abstraction that balances the simplicity and correctness of serial data access (a single query at a time) against the performance and perils of concurrency (multiple queries running in parallel).

    I thought the definition was slightly profound in an elegant sort of way and decided to share.

  • Partitioned Complexity

    Roger Sessions has some good material I wanted to take a moment to highlight.  This is part of his work around  a new Enterprise Architecture framework, Simple Iterative Partitions (SIP).

    Correlating Complexity to State

    First, let's look at how complexity grows based on the number of significant states in a given program.  I'm not a math geek, so we are going to go with an oversimplified example.  If you are a math geek, feel free drop a note in the comments for whatever reason.

    In his example, we first look at a coin-tossing application.  In short, the requirements state that the program should detect a coin-toss and inform the user if the coin landed heads or tails up.  The user will be dropping their penny into a specially designed sensor which our program will read data from.

    Here's our pseudo code:

    PennyState state = sensor.GetState();

    if (state == PennyState.HeadsUp)
    {
       MessageBox.Show("Heads Up");
    }
    else if (state == PennyState.TailsUp)
    {
       MessageBox.Show("Tails Up");
    }

    Now that's a pretty trivial program, but if we look closely, we have two states the program can go through, heads or tails up.  In order to test our application, we would need to drop the penny in the sensor in both positions and check the output.

    Let's increase the scope of our trivial application to include that of checking a dime at the same time.  Now the user will drop a dime in the dime reader and a penny in the penny reader.  Our application will tell the user the result.

    CoinState pennyState = pennySensor.GetState();
    CoinState dimeState = dimeSensor.GetState();

    if (pennyState == CoinState.HeadsUp && dimeState == CoinState.HeadsUp)
    {
       MessageBox.Show("both coins are heads up");
    }
    else if (pennyState == CoinState.TailsUp && dimeState == CoinState.HeadsUp)
    {
       MessageBox.Show("the penny is tails up and the dime is heads up");
    }
    else if (pennyState == CoinState.HeadsUp && dimeState == CoinState.TailsUp)
    {
      MessageBox.Show("the penny is heads up and the dime is tails up");
    }
    else if (pennyState == CoinState.TailsUp && dimeState = CoinState.TailsUp)
    {
       MessageBox.Show("both coins are tails up");
    }

    You can see now that we've increased our number of basic states.  We went from 2 states to 4 by adding the second variable (the dime's state).

    This isn't really earth shattering, but we can begin to see the correlation between the number of states in the program and the amount of complexity.  In fact, you can generally calculate the number of states using basic math.

    Where x is the number of variables, s is the number of states, and t is the number of total states of the program:

    t = s^x

    As you can see, we are dealing with an exponential problem.

    Here are the numbers when dealing with an application made of variables who can have 6 states:

    That's quite a lot of states for a program with only 12 variables.

    Managing State and Complexity Through Partitioning

    Looking at the chart above, we can generally know that any non-trivial application will have a huge number of possible states.  What can we do about it?

    Well, the trick is that while a single program with 4 variables of 6 states will have a total number of just over a thousand states (1296), it doesn't have to be that way.  Here is where partitioning comes to our rescue.  In fact, if we only create one partition and split the program into two programs, we significantly reduce the number of possible states:

    Single Program of 4: 1296 states

    Single Program of 2: 36 states
    Two Programs of 2 states: 72 states

    The reduction is pretty staggering.  We went from 1296 possible states down to only 72!  That's a reduction of over 94%!

    Now if the correlation between the number of states and the amount of complexity holds true, you can just imagine the resulting change to the application.

    So what can we take away from this, without trying to calculate the number of states in our applications?

    Here's the generalized principle:

    Partitioning is a technique for significantly reducing complexity.

    And I'll create a corollary:

    Partitioning an application into Modules is a technique for significantly reducing its complexity.

    Now, we know that not all means of partitioning are equal, but I'll leave that for another post.

    If you want a bit more on SIP or the math behind partitioning (as described by Roger Sessions), I would encourage you to take a look at his website.

  • Large Scale Software Failures

    I tend to follow the news quite regularly, and if you are like me, you are probably aware of the catastrophe that is British Airlines and the new Heathrow T5 terminal.  The accumulation of a mountain of 20k pieces of luggage should give you some indication of the size of the problem.  The gist of the story is that a new £4.3 billion terminal just opened, and what was supposed to be a technologically advanced baggage handling system wasn't quite up to task.

    While I haven't seen an official diagnosis of the problem, I can't help but wonder if a group of software developers somewhere locked in a closet are to blame--not that I've ever seen a project end like that.  I'll be curiously watching to see what some type of official report says.

    This just brings back the thought of the FBI's Virtual Case File, a $100 million software failure

    It looks like Jeff Atwood has a nice collection of large scale failures catalogued as well.

Copyright Los Techies 2007. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems