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

September 2008 - Posts

  • Separate Assemblies != Loose Coupling

    Sorry guys, but it's time to rant.  I see so many people needlessly complicating their architecture and deployment by insisting on using separate assemblies for every layer of the app or even doing the trick where interfaces are in one assembly and the concrete classes are in another assembly.  Stop it!  It's a waste of time.  Logical de-coupling from UI to business logic to infrastructure to the database is very important, but using separate assemblies doesn't do anything to guarantee that decoupling.  You can separate your assemblies all you want, but making the UI depend on the implementation details of the business code in the other assembly is still harmful tight coupling.  Likewise, you can lump data access, the domain model, and even UI concerns in the same assembly and still maintain separation of concerns in every way that really matters to the success of your project.  Our Domain Model and our persistence infrastructure is all in one assembly named "DovetailCRM.Core," but yet there is zero coupling from the Domain Model to the NHibernate mechanism.  We could slide another persistence mechanism (assuming that there actually was another POCO-compliant persistence mechanism with rich functionality in existence for .Net) without changing anything in our Domain Model.

    Here's what's important about coupling between two things (class/module/infrastructure/subsystem/whatever) named X and Y:

    • Can I understand X in isolation, or do I also have to understand Y at the same time?
    • Can I change X independently of Y?  Or to put it differently, will changing X likely break Y or vice versa, 'cause that would be bad?
    • Can I test X in isolation without Y hanging around and getting in the way?  Or can I verify that X works independently of Y?
    • Can I use X with a Z instead of a Y?
    • If I want to reuse X in another context, even if it's in the same application, can I do that without having to drag Y along with me?  And all of the things that Y needs for that matter?

    I'm very firmly in the camp that says you should only split assemblies by deployment targets, and even then, I don't think you need to be strict about assembly separation.  More assemblies == slower compile times (Don't believe me?  Try it out in VS.Net.  I took 56 projects one time and consolidated them down to 10-12 and cut the compile time from 4 minutes to 20 seconds with the same LOC), circular reference problems, and more complicated usage and deployment.  Nothing is more irritating to me than using 3rd party toolkits that force you to reference a dozen different assemblies just to do one simple thing.  Ok, truth be told, nothing irritates me more than using 3rd party control kits in general -- all the worst API's ever created come from .Net control toolkits.

    If you don't think your team won't adequately follow the basic separation of concerns rules you've determined in your architecture, you'll be better off doing something like using CQL constraints with NDepend in your automated build script to find coupling violations.  Even with the separate assembly strategy you would still need to use static code analysis to find every coupling violation.

     

    One more rant, and I may be leaving the reservation on this one.  Obviously, the following rule applies equally to me, but don't ever assume for a second that just because someone is an MVP/INETA Speaker/MS Regional Director/"Professional .Net Gloryhound" that they know WTF they're talking about.  Remember that all of those awards are mostly based on visibility and successful self-promotion rather than on strict technical merit.

     

    Ok, I'm done now.  Thank you for listening, I feel better now.

  • Agile is more disciplined than Waterfal, so sayeth Jason Yip (and me)

    Jason Yip has been one of my favorite bloggers for a long time.  This morning I caught a post from Jason Yip called More thinking about "Agile" vs "Waterfall."  He echoed something that I've thought ever since I moved over from a Waterfall shop to Agile shops about five years ago. 

    Be careful about saying that Waterfall is more disciplined. The waterfall model is simple and structured but the "discipline" is in following prescribed steps as opposed to "discipline" in thinking. The second kind of discipline is by far the more important.

    Agile development, assuming that you're doing it competently, is far more disciplined in the small, day to day activities than we were in my old waterfall shop and all the waterfall shops that I've consulted in.  In the waterfall, we had a lot of one time quality gate processes and intermediate documents to deliver, but very little useful guidance on how to perform the actual development work (requirements, development, testing).  An Agile process, and I'm thinking about XP in specific here rather than the typical watered down Scrum, has a lot of impact on how you write code (Test Driven Development, simple design, YAGNI, pair programming, Continuous Integration), requirements (user stories, iteration planning, acceptance tests), and testing.  I don't go to meetings very often, and I rarely produce documentation beyond Wiki pages, but my daily work is far more disciplined than it was in my previous life in a formal Waterfall project.

    Waterfall discipline is the external discipline of intermediate deliverables and process ceremony.  Agile discipline has to be internalized by the members of the team and realized through their behavior and daily activities.  For better or worse, Agile has far more impact on the way you work than traditionalist waterfall processes.

    The best of Agile is when you throw away process ceremony that adds little or no value, and concentrate really hard on the things that do add quality and productivity to your project.  Of course there's no cookie cutter process plan to follow because "what adds value" is a bit different from project team to project team, but if it was easy we wouldn't make the big bucks.

  • Using StructureMap 2.5 to inject your Entity objects into Services

    Forget the neverending argument on the ALT.NET list about whether or not it’s acceptable to inject services into an Entity object (for the record, I say “no way”).  What if you want to go the other way around?  What if you want to request a service or a view or a command of some kind and have an Entity injected into the service/view/command?  You’ve now got (at least) 2 ways to do that in StructureMap.

     

    If you already have the Entity

    If you’ve already got the Entity you want, you “pass” the Entity object into ObjectFactory (or an IContainer).  Let’s say you have a view named TradeView like this:

     

        public class TradeView : IView

        {

            private readonly Trade _trade;

     

            public TradeView(Trade trade)

            {

                _trade = trade;

            }

     

            public Trade Trade

            {

                get { return _trade; }

            }

        }

    If you already have the Trade object in memory, you can grab the IView that displays the Trade by using the Container.With().GetInstance<T>() methods:

            [Test]

            public void Example()

            {

                IContainer container = new Container();

                Trade theTrade = new Trade();

     

                var view = container.With<Trade>(theTrade).GetInstance<TradeView>();

     

                view.Trade.ShouldBeTheSameAs(theTrade);

            }

    The “explicit arguments” to GetInstance<T>() will be propogated all the way through the object graph.  Let’s say we have a class named Command that takes in an IView, a Trade, and a Node object in its constructor.  The actual object passed to the Command constructor might be a TradeNode class that, surprise, needs a Trade object as well.  An elided version of these classes is shown below:

        public class Command

        {

            public Command(Trade trade, Node node, IView view)

            {

            }

        }

     

        public class TradeNode : Node

        {

            public TradeNode(Trade trade)

            {

            }

        }

    When we request an instance of the Command class using a known Trade object, all of the classes (Command itself, TradeView, and TradeNode) that need a Trade object in their constructor would get the Trade object we specified in …With<Trade>(theTrade)… below:

            [Test]

            public void Explicit_services_are_used_throughout_the_object_graph()

            {

                var theTrade = new Trade();

     

                IContainer container = new Container(r =>

                {

                    r.ForRequestedType<IView>().TheDefaultIsConcreteType<TradeView>();

                    r.ForRequestedType<Node>().TheDefaultIsConcreteType<TradeNode>();

                });

     

                Command command = container.With<Trade>(theTrade).GetInstance<Command>();

     

                command.Trade.ShouldBeTheSameAs(theTrade);

                command.Node.IsType<TradeNode>().Trade.ShouldBeTheSameAs(theTrade);

                command.View.IsType<TradeView>().Trade.ShouldBeTheSameAs(theTrade);

            }

     

    If you had more than one IView that displayed a Trade object, you could also do this:

     

            [Test]

            public void pass_explicit_service_into_all_instances()

            {

                // The Container is constructed with 2 instances

                // of TradeView

                var container = new Container(r =>

                {

                    r.ForRequestedType<TradeView>()

                        .TheDefaultIsConcreteType<TradeView>()

                        .AddConcreteType<SecuredTradeView>();

                });

     

                Trade theTrade = new Trade();

     

                var views = container.With<Trade>(theTrade).GetAllInstances<TradeView>();

     

                views[0].Trade.ShouldBeTheSameAs(theTrade);

                views[1].Trade.ShouldBeTheSameAs(theTrade);

            }

     

    and have the known Trade object passed into every instance of TradeView.

     

    I’ll post the other way to do this tonight….

  • Jeremy's Penultimate Law of Continuous Integration

    Just to add to Laribee's Final Rule of Continuous Integration about never going home with a broken build:

    Do not leave your giant check in until just before quitting time.  The CI build will NEVER function correctly 5 minutes before quitting time.  The CI build will fail spectacularly if it catches the slightest whiff of "I'm in a hurry to leave."

  • Jeremy's Other Laws of Continuous Integration

    Since the first one inevitably irritated people, let's go for rule #2 & #3:

    2.) Check in as often as you come to a stopping point.  The more frequently you check in, the less troubling your merge conflicts will be.  For the most part, I think you can make merge conflicts almost entirely go away after the first couple weeks of the project.  We had a mild conflict today (that spawned my tongue in cheek remark about checking in first) that was caused by one pair renaming a testing utility method to make it more consistent with our other testing methods, while my pair was still using the existing method name.  Both pairs knew it was coming so it was no harm, no foul

    3.) Communicate with your team members anytime you think you might be doing something that would cause a merge conflict.  Yet one more reason why a colocated team beats a distributed team

    4.) Find ways to divide your work into smaller chunks.  If you can't check in new code for days at a time because you aren't at a clean point, you may have some serious problems with your design.

    5.) If you can't check in your code for a long time ( > 1/2 a day let's say), be sure to update your version of the source code with the updates from the rest of the team to make your eventual checkin easier

    6.) Rotate your build notification sounds.

    7.) And in the "do as I say not as I do" category, you might learn how to use a merging tool (then come teach me).

     

    And yes, you can solve the merge conflict problem by going to a pessimistic locking strategy, but I think that causes much more friction than the occasional merge conflict.

     

     

    ...and some other boring things like making sure the build actually succeeds, fixing broken builds immediately, and making sure that the build sets up the development environment and other details you can find in the Check In Dance.

  • Jeremy's First Law of Continuous Integration

    If you check in very often and/or first, you can make merge conflicts be someone else's problem

  • Question of the Day

    The difficulty and pain of TDD adoption is a hot topic over the last couple days.  I'm working on an article on testability and design this morning.  In writing the summary I caught myself saying that there are some exceptional cases where I do unnatural things to promote testability, but that most of testability design is really a stronger focus on the classical OO design qualities of cohesion, coupling, and separation of concerns.  Here's the question of the day though, most of those "exceptional cases" and "unnatural things" are directly related to working around C#'s static type system (marking things as virtual, exposing members as public or doing the InternalsVisibleTo trick, etc.).  Here's the question of the day:

    Will you adopt a dynamic language like IronRuby or try out "side effect free" programming with functional languages like F# just because of the lower friction in TDD from these languages?  There's an obvious cost and risk in switching over, not to mention less tooling, but at what point do we say that there's more potential for higher productivity in these other languages for TDD practitioners and make the jump.  My team considered Ruby on Rails early on, but chose to use C# 3.0 mostly out of familiarity and a feeling by Chad & I that it was a low risk choice. 

    How much of the TDD adoption obstacle is that our mainstream programming language isn't entirely TDD-friendly?

     

    Of course, everytime I curse Anders for making methods nonvirtual by default I remember that he saved us from checked exceptions and remembered to put first class delegate into the language from day one and all is forgiven.

  • Let's go back to the basics of Cohesion and Coupling

    Recently, I've seen a nice trend out on the blogosphere on going back and revisiting the basics of programming like this post from Scott Hanselman and this podcast from the Herding Code gang.  My contribution to this trend just went out in the October issue of MSDN Magazine.  For the latest issue of the Patterns in Practice column I decided to focus on the very basics of software design:  Cohesion and Coupling. I made an effort to explain the two concepts of coupling in terms of the first causes of desiging code that is readable, simpler to change, and easier to write.  Assuming that I made my case on why cohesion and coupling qualities are important to your daily coding effort, I moved onto some design concepts that can help point the way toward better coupling and cohesion qualities in your code:

    • The Tell, Don't Ask Principal from the Pragmatic Programmers
    • The Law of Demeter.  I can't say that I coordinated with him, but fellow Austinite Jimmy Bogard conveniently wrote the perfect companion piece for this section entitled:  Entities and the Law of Demeter
    • "Once and Only Once" from Extreme Programming.  One of the best things you can do to improve your design is to simply recognize and remove duplication whereever it pops up.
    • Information Expert from Craig Larman's GRASP patterns. The GRASP patterns are a great read for OO newbies.

    And just for fun, I talked about some "Code Smells" that can help us spot potential coupling and cohesion problems that have crept into our code:

    • Inappropriate Intimacy

     

     

    Coming up next

    Roy Osherove made a good post yesterday called Goodbye mocks, Farewell stubs about why so many teams and developers struggle with adopting TDD and their inability to grasp the “Testability message.”  He's largely talking about the learning curve hurdles with some of our existing testing tools, but I still think the bigger obstacle to TDD adoption (assuming that people are open minded and willing to begin with) is a general lack of skill with designing Object Oriented systems.  TDD adoption punishes coders that don’t understand the basics of coupling, cohesion, and separation of concerns.  Coincidentally, I'm busy writing my next article for Patterns in Practices on "Testability and Design" to explore the design considerations and patterns for the efficient usage of automated testing (I was going to steer way clear of interaction testing and all the TypeMock/DI/Mock v. Stub. v. Let's just hopelessly muddle the situation by calling lots of very different things a 'Fake' controversies, but decided that it just couldn't be complete without some mention of substituting fake implementations for infrastructure concerns).

     

    The Hereafter...

    I've been renewed to continue the Patterns in Practice column throughout next year, so I need to generate some more article ideas.  Anything below sound good to you?  Got any requests?

    • Essence, Ceremony, Conventions, and Opinionated Software -- I want to explore ways to increase the Essence v. Ceremony quality of our code with better API's, some FP-like coding, and the way that we're starting to exploit convention over configuration techniques in our designs.  I also want to talk about the impact of programming language advances on our designs
    • I'd love to do an article on messaging patterns and Distributed Domain Driven Design ala Greg Young, but this is mostly for my own learning benefit
    • Designing better API's.  I want to use my experiences with StructureMap to talk about how to create more predictable and usable API's.  This has been on my mind quite a bit lately because of some flat out mistakes I made on the previous version of StructureMap that I'm trying to correct
    • I've also proposed Persistence/Infrastructure Ignorance as a possible topic to MSDN.  Obviously, I have to be very careful with this one, but I think it would be valuable to explain the issues and the patterns used to accomplish Infrastructure Ignorance.  I think I would work in the Hexagonal Architecture 
    • The Top N (where N == however long the article needs to be) things that makes a codebase hard to work with.  That's not exactly a design-specific article, but I've had the outline for it for 18 mos
    • Moving beyond the Layering Metaphor for Software Design -- I don't think about my architecture in layers anymore, do you?
    • Data Access patterns.  Repository, Database Mapper, Active Record, etc.  I'm not enthusiastic about this, but sooner or later I'll do it

    I've thought about an article on Inversion of Control as a pattern, but I'm working it into my current article.  I'll also take requests and suggestions.
  • Nice quote from Arnon Rotem-Gal-Oz

     ...I don't like the term "best practices" - it sends out a "you don't have to think anymore" message which is oh-so-incorrect

    Read the rest from Arnon here:  Architecture - It's always a tradeoff

  • Pablo's Days of TDD

    As Chad announced this week, the Los Techies guys are putting on a free developer event called "Pablo's Days of TDD*."  The goal is to do a series of workshops and labs at the novice and intermediate levels.  I'll be there leading some discussions and doing some little presentations on advanced topics like design issues and mocking best practices.  If you're anywhere near central Texas, give it a look and we'll see you there.  The sign up instructions are on Chad's blog at the link above.  Unlike a certain other un-conference, the registration is simply first come, first serve without any kind of elitist "invitation only" nonsense.

     

  • P&P Architectural Guidance Version 2

    The Patterns and Practices team is *finally* updating their architectural guidance.  You can see J. D. Meier's announcement of it here.  Interestingly enough, they're going to do it through CodePlex.  I love the new openness from Microsoft.  Ages ago, I remember getting a lot of good out of the original Enterprise Solutions Patterns (ESP) guide and other work on application architecture they published in the .Net 1.0 days.  The problem is though, that work is atrociously out of date.  Software development and our approaches to design have moved a lot since those days.

    I've been critical of P&P in the past for some of their work on framework construction and tooling.  I've always thought that they've done better with their guidance work than the actual code that they ship.  When I was between jobs this past spring I briefly talked to P&P about a remote position with them, and I told them that I thought they should go back to doing more guidance work like their old application architecture guidance publications.  Despite the fact that I've been in favor of them doing something like this for quite some time, I'm filled with a deep foreboding about this endeavor.  Here are some of the topics they've suggested for the guide:

    • Choosing Presentation Technologies
    • Choosing Data Access Technologies
    • Choosing Workflow Technologies
    • Inline SQL vs. sprocs
    • MVC vs. MVP
    • Domain model driven vs. structure driven
    Do you know what I see up there?  Lots of important topics, and the potential for some very nasty religious warfare.  The obvious problem is that that guide could easily suggest some practices that I (or you, no matter who "you" are) will find anathema, and you'll find yourself having to have yet more arguments with centralized architecture groups, other devs, or nervous clients about why you aren't following the proscribed architectural guidance.  I have it easy because our management and sales seems to trust our development team on technology matters, but if that wasn't the case I think I'd be forced to follow some not entirely optimal technology recommendations from a certain well known consultancy.

    To summarize, I'm glad that P&P is doing this, but I can't help but feel worried over it as well.  Anyway, here's hoping that it goes well and spawns some useful conversation.

     

  • The best (and next best) possible advice I could give you about using the MVC framework

    I ditched quite a bit of some complicated server side state management / screen workflow around the MVC framework today in favor of just a little bit of client side code with the jQuery.Form component.  The lesson learned today for me, and not for the first time, is to keep your MVC framework usage and the server side views as simple as possible. Take all that time you saved on fancy server side work and apply it to serious jQuery-fu.  I would have positioned our design so much better upfront if I'd just taken the freakin' jQuery in Action book home over the weekend early on our project instead of doing so many deep dives into the MVC code.

    Of course, since we're doing so much more jQuery coding on the client, it's making it more and more important to test the UI in multiple browsers.  I hit one of those cases today where something worked perfectly in Firefox (what I think all of us use day to day) but not in IE.  We already use QUnit quite a bit for unit testing client side Javascript, but it's only running in IE during the CI build.  We also have end to end tests with Watin, but again, that's IE only.  I think we'll make the minor move to write a QUnit/Firefox runner for CI, and I think I'm going to go take a much longer look at Selenium RC which supports multiple browsers for the end to end testing. 


  • I'm surrounded!

    Just out of coincidence, I'm wearing my Los Techies t-shirt today.  My coworker Josh Flanagan joined Los Techies today.  That makes me the lone CodeBetter guy in a sea of Los Techies guys in Austin.

    My team (minus Raif who doesn't blog and therefore isn't proven to exist) is at Los Techies now:

    Joshua Flanagan

    Chad Myers

    Go' check out Los Techies and see what the cream of the Austin / San Antonio .Net developer community is up to.

  • Using the StructureMap Container independently of ObjectFactory

    From the StructureMap list I saw a link to an .Net IoC tool roundup that included some mildly inaccurate comments about StructureMap (which I’ll blame on lack o’ documentation for SM 2.5, it’s on my plate, I swear!).  Specifically, the author states:

    With StructureMap, it was extremely hard to test it correctly, because it uses a static class for container/configuration and I had to reset it between tests.

    Ok, the ReInitialize() business is a mess and needs to be documented (but you shouldn’t really ever have to use it in normal usage).  However, you don’t *have* to use the static ObjectFactory and StructureMapConfiguration if you don’t want to.  They’re strictly a convenience method and wrappers about two classes called Container (the actual Container) and Registry (for configuration).  You can set up a Container independently of ObjectFactory by doing this:

     

                IContainer container = new Container(registry =>

                {

                    registry.ScanAssemblies().IncludeAssemblyContainingType<ColorWidget>();

     

                    // Add an instance with properties

                    registry.AddInstanceOf<IWidget>()

                        .UsingConcreteType<ColorWidget>()

                        .WithName("DarkGreen")

                        .WithProperty("color").EqualTo("DarkGreen");

     

                    // Add an instance by specifying the ConcreteKey

                    registry.AddInstanceOf<IWidget>()

                        .UsingConcreteType<ColorWidget>()

                        .WithName("Purple")

                        .WithProperty("color").EqualTo("Purple");

     

                    // Pull a property from the App config

                    registry.AddInstanceOf<IWidget>()

                        .UsingConcreteType<ColorWidget>()

                        .WithName("AppSetting")

                        .WithProperty("color").EqualToAppSetting("Color");

     

     

                    registry.AddInstanceOf<IWidget>().UsingConcreteType<AWidget>();

                });

    In the constructor function of Container up above takes in a single argument of Action<Registry>.  In that action you simply make any or all the configuration against that Registry object being passed in.  The IContainer interface has all the normal “GetInstance<T>()” type methods. 

            [Test]

            public void AddInstanceAndOverrideTheConcreteTypeForADependency()

            {

                IContainer container = new Container(

                    registry => registry.AddInstanceOf<Rule>().UsingConcreteType<WidgetRule>()

                        .WithName("AWidgetRule")

                        .Child<IWidget>().IsConcreteType<AWidget>());

     

                container.GetInstance<Rule>("AWidgetRule")

                    .IsType<WidgetRule>()

                    .Widget.IsType<AWidget>();

            }

    The author also criticizes StructureMap for not supporting the concept of hierarchical containers.  StructureMap does NOT do hierarchical containers the same way as the containers that were influenced by PicoContainer & Avalon containers from Java, but there is an analogue with the “Profile” feature.  I’ll get to that in the next post…

  • "Extension Method" in JavaScript

    I have to admit a secret.  I actually like JavaScript as a programming language -- especially now with jQuery and QUnit.  It's more out of nostalgia for my earlier programming days doing DHTML applications than the fact that JavaScript is now chic in some circles.  

    This morning I found myself wanting some sort of method to check whether an Array object contained a value.  I could have written the code inline, but it was cleaner to just add a new method to the Array class.  Using the prototype object, I'll just add a method called "contains(value)" to all instances of Array:

     Array.prototype.contains = function(value){

         for (var i = 0; i < this.length; i++){

             if (thisIdea == value) return true;

         }

     

         return false;

     }

    In the middle of my code it's used like (actions is an array of all the available context menu actions for a row in a table):

     function showMenuItem(actions, item){

         if (actions.contains(item.id)){

             $(item).show();

         }

         else{

             $(item).hide();

         }

     }

     

    I'm sure there's a better way to do what I did above, but dang that was easy.  Yeah, C# has extension methods, but JavaScript had open classes first with fewer restrictions than the C# version.

More Posts Next page »

Our Sponsors

Proudly Partnered With


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