CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeremy D. Miller -- The Shade Tree Developer

Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

April 2007 - Posts

  • Silverlight and the new Dynamic Language Runtime is going to rock

    I think Silverlight is one of the coolest things to come down from Microsoft in a long time.  The exciting news to me is an official announcement of Ruby & Python support.  Give me a performant Ruby implementation married to the fullblown power of the CLR and I'm going to be a happy camper.  I've started to use more and more fluent interfaces, anonymous delegates, and trying to generally move up the abstraction level with some success, but these are all things that just seem smoother in dynamic languages with metaprogramming capabilities.

    It's about time this whole multiple language/one runtime thing pays off with real diversity in language selection.  Choosing between C# & VB.Net has always reminded me of the scene from Blues Brothers when Elwood asks what sort of music they have in this place and the lady answers "we have both kinds, country and western."
     

    http://blogs.msdn.com/hugunin/archive/2007/04/30/a-dynamic-language-runtime-dlr.aspx 

    via James Kovacs

    at Anders NorĂ¥s' Blog
     

  • Remembering how to use Oracle

    I'm using Oracle for the first time in about 3 years starting today.  I thought it would be like coming home because I grew up on Oracle 7.34 and then on to Oracle 8.1.7.  I know I routinely bash the usage of stored procedures and hand rolled data access strategies as a waste of manpower for all but edge cases, but there was a day and time when I banged out stored procedures and packages in PL/SQL at will and almost lived inside a SQL*Plus window.  While I'm still more comfortable writing Oracle flavored sql, I forgot some of the annoyances with Oracle:

    • The installer just flat out sucks.  It took me 3-4 tries just to get the stinking client on correctly, and the Java installer is sloooooooow
    • Downloading the freeware TOAD once a month.  I opened it up for the first time today and was immediately greeted with a message that it expires tomorrow
    • TNSNames klooge, need I say more?
    • I've gone back and forth on this a couple times, but I think I like autonumber better than sequences now for surrogate keys.  I like letting an ORM handle the mechanics best though.

    The good:

    • The warm and fuzzy feeling.  I've built bigger, badder systems on Oracle, but always had more hiccups with Sql Server 2000 (that nolock crap is ridiculous).  Even if it's completely in my imagination, I like knowing the Oracle database engine is there. 
    • Everything is capitalized.  The old guys I learned Oracle coding from kept the caps lock on almost permanently and that's the way it's supposed to be.  I kinda think of it as the database yelling "yes sir!, fetch INVOICE_DETAIL sir!" back to me like the good obedient soldier it is.
    • Since I've still never managed to get the hang of ANSI join syntax, it's kind of nice to be able to write inner & outer joins without resorting to some sort of GUI wizard
  • Jeremy's Fourth Law of Test Driven Development: Keep Your Tail Short

    One of the first ongoing lesson for making Test Driven Development succeed for you is to learn how to write isolated tests with less effort.  My Fourth Law of TDD is all about recognizing the need to do testing piecewise as a vital part of formulating software designs.  One way or another, all design concepts come down to dividing the whole into granular pieces.  Keeping a short tail is yet one more design cue to help guide you where you want the design to go.

    To preclude any confusion, this post is in no way related to the Long Tail from Chris Anderson, it's only an unfortunate choice of name from me when I originally jotted down my "Laws of TDD" a couple years ago.  Before you ask about the "Fourth," here are links to the previous three "Jeremy's Laws of TDD." 

    1. Isolate the Ugly Stuff (Oct 2005)
    2. Push, Don't Pull (Mar 2006)
    3. Test Small before Testing Big (May 2006) 
    4. Keep Your Tail Short (this post, Apr 2007 - wow, did I get sidetracked)

    5-10 and the Zeroeth law will follow -- someday.

    I'm doing a presentation at DevTeach 2007 on Agile Design that has largely evolved into a code-centric discussion on performing design continuously.  A vital part of making the continuous design philosophy effective is to structure code so that it can easily accept change -- i.e. a heavy focus on the design principles that lead to Orthogonal Code.  Hand in hand with orthogonality for me is the usage of Test Driven Development (or Behavior Driven Development) to drive the design of the code in an evolutionary fashion.  TDD brings some important things to the continuous design table like a revved up feedback cycle and an almost mandatory focus on building a system through the systematic creation of small working pieces of code.

    I would go so far as to say that TDD is the single most important tool for doing design in the small (it shouldn't be your only design tool, but that's a very different post).  That being said, my own experience includes a couple projects where TDD either failed or didn't really wring out all of the advantages that it should.  Looking back at those projects with 20/20 hindsight, it's easy to make a diagnosis:  TDD was just too hard because far too much of the code had a long tail of dependencies that just couldn't be isolated.  If you wanted to test business logic, you had to pull in the database, push around configuration files, and often fire up the user interface for good measure.  TDD just flat out grinds to a halt if you have to tackle too many issues at one time. 

    Looking back at my previous writings on Test Driven Development and designing for maintainability there's an obvious underlying theme poking out from almost all of the "best practice" design concepts I've written about -- strive to do one thing, and only one thing, at a time in your code.  I want to work on one thing at a time because the human mind is finite in its ability to process multiple threads of logic.  I want to pick off some parts of the system that I understand and start coding and delivering value now instead of getting mired in "Analysis Paralysis" trying to see the whole picture.  I want to shorten the feedback cycle between coding and testing to work faster.  I want the ability to test cohesive areas of the code in isolation from other areas of the code to simplify testing.  And oh yeah, if I'm going to design and build things one thing at a time, I'd like to be able to put the pieces together at the end of the day and actually have them work together.

    If you can do one thing at a time in your code the Test Driven Development effort will go much smoother.  One of the first steps to doing one thing at a time is follow Jeremy's Fourth Law of TDD:  Keep Your Tail Short.  The best description for this general concept I've ever heard comes from Stuart Holloway - "When you pull a class off the shelf, what else is coming with it?."  Think of it this way, if I want to test my business rules, or my display logic for that matter, what other areas of the code do I have to pull as well?  By and large you want to answer that question with "not much."  Writing test code just to placate my database or web server when I'm testing business logic is purely overhead -- both in terms of the mechanics of creating the test and the intellectual overhead of understanding the test.

    I'm going to use several examples in this post that violate my Fourth Law to demonstrate why and how keeping a "short tail" is a more effective way to develop software.  These examples might seem contrived, but every single case is something I've worked on or caused.  Some of the worst examples are my recollections from my first, painful project using TDD when we did not keep our tail sufficiently short. 

    My First Foray into TDD Bombed

    My obsession with creating easily testable code dates back to my first official project using TDD.  Unfortunately the whole team was relatively green in regards to Agile engineering practices, and we made the typical mistakes that TDD newbies do by binding the UI and business logic too tightly to the infrastructure.  Specifically, I'm thinking about a workflow feature that I created.  It was a fairly simple state machine in terms of coding, but the automated testing was a different story.  I don't remember the exact details (repressed memory?), but you had to make the workflow actions in a perfectly sequential order.  There wasn't anyway just to create the state machine object to directly go to any arbitrary state.  You had to run the state transitions one at a time, and each state transition made calls to stored procedures.  I also had it set up so that the workflow read and wrote directly to the database.  The end result was the tests could only run against the database and every unit test basically had to include almost every action of the workflow.  The tests were difficult to write, almost impossible to debug, and very brittle since every unit test really depended on every other test.  My workflow logic had a long tail that reached all the way into the database schema -- and to add insult to injury we had a single shared Oracle schema for all development and testing.

    How would I do that today to drive the workflow through testing?  Actually, I think it would be pretty easy.  Move all of the persistence out into a Database Mapper, or just use NHibernate, so the core workflow logic doesn't even know the database exists.  Isolate the state machine code into a smaller class that basically only knows how to change its own state as a result of workflow state transitions, and maybe direct other services to perform actions.  I would tie the whole thing with some sort of Controller class that directs both the state machine class and the persistence service.  The Controller would be tested with mock objects in place of the persistence and the actual workflow state machine logic.  A bit like this:

        public interface INotificationService

        {

            void SendEmail(EmailMessage message);

        }

     

        public class StateMachine

        {

            private Status _status;

     

            // The real constructor could completely set up the StateMachine

            // to any point in the workflow

            public StateMachine(Status status)

            {

                _status = status;

            }

     

            public void CreateNew(INotificationService service, string assignedTo, string description)

            {

            }

     

            public void Approve()

            {

                _status = Status.Approved;

            }

     

            public void Reject(INotificationService service)

            {

            }

        }

     

        // The Controller class that just coordinates the services and

        // StateMachine objects

        public class StateMachineController

        {

            private readonly IStateMachineMapper _mapper;

     

            public StateMachineController(IStateMachineMapper mapper)

            {

                _mapper = mapper;

            }

     

            public void Approve(int issueId)

            {

                StateMachine machine = _mapper.Find(issueId);

                machine.Approve();

                _mapper.Save(machine);

            }

        }

    My goal is to make the StateMachine easy to test by making it easy to setup and completely decoupled from the database.  Most of the heavy duty logic is in StateMachine, so I would focus on isolating that logic and use StateMachineController to handle the coordination with other services.  In my analogy below, StateMachine is Aerosmith and StateMachineController is the roadie for StateMachine.

    Aerosmith and Roadies

    The one system structure that will never, ever deliver either testability or maintainability is the Big Ball of Mud.  In software design, it's imperative to define and assign the various responsibilities of your system to discrete pieces of the system.  I'm a huge fan of Responsibility Driven Design (RDD) from Rebecca Wirfs-Brock.  A key concept in Responsibility Driven Design is to think of classes in terms of stereotypes.  The stereotype of a class says a lot about the role and responsibility of a class within the greater system.  We can use the idea of class stereotypes to quickly break down a complex feature into smaller pieces and even give us some immediate ideas for minimizing the tail of dependencies between the smaller pieces.

    My own little spin on class stereotypes is what I call the "Aerosmith and Roadies" analogy.  Say you're Wozniak and you feel like putting on your own rock concert, what are the things that have to get done, and who does it?  The first responsibility is easy, Aerosmith plays the concert.  That's a great start, but it's a good bet that Aerosmith isn't going to set up the stage, plug in the instruments, get the green M&M's, and generally make sure that Aerosmith has everything it needs.  You're going to need the roadies and other people to setup the stage for Aerosmith so Aerosmith can concentrate on just playing the music.

    I'm working with financial companies now and many projects implement some form of market or trade analysis to support or make trading decisions.  For this case it's almost imperative to follow the Aerosmith and Roadies division of responsibility. 

    The actual analytical code is the obvious rock star.  The only thing the actual analytics code should do is take trade and market data that is handed to it and create knowledge and trends from that data.  The rock star analytics code doesn't know where it's data comes from, and it might not even know what's happening to the information that it creates downstream.  It's important to limit the responsibility of the analytics engine for a number of reasons.

    • The analytics code is potentially very complex.  It should be significantly easier to code if you can work on only the analytical code without worrying about the data source and downstream dependencies.
    • The analytics code has to be easy to test, and the easiest possible class (or cluster of classes) to test is one that takes in data through it's API and returns a result without calling out into anything else.  To make this happen, I must not have a long tail of dependencies on other systems, databases, and calls to services within the analytical engine.  In the automated tests, I can just set up the market and trade data in memory, run it through the analytical engine, and check the results again in memory.  It's critical to make the analytical code testable because it's making decisions about what to do with someone else's money.
    • The analytics code will change over time as the trading gurus tweak their trading algorithms.  The underlying data source and the downstream systems probably won't change at the same time.

    The analytical code has to fed it's data as an input, and something has to actually display or act on the results from the analysis code.  Borrowing terminology from Responsibility Driven Design again, fetching the market and trade data is the responsibility of some sort of Service Provider stereotype.  You would probably also create a separate set of service providers for carrying out the decisions made by the analytics engine after the analysis is complete.  In my Aerosmith concert metaphor, the market data service is like a caterer or a guitar manufacturer, and these people probably don't deal directly with Aerosmith.  You certainly can't expect Aerosmith to call up the caterer and make their orders over the phone, someone else is in the middle.  Wozniak needs some middlemen to go to the caterers and the moving trucks and set things up for Aerosmith to play.

    The middleman in the concert is the roadie.  The roadie runs around, gets the food and instruments from the truck, then delivers the food to Aerosmith.  The roadie gets the instruments out of the trucks, sets up the stage, and plugs in all the instruments on the stage.  All Aerosmith has to do is walk up to the stage and put on the show.  They don't have to be distracted by logistics.  The roadie is the Coordinator and/or Controller stereotype from Responsibility Driven Design.  It's a class that's only real responsibility is coordinating the actions of other classes.  The roadie is the glue.

    So does all of this Aerosmith/Roadie/Class Stereotype exercise do for us in designing software?

    1. Applying the concept of class stereotypes to the larger problem quickly suggests some division of responsibilities within the larger trade analysis subsystem.  In effect, we've set ourselves up to "divide and conquer" the code so we can mentally deal with fewer variables in our design at any one time.  We've reduced the bigger problem into smaller problems to limit the complexity of any one piece of code.
    2. The analytical code has a short tail and can be tested in isolation.
    3. The data provider is only that, a data provider.  We can test the data provider in isolation from the analytics. 
    4. Because the analytical code has no tight dependency on the data source, we can potentially use the analytics engine in a completely new context.  Today you're building the analytics engine to work on the trades previously created in your system on the server side.  What if tomorrow you want to provide "what if" calculations on potential trades to a user working in a completely different screen on the client side?  With a short tail of dependencies, the analytics engine is reusable.  With a long tail of dependencies on infrastructure, you're not going to be able to easily reuse the analytics functionality.

    Wait Jeremy, couldn't I just isolate the analytics engine by using mock objects or stubs for the market and trade data?  Yes, absolutely, but setting up mock expectations is also a dependency.  Anytime you find yourself doing the exact same mock object setup "preamble" in multiple unit tests it's a design cue that there might be more than one responsibility in the class under test.  Think about splitting up the class to test with less mock object setup. 

    Scott Bellware absolutely groans when I use this analogy, and that's more than enough justification to throw it in ;-)

    Can you get there from here?

    Here's an analogy for systems that are hard to test.  We live in Stamford, Connecticut.  My extended family is mostly scattered across the area where Missouri, Arkansas, and Oklahoma come together.  When we visit my relatives there simply isn't an easy way to fly from one place to the other.  We've got to detour through Charlotte or Pittsburgh or Houston to get from one place to another, not to mention the effort of driving to the airport. 

    A couple years ago I made a first pass at adding diagnostic functionality to StructureMap to create user friendly messages for common configuration errors.  I created a class hierarchy that represented an instance, all the arguments to its constructor, and its dependencies.  This diagnostic class (InstanceGraph) could only be constructed by passing in a .Net Type and a fully formed object containing the configuration of the instance.  Every time I needed to write another unit test I had to jump through hoops to create a fake Type with the correct constructor arguments, set up the configuration for the instance, then I could finally build the InstanceGraph object and look at the problems that it detected.  It just took way too long to build tests, especially since I was having to do a lot of setup that really didn't have any semantic meaning to the assertions in the unit tests.  In the end, I realized that the diagnostics could really be modeled as two distinct responsibilities:

    1. Parsing the .Net Type's and the configuration into a "design time" model
    2. Analyzing the "configuration time" model to look for missing, invalid, or inconsistent configuration

    In essence, I cut off the reflection "tail" from my diagnostic code.  I created that new model that had absolutely zero dependencies on System.Reflection and just like that I was able to write unit tests with very little friction.  I could skip the "create fake Type" test setup and go straight to the exact scenario that I wanted to test.  I'd say that I made two improvements:

    1. The unit tests required less mechanical setup work and therefore unit testing was faster
    2. The unit tests were easier to understand because there was less code noise from all of the test data setup.  That's an important quality because unit tests serve an important secondary role as low level API documentation.

    Of course I still had to build code that knew how to use Reflection on .Net Type's and the StructureMap configuration to build up the design time model, but that code is now relatively simple.

    One of the important things I've learned is that excessive test setup work is a code smell that points to a possible problem in your design.

     

    Test by Measuring What You are Trying to Test!

    A couple years ago I inherited a .Net application from another team that had just finished doing a partial rewrite from VB6 and ASP classic.  I know that team was trying to use Test Driven Development in their daily coding, but I think they hit the exact same problems with testability that I experienced on my first TDD project by letting the business code get tightly coupled to both the database and the user interface.  The application took in submitted invoices, performed copious amounts of business rules validation, and either succeeded and sent the invoice on to the downstream systems or reported the list of validation failure messages.  One of the immediate problems was the main class that built the user response was a long set of procedural code that intermingled the html creation and the business logic like this (it had been a straight port from VB6 & ASP Classic to C# by people who had never done .Net, so cut them some slack here):

        public class InvoiceScreenCreator

        {

            private readonly Invoice _invoice;

     

            public InvoiceScreenCreator(Invoice invoice)

            {

                _invoice = invoice;

            }

     

            public string CreateHTML()

            {

                string html = "<h3>" + _invoice.InvoiceId + "</h3>";

     

                // Run the complex invoice validation logic

                if (someFairlyComplexBusinessLogicDeterminationOnInvoice(_invoice))

                {

                    html = html + "<p>The invoice succeeded!</p>";

                }

                else

                {

                    foreach (string errorMessage in _invoice.ErrorMessages)

                    {

                        writeInvoiceError(errorMessage);

                    }

                }

     

                return html;

            }

        }

     

    There's plenty wrong with that general approach, but the killer to me was that there was quite a bit of complexity in the business rules and the only direct way to measure the business logic outcome was to scrape through the html created by the InvoiceScreenCreator class.  You're effectively testing business logic through side effects, and you're not able to write isolated unit tests for either the user interface or the business logic.  If something is wrong in the tests you have both UI and business logic to debug.  Testing business logic through the user interface can easily detract from the understandability of the test as user interface verbiage is intermixed with the core business logic.  It works the other way around too.  Creating the user display was nontrivial and it would have been beneficial to test the user display in isolation from the invoice validation logic.

    Oh, and needless to say for anyone who wrote or maintained ASP Classic back in the day, intertwining business logic in the middle of concatenating html together almost completely repels any effort to understand the business logic.

    Again, the solution is to separate the responsibilities for the user display and the business logic into different classes or subsystems.  The business logic runs against the submitted invoice, makes the validation determinations, and builds some sort of object that reports all of the validation information.  The user interface code could just take the completed validation report and create the display.  Make that separation and now you can test either piece in relative isolation.  In reality, the user interface and business logic are likely to change at different times.  It's worth your while to be able to change one without either affecting the other or having to understand the other piece while you work.

    Of course another lesson is that you pretty well get what you deserve when you do a straight port of dubious quality legacy code.

    Isolate the Churn

    Some elements of your codebase are going to change much more frequently than the rest of the system.  Some modules may need a very large number of testing permutations to fully cover all of the input possibilities.  In either case it's very advantageous to isolate these areas of your code from everything else.  It's smart to optimize the mechanics of testing for these modules by having a quick path to create test inputs and measure the outcome without involving any other piece of code..  Case in point, working with financial companies now I'm frequently bumping into systems that perform analysis on trade and market data to determine pricing or trading strategies.  The analysis code, especially if it's a trading strategy, is going to go through a lot of churn as the algorithms change while the backend storage for the trade and market information remains relatively unchanged.  The analysis code will inevitably require a large number of test cases to cover all the permutations of business conditions.  I think it's probably fair to say that the bottleneck in delivering the trade and market analysis is most likely the testing time and overhead.  Making that code easier to test by limiting its tail of dependencies should optimize your time to ship that code.

    Of course, if you treat the trade and market analysis code like the rock star it is, then it's already going to be isolated with a minimal tail of dependencies and you're good to go.

    Whenever you can, keep the Database on the Sidelines

    The database cares very deeply about the complete integrity of your data -- heck, that's a large part of a relational database's very purpose in life.  That very data integrity goodness is a lot of what makes a database a PITA when you're constructing automated tests.  To write an effective automated test you need to establish a combination of known inputs and expected outputs.  If you're testing against the database that means loading the database with data.  Sometimes that isn't that big of a deal, but with any level of database complexity that quickly turns into a pain because:

    • Database access in tests will make the tests run slower than tests that run completely within an AppDomain.  And yes, automated test execution time is a big deal, worthy of serious design consideration.  Enough so that I'd call it a justification by itself for decoupling business logic from the database
    • You have to make sure that dependent data is loaded first for referential integrity.  You can load a set of known reference data to help with this, but tests are generally much more comprehensible if you can see the test inputs and outputs in the same screen.
    • You have to supply some data to the database for non-nullable fields that isn't relevant to the test.  It's extra mechanical work and it's noise code in the tests.

    Think about this very realistic case.  You're building a screen to edit an existing invoice.  If the invoice has already been paid you want the screen to disable editing.  When I'm testing my presenter/controller for this scenario the only piece of information I need to set on an Invoice object is some sort of IsPaid flag.  Think about the test setup overhead of just creating an Invoice object and setting a single property versus the effort it typically takes to create an invoice in the database tables.

    You may not interpret anything in this section to mean you shouldn't use referential integrity checks in the database.  Leaving off referential integrity checks in the database is a lot like opening the kitchen door in the summer and letting all the fly's in.  It's just asking for really weird bugs in the system.  Moreover, I've often found that a lack of referential integrity makes it harder to write integration tests.  Let the database do its thing, and the business logic do its thing without each other getting in each other's way.

    Conclusion 

    Sometimes the fastest way to get code working is to write code in more, smaller pieces.  It may seem like more complexity, but I'll argue vociferously that it's better to minimize the complexity of any one part of the system rather than minimize the number of pieces in the system.  Software design and construction is all about divide and conquer.  Big classes and methods spanning multiple responsibilities and multiple concerns will never, ever be as efficient to ship as a well factored system.  Remember when you're deciding how to structure your code that code cannot ship until testing is complete.  I

     mostly presented the "Keep Your Tail Short" law in terms of testability, but it also goes a long way towards creating more opportunities for reuse and extension of the existing system.  That's crucial for doing continuous design.  Putting off technical complexity and delaying architectural commitment works best when the code is malleable, and that's enabled by minimizing the dependency tails between the classes in the code.

     

    Wait, there's even more!  I'll write a follow up soon with some more concrete examples of "Keep Your Tail Short" in regards to enterprise development.  I'm using this post, and several others over the next couple weeks, to flesh out my talking points for my "Laws of Agile Design" talk at DevTeach.  Feedback and criticism on this post would be very much appreciated.

     

  • Get a Build Server and Keep it Clean

    The importance of a clean build server was reinforced for me this morning.  We're getting ready to wrap up our first demonstration of our executable for users in a different timezone in London.  Everything is wonderful on our developer workstations, but not so good on a clean box.  It's the normal culprit, a 3rd party control library needs some licensing info embedded into an assembly or has to be installed or something else.  We found the problem easy enough before it hit the end users because we run the client on our build box that doesn't have Visual Studio or the control libraries installed into the GAC.  A clean build server finds these problems for you fast so the customer or testers don't.  Whatever you do, don't put Visual Studio on your build box because it can fool you into thinking your installation script is complete when it only really works because of the assemblies that VS GAC's for you.

  • Today's deep thought

    In the absence of any other compelling knowledge, take the message of an exception at face value.  Don't make up elaborate reasons in your own mind.  If it says the .Net 2.0 SDK isn't installed, just go install it.  Doh.

    Also remember Occam's Razor too.

  • Jamie Cansdale is my hero

    I've had a minor epiphany in the last week or so.  For some boneheaded reason I never caught onto TestDriven.Net's "Repeat Test Run" feature until I saw somebody mention it on a comment to Ayende's post.  I promptly went into VS.Net and set up keyboard shortcuts for "Repeat Test Run" & "Repeat with Debugging."  No more hunting around in the open window list trying to get back to the test fixture, just go "CTRL-2" or "CTRL-3" (my mappings) and run the last test.  Anything that makes the mechanics simpler just frees your mind for the meatier thinking work.

    It's a deceptively simple looking tool, but there's goodness galore in TestDriven.Net.

    Tips on setting up the keyboard shortcuts:

    http://weblogs.asp.net/nunitaddin/archive/2004/08/30/222447.aspx

  • Self Organizing Teams are Superior to Command n' Control Teams

    I've been thinking a lot lately about self-organized teams versus teams that are run in a command and control manner.  My experience and observation is that self organized teams blow the doors off of teams that are tightly controlled by some type of centralized leader.  I'll throw out a couple reasons why I think this is:

    • People in a self-organized team are able to make decisions themselves and accordingly adapt to changing situations.  Command and control grunts have to wait for the boss to tell them what to do.  That introduces latency in the development process as the team waits for the leader to shake free to deal with a decision.  It can also sap a developer of any energy to contribute to the design and approach if they know they don't have any say in the matter.  It's a negative incentive to increase their intellectual participation in the project, and that can only hurt the team.
    • Self organized teams do a much better job of utilizing the talents of the team because more minds are involved in any activity.  By investing one person with all decision making authority, you effectively shut down the other team member's contributions to the design and planning.  They become drones.
    • Self organized teams have much more communication between team members.  A command and control team chokes communication by running too much through one person.
    • Command and control organizations don't provide as many chances for personal development.  The best way to learn is to have actual responsibility and opportunities to do new things.  If all you do is what you're told without question, you don't get to learn how to make decisions.
    • A self organized team is collectively aware of the upcoming work and much better able to bootstrap themselves with new work when they complete their existing task.  I've learned that there's a lag between telling a developer to write a feature and the beginning of coding because it takes some time to understand what's required.  You can cut down that lag by doing planning and design together as a team.
    • Self organized teams spread knowledge around much better and make decisions together.  That makes each team member more effective because they have much more background on the "why" of the coding assignments.  A command and control team member often lacks an understanding of why a decision was made because they weren't involved with that decision.  That hampers their ability to follow a design or approach.

    Maybe that works for some perfect team Jeremy, but I can't trust my guys to bootstrap themselves.  I have to be in control.  Are you sure?  Really?  You'll never know how people will deal with responsibility until they actually have some.  I'm actually an optimist in regards to people.  I actually think people can and largely will behave in a responsible manner. 

  • A Train of Thought

    I'm two weeks into a new project in midtown Manhattan, and I'm using the train rides to do side project things.  Coming home this evening there are a couple things I'm thinking about, so here's a Bare Naked Ladies-style stream of consciousness blog post (my wife hates BNL for that, but I'm a fan).

    Novelty in Your Design Deserves Extra Scrutiny

    Innovation is a great thing, and the final book on software development is still in a rough draft.  That aside, I want to urge a great deal of caution when you use any kind of design that contains elements of novelty.  When you go off the beaten track, you need to be more reflective than normal because you're taking on additional risk.  Is my new idea just a crackpot idea?  Does it really provide any real value over boring, run of the mill patterns?  I've seen too many grand, creative ideas go sour -- and a couple turn into big successes.  By all means, be innovative and creative, but you better be watching the feedback from your innovation and be prepared to walk away from it if necessary.

    The DNR Episode on the Entities Framework

    I like DotNetRocks, but I don't often remember to listen to it very often.  After Ayende and Scott both made some not quite positive commentaries on the podcast featuring Daniel Simmons (Microsoft guy, not the author of Hyperion) from the Linq to Entities team, I gave it a listen.  I didn't hear anything on the show that particularly changed my mind about the Entities Framework.  I still think it's a piece of very impressive technology that's saddled with questionable usability for the way I want an ORM to work. 

    The strongest comment I want to make about the episode is that I think the hosts didn't quite ask the right questions.  Almost the whole podcast was data access this and sql that.  Data access and persistence is a big issue yes, but to me the choice of persistence strategy is driven by the business logic first with performance a close second.  The real question is how does the EF allow me to write business logic in isolation from the database?  It's important to me to write business logic code in a way that makes that code easy to write, read, and test.  My first step to meeting those goals in building a business logic intensive app is to isolate the business logic away from the details of the backend storage, and that's why the "NHibernate Mafia" wants Persistence Ignorance for our domain classes.   

    Oh, and I hate the dichotomy between business objects and entities.  The very term "Business Object" is rife with ambiguity.  I like the Evans terminology and mindset better.  I have domain model classes (Entity in Evans terminology) and little "s" service classes for the things that don't fit into domain model classes.  I think the old "Business Object/Entity" split reflects a largely procedural mindset where logic and data are two different things -- you basically have lumps of data (recordsets) and classes that manipulate those lumps of data.  It's classical procedural programming. 

    OSS and the Long Tail

    When we were at the MVP Summit we heard Don Box effectively blow off TDD/BDD/DDD as just passing TLA's.  His contention was that Microsoft didn't, and shouldn't, favor any particular TLA style of development.  I thought Don Box told a pretty big fib on that one.  Most of the the tooling from Microsoft is built around RAD with a very obvious preference for a datacentric view of software development.  Not because Microsoft is evil, or intellectually sluggish, or any other nefarious reason.  I would guess that Microsoft largely focuses on the Visual programming paradigm because that's what Microsoft developers generally seem to want.  In the end it's hard to argue with the fact that Microsoft is just doing what the biggest share of its customers want them to do.  It actually sounds like good business practice to me.

    You've probably been subjected to the Long Tail idea.  The mainstream approach in .Net is RAD, but I don't want to have to work that way.  I'm generally in the newly christened, and mildly self-deprecating, ALT.NET camp.  Focus on the "ALT" -- as in alternative, as in "not the mainstream."  I know full well that I'm going against the .Net grain in the way that I develop, but fortunately, there's a lot of OSS tooling to enable my preferred approach to software development that Microsoft tool simply do not.  OSS is effectively the major source of diversity in software development right now.  OSS development improves the practice of software development by giving us choices that divert from the Microsoft mainstream.  There just can't be any one way that works for all systems.  OSS tools are our Long Tail for .Net development.

    Functional Programming

    I wish I knew more about Functional Programming, and I'm finding myself using more anonymous delegates and wishing for C#3 lambda expressions.  I don't know about FP taking over the world and replacing OOP, first because I'm not completely convinced that that's a good idea, and second because after 30+ years OOP has never really surpassed procedural programming, so how much chance does FP really have to become dominant in my lifetime?  I do know that I don't want to be some old guy that just can't get the newer functional programming style because I'm stuck in OO -- just like the guys who simply cannot shake structured programming and still write COBOL in C#.

  • My Crackpot Idea for WinForms Development

    Automated testing, especially at an acceptance level, can be a bear with WinForms applications.  On my last project we effectively abandoned integrated FIT testing against the UI.  We tried to go down a path of writing Window Driver's against each big control, and driving that through FIT & NUnit tests with NUnitForms.  It just turned out to be too much work, too much duplication of information, and just plain laborious. 

    There are definitely some things you can do to enhance testability.  The various flavors of Model View Presenter come to mind immediately, but that can easily bring on some repetitive coding around filling dropdown lists, validation, and coordination with views. 

    I'm going off the beaten path in my new WinForms project.  I'm ditching WinForms data binding altogether because it plays utter havoc with automated testing.  Instead, I'm building my own programmatic data binding that effectively embeds a Window Driver class directly into each User Control.  The "ScreenBinder" class is configured programmatically with a fluent interface (Martin says the best way to understand the limits of a technique is to overuse it;). 

    I'm trying to kill 4-5 birds with one stone:

    • That fluent interface contains grammars to declaratively attach properties of the model class to elements on the page.  In effect, I'm recreating data binding, but in this approach I'm going to have explicit control over when things happen.  No more goofy hocus pocus focus stuff to get data binding to fire inside tests.
    • The ScreenBinder will also double as a Window Driver that I can use inside automated tests to find screen elements by either the bound field name or the attached label name.  I'm already building a reusable DoFixture right off the bat that can act as the foundation for a testing DSL to express screen requirements in automated tests.  On my previous project we were routinely killed by "oh yeah, this element should default to XYZ when ABC happens like the legacy system" type of requirements.  This time around I want to be able to capture that stuff upfront in human readable FIT tests that can be run in the automated builds.
    • Declaratively add minor screen behaviors like filling a combo box with data from the service layer with a grammar like "Bind(SomeConstantClass.Category).To(categoryComboBox).WithLabel(categoryLabel).FillWithList(ListType.Category)"  Basically, I'm hoping to have a single abstract method that's overriden in each UserControl that declaratively defines much of the behavior of the screen.  One of my design goals is to be able to quickly understand the behavior of a screen largely by reading through this method.
    • Wait, you're putting more behavior in the screen!  Isn't that wrong?  Well generally I'd say yes, but the underlying goal is to make code easy to write, change, read, and test.  I'm using what I call the "Micro-Controller" pattern to define little reusable controller classes to drive one element at a time.  Those little micro-controller classes can be TDD'ed to my heart's content.
    • I'm building a quick test harness with NUnitForms to make declarative assertions against one of my BoundControl's for common functionality.  I'm figuring that by making the screens easier to test inside of NUnit that I can get away with thinner Presenter's.  I'll probably go with a Supervising Controller for more complex logic and dealing with the service layer.
    • The ScreenBinder ends up being a great way to bind declarative validation rules to the proper screen elements.  I simply capture a Notification object that relates validation messages to the property of the Model class.  The ScreenBinder knows the correct element for a given Model property, so it's not that hard to go the extra step to attach validation messages to the proper screen elements.  On my last project one of my client developers built something similar to the new Validation Block that used attributes on our domain model classes to enforce validation logic.  We did use the BindingSource on the screen to attach validation messages to the proper screen element.  I'm going to do the same thing here, but use a Notification object in between to make validation logic easier to test.

    So, the question I ask you, gentle reader, is how crackpot is this idea?  If it works I'm thinking about harvesting a new OSS project out of this work (after DevTeach and a solid StoryTeller beta and assuming that the client is okay with it).  Otherwise, if I never post about it again it's a good bet that it failed. 

    There's no possible way that it would fly with my client, but I wonder how much better this approach would be if I could drive the UI with the RubyCLR bridge so I could use the declarative ActiveRecord validation scheme and symbol.  I think the Fluent Interface approach would be more effective in C# 3 with the ability to use extension methods to add application specific additions to the fluent interface.

    I'm working solo at the minute, but I'm going to be joined by another Finetix developer soon.  One of the first things I'm going to do when he onboards is get his opinion on the "novelty" portions of my envisioned approach.  If that approach doesn't fly with him, it probably gets scrapped.  And if he's enthusiastic, then we still need to be careful because then we're just guilty of group think.

  • Bloom's Taxonomy and Design Patterns

    Warning!  Pedantry and self-indulgence ahead!

    I'm a big fan of design patterns and I feel that they are an almost mandatory subject of study for all serious developers.  I think I'm going to make the "You really should learn design patterns" post an annual event.  However, any time I've posted on design patterns I invariably get a couple comments from readers who have had very negative experiences with design patterns -- mostly from "other" people getting patterns happy and slinging them around foolishly or unnecessarily.  So before I lurch into yet another exhortation to go study design patterns, let's talk about what it means to "know" something.

    Bloom's Taxonomy

    Bloom's Taxonomy is a classification of the different levels of learning and understanding used by teachers to set objectives for students.  I mentioned this in a conversation at work last year and got some blank looks, but I think it's a very valuable tool for judging a person's grasp of a subject.  One of the things that originally sparked this post (the draft is over a year old;) was a developer I interviewed that claimed to be an absolute stud at ASP.Net.  Bloom's Taxonomy lists six different levels of learning.  I think our ASP.Net stud was largely basing his perceived expertise on knowing a lot of facts.  Memorizing the page event lifecycle in ASP.Net is an impressive achievement, but it doesn't mean crap in the greater scheme of things if you don't understand how to use those facts. 

    Using ASP.Net as our context, here's how Bloom's Taxonomy breaks down:

    1. Knowledge - A developer knows some facts about ASP.Net.  They can recall information about ASP.Net.  They've memorized the event lifecycle.
    2. Comprehension - A developer understands ASP.Net and can describe ASP.Net in his or her own words.  They understand the flow of the event lifecycle and can describe it.
    3. Application - A developer can actually use ASP.Net to create solutions outside of the classroom Northwind applications.  A developer at this level can actually earn a salary for programming.
    4. Analysis - A developer can trouble shoot ASP.Net programs.  He or she understands the various technical pieces of the ASP.Net architecture and understands how they all fit together.
    5. Synthesis - A developer can take the pieces of ASP.Net and build something totally new, like a new layout framework or their own content management system on top of ASP.Net
    6. Evaluation - The highest level in Bloom's Taxonomy.  The developer is able to make qualitative judgements about the appropriateness or effectiveness of his or her ASP.Net solution.  At this point they've discovered that ASP.Net WebForms isn't an ideal architecture for sustainable development and they're studying a myriad of Rails like MVC frameworks and pondering continuation based solutions (couldn't help myself).

    I'll posit the theory right here that developers are better with any given technology as they progress up Bloom's Taxonomy.  I'll go even farther, you're not good at a technology, platform, or framework until you get to levels 5 & 6 on Bloom's Taxonomy. 

    When I was on a central architecture team years ago our management had us do a self reported skills assessment listing our level of expertise with various technologies.  Looking through the complete Excel sheet you would have thought we were a veritable pantheon of Software Development gods.  The reality was much more pedestrian.  I think that kind of list would be a lot more accurate if we were marking our level of expertise as "Knowledge" with Java, "Analysis" with Oracle, and "Evaluation" with VB6.

    So, when I say go learn design patterns, I really mean to keep climbing up past lower level Knowledge, Comprehension, and Application into the higher levels of Bloom's Taxonomy where you're more capable of making qualitative judgements about the appropriate usage of a design pattern.  Knowing the names of patterns and even how to apply the patterns isn't as helpful as knowing when a pattern is and isn't beneficial.  A very important part of learning design patterns is being able to evaluate the usage of a pattern in a given situation.

     

    Why a Study of Design Patterns is Valuable

    I think a study of design patterns is a great way to boost your abilities as a developer and designer of software.  Jean-Paul thought so too in Build a Solid Core.  I've gone down this path before, but from conversations I've had recently, three big reasons come to mind:

    1. Faster communication and understanding.  Last fall a senior developer at my client was describing a feature of their proprietary ORM tool.  All he was describing was their implementation of the "Unit of Work" pattern, only he didn't know the term for it.  Because I'm familiar with that pattern I was able to quickly understand and even apply that feature in our development.  If he had been familiar with the pattern name, he could have described their framework to me much faster.  Moreover, assuming my explanation isn't sufficient, or they want to read over it out of band, I can simply refer other developers to the PEAA book to read a much better explanation.  With a few exceptions, I've spent most of the last 3-4 years coming from behind other developers and working on existing systems.  Being a student of design patterns has helped give me categorize and understand the existing solutions that I've come across faster than I think I could if I wasn't familiar with design patterns.  Unfortunately the most common pattern is the Ball of Mud, but that fact is just another reason to learn about better patterns like "Layered Application."
    2. It's all been done.  A client developer I worked with this year told me one time that he just tried to do the right thing by applying good design principles and the result just happened to look like design patterns.  At which point he paused and looked pensive for a moment.  So yes, Derrick, that's kind of the point of learning patterns in the first place.  Most of the design patterns out there are a culmination of years of learning by developers who came before us.  It's a great shortcut in your career progression to simply borrow the lessons learned by older developers.
    3. Know your options.  I've been putting together my DevTeach talk on Design Patterns for WinForms development that will deal with different patterns for structuring WinForms screens.  It occurred to me that one of the most useful things about studying design patterns is simply learning about other design alternatives.  There's no way to know this for sure, but I'll bet you that the mass majority of WinForms work is done with the Autonomous View style, mostly because developers don't even know that there are alternatives like Passive View or Presentation Model -- or why those alternatives can be preferable.  Who knows, maybe learning about the different branches of the Model View Presenter tree will give developers some inspiration to do something totally new and better.  If nothing else, learning about design patterns will make you challenge your own designs.
  • StructureMap.DataAccess

    I forgot to mention it, but there is a new component being shipped with StructureMap called StructureMap.DataAccess.  It's just a little helper component that wraps common ADO.Net manipulation I use when I need traditional DAL functionality (think opening and closing connections, try/catch, better exception messages, transaction management, etc.).  I finally combined it into StructureMap under the Apache 2.0 license mostly because I wanted to use it across projects, mostly to write test automation harnesses and other little utilities.  Life is simply too short to waste human being time on ADO.Net manipulation.

    Feel free to use it, steal code from it, or just plain laugh at it.  Be aware that it's optimized for ease of use, not performance. 

    Part of the value of OSS is that you can read the code and under a permissive license, lift out that code to use somewhere else.  I've done it with NUnit & NAnt, so I certainly don't mind if anyone tinkers with StructureMap or StoryTeller.

    Right now it only supports MSSQL because that's all I've been using the last couple of years.  I had an Oracle version a rewrite or two ago that I'll probably add back in soon for my current project. 

    I'm thinking about harnessing some FitNesse fixture classes from a past project for setting up and executing data intensive FIT tests that used DataAccess and releasing those fistures as part of StoryTeller, again so I can reuse that stuff across projects.

    StructureMap was originally intended to be an O/R mapping and data access tool, and StructureMap.DataAccess is all that's left of that original pipe dream.

  • I'm a moron

    I've blown about 2 hours over the last two days on this one. I have a couple of namespaces called "Binding," one in the UI project and another in the unit testing enviroment.  These files keep getting mysteriously blown away periodically.  I finally put 2 & 2 together and remembered that I have this little snippet in the NAnt build to clean up bin/debug & obj trash files:

     

      <target name="cleanJunk">
        <delete failonerror="false">
          <fileset basedir=".">
            <include name="source/**/obj/**"/>
            <include name="source/**/bin**"/>
            <include name="**/_ReSharper*"/>
            <include name="source/**/*.resharperoptions"/>
          </fileset>
        </delete>
      </target>

    Just added another "/" behind "bin" and the disappearing file problem magically goes away.

    Sigh.

  • Just some thoughts this morning

    Just some things that are percolating in my head this morning on the train ride to work that just won't make a real post.  I write some posts for my readers, and some posts just to compose my thoughts.  This is definitely the latter.

    Create Knowledge Together

    Yesterday I had a meeting where the client's lead and I started laying out some design ideas and approaches to other members of the team.  The meeting ended up being almost a near rehash of the exact same conversations that the client lead and I had already had over the past week and I think that it flustered him a little bit.  My thought was that we really should have had those conversations with a broader swathe of the team in the first place -- and will from here on out.  You create a lot of knowledge in a software project, especially in the early stages of the project.  It's never enough just to create that knowledge, you also have to transfer that knowledge somehow to the rest of the team.  Knowledge transfer is most effective when the "why" behind a decision is also communicated. 

    There's a bit of danger in having only the senior most guy(s) or gal(s) do the heavy thinking in isolation for too long.  It may seem like it's more efficient to keep the other developers working on other things while your senior most person is working solo to prepare the field, but many times it's more productive in the end to have more developers involved in the knowledge creation early to cut down on the overhead of communication later.  The hardest part of leading design efforts to me is the communication aspect, not the design itself.  I distinctly remember being very frustrated on my first lead assignment because I had everything thought out in my head, but I just couldn't get that vision across to my team.  The end result was that I wrote maybe 90% of the initial code on a 4-5 developer team.  If the other developers had been involved earlier, and I had done much more collaborative design, I bet that 90% figure would have been much lower and we would have finished with much less overtime.

    I'm largely an introvert, so one of the hardest things for me on software teams is trying to think out load and do design collaboratively with other team members (I have some serious problems trying to pair with extremely extroverted people. I'm always tempted to just scream "shut up and let me think in peace!").  The sweet siren call of going headphones down and cranking out code has to be defied.  Besides, that's what side projects are for.

    Reduce Communication Latency

    Communication, and the overhead and "lossiness" of communication, is a massive cost in any nontrivial software project.  You have more latency and "lossiness" in your communication with more relays in information between people, lower fidelity mechanisms for communication, and temporal displacement of the communication.  Think about that last part.  What's easier for you to explain to a team member, code you wrote yesterday versus code that you wrote three months ago?

    It's definitely a factor that the business folks don't properly account for when they're weighing the cost savings from offshoring.  Sequential lifecycles with lots of specialization in the team are the absolute worst.  I've seen too many projects fumble handoffs between analysts, developers, and testers.  A strictly sequential cycle can be a killer because the different people on a project are coming onto a project at completely different times.  Every successive batch of people on the project have to learn about the project before they can begin.  In my experience, waterfall testers are often slow to pick up the pace of testing at first because they're not familiar with the new functionality yet.  Big teams of specialists that are working on multiple projects simultaneously have extra burdens from the sheer number of people who need to communicate and the context switching between different assignments. 

    I want my teams to cut down on communication latency by:

    • Having everybody work on the project at the same time
    • Analysts may be a little ahead, but have developers and testers start working on a feature at the exact same time with a common understanding.  Both to cut down on fights over different interpretations of the requirements, and to make sure the tester knows exactly how to test a feature the second it's finished and the developer knows the tester's expectations.
    • Involve fewer people in the project.  Fewer people means less latency because there are fewer communication "hops."  Shrink the team by eliminating specialization roles as much as possible.  Whatever you do, strive for an organization where most of your people are focused on one project at a time.  I've never seen a "multi-tasking" organization that didn't flat out suck.
    • Face to face communication is a vastly better way to convey understanding and create a common vision than all the paperwork in the world ever will.  To me, documentation is only valuable for it's durability.  Documentation is largely for the people who come next and people outside your team.  Don't depend on it for communication between your team.

    What about Tomorrow?

    As a consultant I hear plenty of very understandable concern for what happens after I leave the project.  Mostly it's a cry for effective documentation so somebody else can understand the system after we're gone.  I do want to leave a system and environment that is maintainable, but I'm not really a believer in much traditional documentation.  It might come down to differing paranoia's.  I'm always more worried about the overhead of creating documentation because I don't believe it's valuable for the creation of software.  I'm especially concerned about creating documentation that quickly becomes out of date and needs to be either thrown out or updated.  That's just waste.  I definitely don't want any incentive to carry out a bad design just because it's too much work to change the formal documentation.  Some of the folks at my client are more concerned about getting a system that they can't make heads or tails out of.  I think we'll be about to easily meet in the middle.  Without further ado, here's my recipe for what *I* want when I have to take over somebody else's code (and I've never, ever gotten):

    • Just really good code.  If I could have anything, and only one thing, it would be well written, well factored, clean, intention revealing code.  Everything else is just trying to sprinkle on some heavy spices to disguise the fact that your code smells like rotten meat.  I took over a system from some consultants that had fabulous documentation (it was definitely a cost reimbursable contract), but had terrible code.  We had to toss out the system, and it was hard to support anyway because of the architecture.  I'd also consider very high unit test coverage to be very valuable.  I find systems with a great deal of unit test coverage to be much easier to deal with, both because of the unit tests themselves and also because the code tends to have better than average separation of concerns.
    • A project Wiki that can act as a great starting point to everything else, and it's relatively easy to keep up to date compared to other medium.  Now what's on that Wiki?  I'll stick up a 2-3 page paper describing the key element of the system and a handful of UML diagrams just to act as a roadmap to the system.  I want another page that details the configuration management practices for the project.  Where is the code repository, how do I build the system, and how is it deployed?
    • Comprehensive build automation.  I want a brand new team member to be able to follow a couple steps in a Wiki page to set up his system, checkout the code, and use the build script to be up and running in under an hour.  Give me a good story for build automation to setup the development environment, and that goes a long, long way towards being able to work with someone else's code.  I don't want to have to scan a word document looking for the legacy COM component that has to be registered on some out of the way place.  I want the build script to do it for me and get going. 
    • Use acceptance tests, and especially executable specifications, as the real detailed documentation.  Don't create a document that a tester can then use to create a test plan.  Go straight to an acceptance test, keep it human readable, and then see if you can automate that test and stick it in an automated test suite that's run at least every night.  Make your acceptance tests a requirement that "bites back" when the system doesn't meet the requirement.  <PROMOTION>Come to DevTeach and one of my talks is on this very subject.</PROMOTION>
    • Try really hard to use common tools and common patterns.  Frankly, try to make Addison Wessely and Manning do as much of your documentation work as possible.  A major advantage of using off the shelf tools, and I'm counting OSS tools here too, is that documentation and knowledge exists for these tools already.  Writing your own O/R Mapper is going to be harder to maintain.  My current project is going to be using the Passive View variant of MVP.  Granted, I don't think it's that common in .Net circles outside the blogosphere yet, but I can point the Wiki right to www.martinfowler.com and give quite a bit of background on our design choices and philosophy.  I am thinking very seriously about building and using an alternative to Data Binding in WinForms, and if we do end up going down that path, I'll have to document that somewhat.  A lot of people blow off design patterns as just "something I do without that silly jargon," but that silly jargon can be an effective way of communicating quite a bit of information about a solution in a little packet of information.  <RANT>If you haven't already, go learn about using Design Patterns</RANT>

    Something important that I wanted to call out was the desire for moving documentation closer to the code and even trying to create mechanisms to ensure that the documentation is synchronized with the code.  The Don't Repeat Yourself principle should be applied to documentation as well.  I actually count things like a NAnt script, unit tests, and FIT tests as a very effective form of documentation - that can't get out of synch with the code as long as they're being executed regularly.

    Good Practices aren't just a Strategic Advantage

    Good practices like unit testing and build automation shouldn't just be looked at as a strategic enabler of the long term goals.  Good practices can be made a tactical advantage in getting your day to day work done.  More importantly, find a way to apply good practices in a way that makes you more productive.

  • Nice paper on Model View Presenter

    Here's a nice paper I found off of reddit this morning explaining the adjustments made to go from MVC to MVP and some historical background.

    http://www.object-arts.com/papers/TwistingTheTriad.PDF

  • Mildly embarassing tidbit from my resume

    I was cleaning out my hard drive tonight and found an old copy of my resume.  Way at the bottom of the "publications" section was this nugget that I'd almost forgotten about (read the last word):

    Published article in the 5/31/00 edition of ASPToday.com, “Extending the DOM Using Javascript Objects with RDS.”

    Yes, in 1000 words or less, Jeremy will show you a powerful technique for ripping a hole in your database security and demonstrate a quick and easy way to write completely unmaintainable code.

    And yes, I do know the code was hopelessly unmaintainable because my successor told me so after I left when they finally wrote a real system to replace my Shadow IT work.
     

    Once upon a time I taught myself JavaScript and DHTML by reverse engineering the old Visual Interdev _ScriptLibrary/SOM stuff to build my own grid controls that used MS's Remote Data Service library.  For those of you too young, or too smart, RDS basically let you connect straight to your database over HTTP directly from a web page -- still the fastest way I've ever used to spill data into a dynamic web page.  All you had to do was embed the database connection string directly into your web page and you were ready to start firing SQL commands straight from JavaScript to the DB.  Good times.

More Posts Next page »

This Blog

Syndication

News

All opinions expressed here constitute my (Jeremy D. Miller's) personal opinion, and do not necessarily represent the opinion of any other organization or person, including (but not limited to) my fellow employees, my employer, its clients or their agents.

About Me

"Best Of" Compendium