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

November 2007 - Posts

  • Resources from my DevTeach talks

    To everybody that attended one of my talks at DevTeach this week.  All of the materials are now online for download at the DevTeach website.  If there's something else you find missing or just want to find, please drop a comment and I'll post more links.  I'll write a longer writeup after I get home over the weekend, but in the meantime I'd like to thank everybody that attended my talks this week.  I got a tremendous reception from the audience and I loved the stream of questions and conversations during the talks.  Some speakers want just to tell you things, but I do a lot better speaking in informal talks where the audience is participating and DevTeach has been great for that.

     

    Other Reading

    • I used a lot of examples from StoryTeller for both WinForms samples and build automation samples.  You can download and mock this code to your heart's content at http://storyteller.tigris.org.

    Agile Design

     

    Maintainable Ecosystem

     

    Put that Wizard Down!  (Patterns for Maintainable WinForms)

    It's not entirely a done deal yet, but it looks increasingly likely that I will be writing a book next year on design patterns for smart/desktop/composite applications along the lines of Martin's duplex book idea.  The following is basically the proto-book.  Look for more content by the end of the year.

     

  • What do you want in C# vNext?

    I'm somewhat of the opinion that static typed languages are closing in on being an evolutionary dead end, but let's just say that C# is still important for the foreseeable future.  That being said, what do you want for C# vNext?  If we have to be constrained by static typing, I vote for making C# more like Objective C (not that I've ever coded in Obj C, just that it seems to have the things I want.).  My little list in order (not that I expect much of it to happen) is this:

    1. Mixin's. I found myself really wanting this for a framework I have in my current project.  Extension methods are okay, but I'd rather make it all the way to Mixin's.  Obj C can do it as a static typed language so it's definitely possible.  Heck, you can kind of do it in JavaScript.
    2. Symbols.  Reflection based solutions could be so much easier with Symbols.  I'd love to have compiler safe equivalents to Ruby Symbols.
    3. Make hashes a language feature.  I keep bumping into frameworks that really want to pass around hashtables.  If you absolutely have to do that, I wanna do var hash = :key => "red", :key2 => "green" in one line of code.  Somebody recently commented that object initializers might be a decent compromise.
    4. Automatic delegation ala Ruby or Objective C.
    5. Metaprogramming!  Method Missing magic!  I'm not holding my breathe on this one because it sounds like a bridge too far for me.  Give me metaprogramming and mixins and I think we can do AOP like things with less effort.
    6. Everything is virtual by default to make mocking easier

    Anyway, what's your wish list?

  • See you all at DevTeach Vancouver

    DevTeach is a week away, but I'm going mostly offline for the upcoming Thanksgiving week.  Just in case you've wondered, there are still some places in the continental US where the internet doesn't yet reach -- like my grandparent's farm in Missouri.

     

    Later. 


     

  • Welcome Ian Cooper to CodeBetter

    And let's have a big round of applause for Ian Cooper, our newest CodeBetter blogger.  Several of us CodeBetter bloggers met Ian at a conference this past spring and instantly recognized a kindred spirit.  I'm thrilled to announce that Ian is going to be joining the CodeBetter crew.  Look soon for content from Ian on Linq, MVC, and the ALT.NET scene in the UK.

    Check out Ian on web development with MVC today at:


     

  • Little observations

    • Stale code is dangerous.  My poor colleague tried to merge code from a class that's basically a directives file today.  He had kept his code out for a month.  When I was much younger my father would gently mock me about my propensity to foul out of basketball games.  Guess who played the "I told you so Father" role today?  (I did help him through the merge).  One more time with feeling, stale code is evil.  Check in often.  Work in small steps so you can check in often.  If you can't check in often, update your copy from the master frequently.  You can keep the nasty merges away without retreating to pessimistic locking.  Walking out of the office at night with modified code on your workstation needs to feel like going to work in the morning without a shower.
    • Side note:  I worked with a quirky developer at my last job that used to say "Uh oh, it looks like another learning opportunity" anytime he or we suffered an episode like my colleague today with the merge.
    • Note to self:  get better with SVN Merge
    • Keep the build server clean baby!  The build server today caught a problem with a VS project reference that wasn't apparent on a developer workstation.
    • Frequent checkins plus the SVN Revert command == ugly code be gone
    • Cubicles == Collaboration Proof Force Field.  Is there any worse way possible to arrange a development team?
    • A team building a feature is far better than a group of individuals doing tasks.  It's the same amount of work, but somehow the team/feature combo working with a shared purpose produces more real value than a bunch of disconnected individuals working tasks in a project management worksheet.
    • Something smells if you sit in a meeting for an hour and are only impacted by 5 minutes of that hour.
  • A Train of Thought: November 13th, 2007 Edition

    I'm cheating here, because I'm writing this from my kitchen table.  My current client is one of the big investment banks.  While I'm not too enthusiastic about their culture, I can seriously get into having all the banking holidays off.  I went to part of the Westchester/Fairfield County Code Camp this weekend and came away with some topics for blogging.  It's the same old discussions that just don't go away, but I guess they don't go away because we just don't have the answers.

     

    Windows Workflow Foundation

    One of my colleagues, Jason Sliss, gave a talk about the Workflow Foundation.  I've been putting off a long look at WF for quite some time, so I was interested to see what Jason had to say.  I built a fairly complex workflow engine and system several years ago, and workflow has been a low level interest of mine ever since.  I think WF looks interesting, but I'm not sure that I'd be that tempted to use it.  Other people were complaining that WF didn't have pre-canned solutions for many problems, but I actually like the fact that it doesn't try to solve every problem for you.  I think that making WF more or less a library to consume within your application rather than some sort of big whitebox framework will make it far easier to consume and much more flexible.

    More on WF scattered below.

     

    People Design Software

    One of the first thoughts I had while watching the demo of WF is that a developer could make one unholy mess of unmaintainable crap.  Unless you're on top of things and applying the Single Responsibility Principle and worrying about testability, I think the WF would tempt you into throwing everything and the kitchen sink into the workflow classes.  There's nothing in the WF that I saw that leads to good separation of concerns.  In fact, I think the designer-centric nature of WF development will encourage bad design.

    What's my point?  It's simply this:  people design software, not tools.  A good developer will use WF in a way that's sustainable and maintainable (especially since business workflow's *always* change).  A bad developer will unthinkingly use the designer to drop code willy nilly and create spaghetti.

    Actually, let me put it this way.  Tools can create passable designs in the right circumstances.  People can make great designs.  People can recognize when the tools aren't generating the appropriate designs for the circumstances and alter their approach.  Free will and all you know.

     

    Too much generalization

    What's the deal with so many frameworks trying to pass around Dictionary<string, object> hashes as the argument or state?  Put me down as hating this.  I've seen this approach cause absolutely nothing but trouble and confusion.  It's a weak contract sematically.  When you're trying to understand code it's "mystery meat."  Anything could be in there.  Writing explicit code even though that may take longer upfront versus passing around mystery meat to reuse a generic solution?  I'd rather write explicit one-off code instead of passing around mystery meat arguments just to conform to a generic framework.  Even if the initial write takes longer, I think the mystery meat would make you pay later. 

    Shouldn't generics have ended much of the Dictionary<string, object> abuse?  And if we're gonna keep getting this stuff forced on us, can we get a language construct for defining hashtables inline like Ruby has?  And symbols too (compiler checked symbols might be cool if it's feasible).  I know many people are worried about C# getting too big, but I think we could fit this little request into C# 4.0.  Who's with me?

     

    Xaml is Ugly

    Explain to the slow kids why or how Xaml is more readable and easier than expressing things in code?  I'm not talking about using Xaml for user interface layout here, that I buy.

     

    Language Oriented Programming vs Visual Tooling

    Both at the Code Camp and on a podcast I listened to on WF I heard several people make the statement that WF is a better way to write workflows because the visual designer makes it easier to write and understand.  That statement was thrown out with zero justification, and that's too bad because the superiority of visualization is a whopping assumption to make unchallenged.  I think we need to give Language Oriented Programming a chance here as a cheaper solution that might just end up being easier to deal with.  I'll have to come back later with some links, but I've seen some examples of using DSL's in Ruby for defining workflow that I think are quicker to develop and easier to read (and hence to understand and maintain) than the visual representation in WF.

    I was thinking of the "acts_as_state_machine" plugin to Rails. This kind of stuff is why I'm intrigued by IronRuby.

    From Micah Martin of ObjectMentor fame:  http://statemachine.rubyforge.org/

     

    I prefer User Stories over Use Cases

    I started a new little project for my client last week.  I just had a couple massive Use Case documents dumped on me from an analyst on the other side of the Atlantic ocean.  I was curious to see how it played out because my knowledge of Use Cases is strictly academic.  The Use Case I received was textbook with actors and RUP verbiage and plenty of scenario descriptions in the Word doc.  After about a half hour of looking at the Use Case I'm more than ready to say that I strongly prefer using User Stories for requirements.  You can try the Mike Cohn link at the end of this section for an expert's opinion on the difference, but first here's my reasoning on the advantages of User Stories versus Use Cases

    • User Stories are generally finer grained, and I think that's useful both from an ease of estimation standpoint and the prioritization standpoint.  I broke my use case document into about 20 different user stories for my own edification, then emailed that list back to the analyst.  When I look into the Use Case I see detailed specs for a lot of different development tasks in the new screen and workflow.  Some of these tasks are vital, and others are simply nice to do.  As I'm going to remind the client today, I'm rolling off at the end of the year and I simply can't get to every single wrinkle in the Use Case.  The lower priority stuff isn't going to make it into the first release.  If we were using fine grained stories we'd simply play the high priority stuff and let the lower priority stuff stay in the backlog.  User Stories are practically built for iterative development.  The Use Case throws everything into a big bucket, and my analyst spent time detailing out features that won't get built.
    • User Stories let you get started sooner and that's important.  With a tight schedule, I'm going to be regretting the couple days that I couldn't spend on my new project because the analyst was perfecting the Use Case document.  The simple act of dividing things up into smaller chunks gets actionable requirements into the grubby little hands of the developers and testers earlier.  Putting off detail on stories that aren't yet in play is also more efficient to me.  Why do detailed analysis on a requirement that might never get built?
    • The conversation thing.  A User Story is largely a project management device and a means to creating a common language for the team and customer about features in the system.  In one sense the User Story is simply a placeholder for the conversations and interactions between the business, analysts, and developers that make up the detailed requirements process.  One of my favorite sayings is "the design hat never comes off," but it's just as important to keep the requirements analysis hat on as well.  We always understand the requirements better as we proceed through the system.  A Use Case just gives you too much incentive to sign off and stop thinking.

    Mike Cohn prefers User Stories too.

     

    Patterns are more important than Tooling

    I'm going through one of my periodic "maybe I should go give CAB another detailed look" phases.  My attitude hasn't changed yet.  If you know the underlying design patterns behind the CAB, you'll probably be able to build something simpler that's more appropriate for your system without the CAB.  If you know the patterns behind the CAB, you'll be more successful with the CAB.  The same thing applies to the WF.  If you simply understand the idea of a state machine, I really don't think the WF holds much value for simpler workflows.  Both of these tools try to solve problems in a generic way.  That's great from the reusibility standpoint, but it's a sacrifice.  My TradeCapture application is extended by a very specific mechanism that's expressed in domain specific terms, not by "SmartParts" and "WorkItems."

    I've built 5-6 WinForms applications of significant complexity now.  Every single one of them had:

    • A main form called "ApplicationShell" than contained all of the other child forms and controls
    • An ApplicationController class that governed the activation of child Presenters and views
    • Some sort of IPresenter/Presenter layer supertype that all views had to implement
    • An IView interface
    • ICommand interface for the Command pattern
    • What I call a "ScreenCollection" to track the open screens

    Aha! you say.  CAB has most of that stuff and you're just giving into your NIH tendencies!  I'd still say no, because every single application was different.  The patterns happened in every project, but the details differed considerably.  Even the ICommand interface has varied with additional security, validation, or menu specific stuff between apps.  I personally like having all of these classes be customized for the application.  It makes them easier to use than a generic solution.

    Here's a side argument I've seen crop up a couple times in the past week.  Is it better to learn design patterns and principles first, or learn the same patterns and principles as a consequence of using a tool or framework that incorporates these patterns?  After looking harder at the CAB, I'd say that it's not a bad thing at all to study for the design patterns it incorporates, but I'm still dubious that working with CAB is the best way to learn the MVP pattern.  I'm defintely in the camp that says it's more important and effective to learn the patterns independently of a tool.  After all, how else can you really judge whether or not the tool is really what you need?

    Invest in People before investing in Tools

    I see sooooooo much effort and money going into producing or purchasing tooling that will "enable" bad or undertrained developers to write software with adequate results.  Software factories to tell them what to do next.  Methodologies try to straitjacket developers into being spec programmers.  Tools that frankly have no power because the makers are favoring safety to keep developers from hurting themselves.  All powerful frameworks that try to do ease development by leaving developers very little choice or freedom.  Yes, the average developer might be underskilled and undertrained, and we generally need to do something about that to make them more effective.  My constant contention is that we'd be better off to raise the average developer skill level across the board.  In economic terms I think it's cheaper to invest more in developing developers than it is in fancy tooling. 

    What is so wrong with our value system that we favor using tooling to make people interchangeable instead of investing in people to make them, and us, more effective?

  • Don't think you know more than you do

    On the train this morning I was working on my DevTeach talk about doing design on an Agile project.  I'm trying to explain the concepts of the Last Responsible Moment and delaying technical commitment in terms of Lean Programming.  Part of the theme of my talk is simply to not do anything that you don't know that you need to do.  "If we do task A now, feature B will be easier later" is an example of speculation, not knowledge.  It might turn out to be a good decision, but do you really know for sure that you'll actually implement feature B?  If feature B doesn't actually get built, you might have wasted effort building extra complexity in the form of hooks for a feature that never gets built.

    You need to be very cognizant of the difference between "I think designing it this fancier way will help in release 2..." and "we could reduce some duplication if we abstracted the XYZ like this."  The first statement is an idea that you keep in the back of your mind.  The second statement is something to act on.

    Don't ever let yourself believe that you know what the business wants or needs more than they do.  My poor colleague just got hit by an example of this.  He'd built some nontrivial functionality to interpret trade prices in a new screen to match a specification from our client's tech lead.  You can probably guess what happened as soon as an actual business person saw the screen for the first time today.  Needless to say, my colleague just started rewriting the implementation of the trade price interpretation (20 unit tests worth of code).  It's good to know the business domain, but don't fool yourself into believing that you're the domain expert instead of the business.

    I built a couple complex features this summer that have never, ever been used in production.  Same story, same team lead.  When I finally started talking to the end users (and knowing enough about the domain to actually understand what they were talking about) I found out quickly that these features were more or less useless to them.  The business problem we were trying to address still exists, but the real solution was to make part of the screen behave more intelligently to speed up the entry of Trades.  We blew it by assuming that we knew what the business needed.

    If it isn't entirely obvious, I'm not in an Agile shop at all at the moment.  We're doing the engineering practices, but the project management isn't there.  I think one of the biggest advantages of Agile is turning the software development process into more of a "Pull" mechanism instead of the traditional "Push" model of linear waterfall.  I don't try to guess out what the business might want or find useful.  I'll make suggestions, but the final decision still has to be from the business.  If the business is setting the priorities then you'll be building features according to an established business need.  You can cut waste by only designing the software for the features the business has already requested (how you keep the doors open for later features is a much, much bigger discussion some other time).

    Grrr.

  • Funny quotes about old programming languages

    If you are a COBOL guy, doen't get too upset because it all comes around.  If you really want to see a language put down, read what the Ruby community or functional programming gurus say about Java (and C# by inference). 

    http://www.sysprog.net/quotcob.html

    For the record, I have coded in Fortran 77 (badly) and worked in a shop mostly dominated by COBOL.  I don't have anything against COBOL per se, but I think the early versions discouraged the usage of subroutines due to inefficiency set back programming a bit.  I jokingly called someone a "COBOL programmer" just yesterday for a big, big chunk of Java code unpolluted by fluff like other classes and extraneous methods (behind his back, but don't feel sorry for him, he makes much more than you or I.  Non-coding architect having fun learning to code again).  One use case, one method, start to finish with no wussy subroutines baby! 

    Many people say that Ruby is like a developer magnifier that allows good developers to be faster and bad developers to fail faster.  That might be so, but to me, Fortran 77 was more like an equalizer.  Everybody is humbled before the "unknown error at line 0" compiler message.

    My favorites:

      •  A computer without COBOL and FORTRAN is like a piece of chocolate cake without ketchup or mustard. (John Krueger)
      • The tree large enough that a stake capable of killing COBOL could be fashioned from its trunk has not yet grown anywhere upon the face of this verdant planet. (Dan Martinez)
      • Cobol has almost no fervent enthusiasts. As a programming tool, it has roughly the sex appeal of a wrench. (Charles Petzold)

    Same site, other pages

      • Lisp has all the visual appeal of oatmeal with fingernail clippings mixed in. (((Larry Wall)))

      • If Java had true garbage collection, most programs would delete themselves upon execution. (Robert Sewell)

      • Using Java for serious jobs is like trying to take the skin off a rice pudding wearing boxing gloves. (Tel Hudson)

      • Perl: The only language that looks the same before and after RSA encryption. (Keith Bostic)

     

  • I don't know why, but this just makes me optimistic about humanity

    From Ajaxian.  Two competing JavaScript libraries have learned to peacefully share the "$" function.  That'd be a great Sesame Street skit if anybody but geeky developers understood the reference.

  • ALT.NET in Italy

    Check it out:  http://codeclimber.net.nz/archive/2007/10/31/An-ALT.NET-group-is-born-in-Italy.aspx

    Nothing stopping from doing your own, or setting up a SIG under your .Net user group.

More Posts

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

StructureMap (Dependency Injection for .Net)

StoryTeller (Supercharged Fit)

Build your own Cab

TestDriven

MVP