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

Dave Laribee

"Whoso would be a man must be a nonconformist." - Ralph Waldo Emerson
  • Deep Fried DDD

    Over the weekend I got the chance to sit down with Keith Elder and Chris Woodruff of Deep Fried Bytes fame and discuss domain-driven design. It was a fun conversation and the first part (of two) is available for download.

    We focused on some of -- what I'd consider, anyway -- the important fundamentals of DDD: ubiquitous language, bounded contexts, and model driven development. I'm happy with that outcome; I feel too many times people new to domain model and DDD latch on to some of the less critical concepts (the repository pattern, say) when they should be asking: "what's this do for me and at a 10,000 foot view how should I structure my models?" Part 2 of the podcast will delve more into the nuts and bolts of the core pattern language: entities, value objects, repositories, etc.

    So if you're new to DDD* or working on domain models, check it out!

    Now back to your regularly-scheduled programming...

    * And if you're new to DDD you really should read Eric Evans' book!

  • Rik on Design Patterns

    Rik Bardrof, one of the senior developers at Xclaim, recently gave a presentation to the Syracuse .NET Developer's Group. I was in town, so I captured the talk.

    In it, he covers a few patterns/principles we use extensively in our products:

    Enjoy!

  • Doctors We Ain't

    Time for a little bit of a rant.

    In a recent post, Jeffery Palermo paraphrases an analogy made by David Platt on a recent episode of the .NET Rocks podcast:

    In software, we can't expect our clients to know what they need. Much like the depth of a patient may be "I need to get rid of this infection" or "Give me some pills. I'm in pain". Our clients know what is causing them pain, in the business sense, so the problem is from that experience perspective. Some clients might go so far as to ask for some "pills", that is, they might ask for a specific software system that is assumed to solve the problem.

    I have to disagree.

    There was a time where I would agree with this statement, but implementing practices such as a weekly demo, an acceptance testing environment, and user stories actually written by the user drives my issue with the notion that software developers and architects have all the answers.

    Users Definitely Know What They Want

    It's not like user's don't know what they want; they do. Damn straight stakeholders know what benefit they expect from a software engagement. When they don't we're practically cruising toward an unsuccessful outcome where the inmates (developers) are running the asylum. They know how their business works better than you do. They likely don't know how to get what they want. If the purport to, then you probably have a problem on your hands. In my experience, this is rare.

    The Domain Expert

    And what about the method Domain-Driven Design puts forward? A domain expert -- often a user of the software -- is the best resource for understanding complex business logic. They'll tell you the what and we figure out the how. Of course with a practices like model-driven development (where model == code), DSLs, and BDD we're bringing our code ever closer to the user.

    If you don't have a domain expert or your expert is unwilling to spend time with you, that's a risk in your project. You'll see the doctor analog, but I'd caution bringing that template in as a norm. It's a risk and a sub-optimal situation. Fight for your right to talk to the domain expert! Build a relationship there.

    The ToC Approach to Software

    Eli Goldratt discusses the role of software initiatives in a lean organization in a presentation available on Audible. One of the processes in ToC is the 4x4 event. In short, the 4x4 is a meeting involving business leaders where constraints and conflicts are identified. It's a time used to identify problems with the system as a whole. One possible result of this meeting is to launch a development project that provides the minimum possible product to exploit and/or protect a capacity-constrained resource. Think the folks putting money down know what we want there? You betcha.

    So What Are We?!

    In one respect we're cartographers. We're there to take the business need and convert that to working code, ideally on a regular basis. In another light, especially in product development, we're stewards or politicians. It's our job to take multiple inputs from multiple customers and introduce features in a way that satisfies our constituencies. The big risk in this context is, of course, re-election.

    A doctor-patient relationship is a very particular pattern of human behavior. How many of you have been rushed through a doctor's visit or had the "privilege" of a visit with a hot-shot specialist? I know last time I was in the hospital (for a wrist surgery, RSI) I spent about four hours waiting around.

    I'd advocate a more collaborative approach. Users do know what they want. Developers need to raise their game to collaborate with them to show them how to pull product. We can start by taking some time and showing them how to write a user stories, for example. We want to establish a relationship with the users of the software we make (their software!), walk a mile in their shoes, and expend the effort to better communicate by forming a peer relationship.

  • How I Got Started in Software

    My buddy Jason Meridith tagged me in the blog meme du jour asking, "how did you get started in software development?"

    How old were you when you started programming?

    At the age of ten or so I frittered around with Basic on the Commodore 64 and Vic-20 back in the day, but I wouldn't classify that as anything too serious. I was a big fan of text-based adventures and they were pretty easy to make. The real art/challenge/fun was always in the story and design of the puzzles. Thankfully, I missed the punch card era.

    How did you get started in programming?

    I really got hooked in college. Now I went to your typical north east liberal arts college and studied eastern religion and psychology (predominately), but one day I made friends with a wacky fellow who called himself "Lothar" and he turned me on to MOOs. MOOs are kind of like a MUD but marginally less geeky. It's essentialy an online community backed by an object oriented programming language. One thing lead to another and I became a programmer on a MOO.

    What was your first language?

    The MOO language (apparently Algol-like) and Pascal in college. In production terms a schizophrenic mix of FoxPro and C.

    What was the first real program you wrote?

    A program that calculated when an oil tank needed to be filled based on tank volume, average daily temperatures, furnace type, and the date of last fill: what a perfect scenario for DDD!

    What languages have you used since you started programming?

    C#, Ruby, JavaScript, Visual Basic, Java, C, C++, FoxPro, SQL, Pascal, and MOO.

    What was your first professional programming gig?

    I started working full time in software at the age of 20. I was hired to write an application for a personal GPS-tracking device. There was some embedded development to do but the main thrust of the application was a call center tool that would record and plot the devices on a map. Fun. As this was a start-up, I also wrote a number of one off applications to hedge starvation. My favorites clients were the ones that would give you free stuff: a cheese shop and a beer distributor.

    If you knew then what you know now, would you have started programming?

    Without a doubt, yes.

    If there is one thing you learned along the way that you would tell new developers, what would it be?

    Two things actually:

    1. Focus on principles. Don't get hung up on products, rather form the opinions and learn the techniques you'll be able to transport with you across any project. It's the kind of investment in your self that pays dividends to you and your clients, so win-win.

    2. Connect with other developers. You'll encounter the "Simpson's Comic Shop Owner" personality as you do this, but ignore them and persist until you find a group of peers. The learning that will come from this group (and it's usually a symbiotic relationship) is incredibly valuable.

  • Super Models, Part 2: Avoid Mutators

    A quick disclaimer: we're entering religious territory here. I feel strongly about this issue, but it's certainly my opinion. If you want to get the full sense of how passionate people are about this issue, check out this article at JavaWorld.

    I've come to the point of view that Entities should not use set mutators ("setters"). Anything you represent as a setter can usually be better represented as a plain old method. Why?

    Let's remember one of the fundamental guidelines of DDD: intention revealing interfaces. Which is more intention revealing?

    Customer c = new Customers().Find(42);
    
    // This...
    c.Address = aNewAddressValueObject;
    
    // or this?
    c.ChangeAddress(aNewAddressValueObject);
    

    That's a subtle point and it's admittedly open for debate. To firm up my argument let's consider the situation where I'm crunching knowledge into model and address change becomes a temporal concept. I now need to track what an address is of a certain date and time. Surely a setter will do the trick, but I think the command "change an address" is better expressed with a method. I can fiddle with the internals of that method and, because we're practicing command-query separation, accept that commands change the state of aggregate roots and entities.

    For me, the biggest argument for avoiding setters is that it promotes thinking in terms of data in a paradigm (DDD) where data-first can be harmful and counter productive. I cannot stress enough: entities are behavioral objects and, for my money, Action<T> where T is some value object fits the notion of command rather elegantly.

  • "Agile Shop"

    The term just reeks of steady state management.

    I find the idea of an "Agile shop" or an "Agile team" is a little misleading and misses the point. What we want is an "Agile organization." The main feature of Agility, to me, is the ability to respond to change: to follow new business opportunities or address challenges. This feature has nothing to do with software development. It just so happens that software might be required to exploit business potential.

    No doubt you can employ development practices such as TDD/BDD, DDD, continuous integration, etc. (after quite a steep learning curve and dues paying process) to create an Agile codebase, but we should not convince ourselves that this is what it means to work in an Agile shop. Good practices simply indicate we're striving for quality and maintainability and collective code ownership and a good team.

    There are more important limiting factors. Let's look at our backlog (or in lean terms, investment): Is it prepared? Do stories have acceptance language? Is there an expression of business value? Is software being released or demonstrated regularly. Is there involvement? Are there clear and evolving priorities? Are your stories speculative things written by the development team or a lead or an architect? And have you been developing infrastructure code in an "Agile way" for the last two months? Do customers/users refuse to meet with you? Is work constantly being expedited? Are you in a cube farm? Do you work a ton of voluntary overtime and is there a turnover problem in your team?

    In the realm of continuous improvement certifications and labels don't count for a whole heck of a lot. Even the most deadly clan of XP ninja will create a local optima rule that is likely to damage the entire system (i.e. company). Businesses need to consider larger issues of throughput (sales) and constraints. Which shareholders care if the team's rocking when there's a mountain of work in progress piling up at deployment preventing new revenue? Which line manager's responsibility is it to make sure the right things are being worked on? How are decisions being made in the larger context?

    Not to get super preachy on you all, but sometimes I think we're full bore on the wrong mission.

  • Crunchy Peanut Butter

    In a post where Jeremy drops some fluent fu, he responds to my assertion that Windsor and NHibernate are the peanut butter and jelly of ALT.NET:

    I'll overlook the fact that my friend David also implicitly implied that an IoC container not named StructureMap was the de facto standard.

    Okay. Okay! Fair enough. Let's call StructureMap the "crunchy peanut butter" (my favorite) and Windsor the "smooth peanut butter" and Ninject the "organic peanut butter" and Unity the "peanut flavored soy-based food paste used on human-powered NASA missions, a.k.a. 'Astronaut Peanut Butter'." Sorry, Glenn, you're name came up when I asked who I needed to alienate next.

    I guess if this post had a point it'd be that our peanut butter is really the Dependency Inversion Principle and the jelly is the paradigm of OOP/DDD/etc. Good reminder!

  • Test Your NHibernate Mappings!

    Disclaimer! Ayende rightly points out that if you are testing your queries you get this mapping test for free. If you aren't, well put this in place as a stop gap measure (to test mappings) and if you have queries, which you probably do, get to testin'!

    A while back Bil Simser put up a post on the first test you should write when using Castle Windsor. In it he shows a technique for verifying his component registrations are correct.

    Since Windsor and NHibernate are the peanut butter and jelly of the ALT.NET crowd, I think we can and should do the same for NHibernate:

    
    [Test]
    public void Verify_NHibernate_mappings()
    {
       string myConfigPath = @"wherever\you\put\your\NHibernate\config.xml";
       Configuration config = new Configuration();
       _sessionFactory = config.Configure(nhibernateConfig).BuildSessionFactory();
    }
    
    

    Would that I did this before today. Yeah, I win the douchey team member award for making a bunch of refactorings (renames mostly) and not fixing the mappings. Remember: Resharper, as great as it is, doesn't do NHibernate mappings. Of course the unit tests passed so I think I'm fine and move on with my life. The next developer that updates with my commit can't run the app and gets to clean up my mess. Fun for them!

    I've learned my lesson. This little screw up illustrates the need for at least some automated integration tests and the lynchpins of many of our architectures -- the ORM/IoC tools -- seem like easy and high value targets.

  • Hook Methods

    I've written about the template method pattern before. For my money it's still a very useful pattern for building super lightweight frameworks and enabling the open-closed principle which states:

    Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.

    So let's review quickly what a template method looks like and what it can do for our code:

    
    public abstract class PriceCalculator
    {
      public Money Calculate(Product product)
      {
        Money retailPrice = GetRetailPrice();
        Discount discount = CalculateDiscount(product);
        return discount.Apply(retailPrice);
      }
      
      public abstract Discount CalculateDiscount(Product product);
      
      public Rate GetRetailPrice() { //... }
    }
    
    public class GoldCustomerPriceCalculator : PriceCalculator
    {
      public override Discount CalculateDiscount(Product product)
      {
        // Gold customers get 20% off, OR
        // We could use per-product discounts.
        return new Discount(20); 
      }
    } 
    
    public class StandardCustomerPriceCalculator : PriceCalculator
    {
      public override Discount CalculateDiscount(Product product)
      {
        // Standard customers receive no discount
        return new Discount(0); 
      }
    }
    
    

    It's pretty easy to see we've gotten some variation. This is a simple example off the top of my head and there's probably a better way to tackle this domain problem, but it shows template method in action so I'll leave it alone.

    This is all well and good, but what if we encountered a scenario where our class could function autonomously but we want to provide an hook or extensibility point for edge cases or later extension (beware of YAGNI on the latter). I'll call this technique a hook method.

    What's a hook method? By playing with the physics of template method a bit to we can make derivations elective by lifting the abstract constraint on our base class and making the template method virtual. The former move is optional and the later is required. Your solution will dictate whether or not the base class should or should not be declared abstract.

    Let's consider an example where we want a start/finish semantic for an implementation of model view presenter. In this example I want to have a base presenter that provides some common functionality: attaching the presenter to the view and raising events to signify the presenter has been started. I want to provide a hook so my presenter implementations can do some processing, call services, obtain reference data, etc. I can accomplish this with a hook method style of template method like so:

    
    public abstract class Presenter : IPresenter
    {
    
      public void Start()
      {
        if (Starting != null) Starting(this, EventArgs.Empty);
        View.Attach(this);
        Startup();
        if (Started != null) Started(this, EventArgs.Empty);
      }
      
      protected virtual void Startup() {};
      
      public event EventHandler Starting;
      public event EventHandler Started;
    }
    
    

    Or we can return to the contrived example of the price calculator to illustrate a non-abstract class:

    
    public class PriceCalculator
    {
      public Money Calculate(Product product)
      {
        Money retailPrice = GetRetailPrice();
        Discount discount = CalculateDiscount(product);
        return discount.Apply(retailPrice);
      }
      
      public virtual Discount CalculateDiscount(Product product)
      {
        return new Discount(0);
      }
      
      public Rate GetRetailPrice() { //... }
    }
    
    public class GoldCustomerPriceCalculator : PriceCalculator
    {
      public override Discount CalculateDiscount(Product product)
      {
        // Gold customers get 20% off, OR
        // We could use per-product discounts.
        return new Discount(20); 
      }
    }
    
    Money price = new PriceCalculator.Calculate(someProduct);
    // or
    Money price = new GoldCutomerPriceCalculator.Calculate(someProduct);
    
    

    I'm sure many of you have seen examples of this in the wild. I'd file this under "pattern life hack." That is, a simple and subtle shift in thinking around template method that expands its many uses in DRYing up your codebase.

  • Super Models, Part 1: Sexy Specifications

    In Domain-Driven Design we turn to the specification pattern when we want to check whether an object matches some criteria. I think specification is the oft-forgotten bastard child pattern of the domain model pattern language. I know I frequently turn to queries -- sometimes query objects -- when I want to retrieve a set of some entity to work on.

    There are some major drawbacks to using queries. Namely there's a huge testing liability. Say we're using a technology like LINQ or NHibernate HQL or even SQL. Well our query and its various predicates that make up our "where clause" are tied up in a single monolithic statement, each of which needs testing. We end up reach deep into the bucket of compromise to find solutions to deal with this mess. Things like object mothers and fluent fixtures help, but are in no way ideal. Wouldn't it be great if we could create a little vocabulary where each word was verified and tested?

    Well, yes, it would. And we can accomplish some of these goals by breeding the specification pattern with one of the original GoF patterns, composite. Other people have written about or demonstrated this concept (extensively) so I'll keep my treatment lean and referential, but I'd encourage you to read on; I'll cover a cute little trick at the end.

    Sidebar: Specification is quickly challenging service or component for the title "most overloaded term in software development." Think about it; we've got specifications in Behavior-Driven Development, Domain-Driven Design, and Design by Contract. To be clear I'm using specification in terms of model specifications and the practice of DDD.

    Composite Specifications

    Let's start with a quick interface, and I'm assuming you've done the background reading on the pattern:

    public interface ISpecification
    {
       bool Matches(T entity);
    }
    

    In reality I'd use a generic with a constraint to be sure that "T" in our case is an IEntity. I define an IEntity for my models so I can be sure we have things like an "ID" and a "Version" and can safely but generic constraints in layer supertypes like repositories, builders, factories, etc.

    Next I'll define a base class, or layer supertype if you trend fancy, with some special methods and some nested classes. Pay attention to the "And" and "Or" with corresponding nested classes:

    public abstract class Specification : ISpecification
    {
       public abstract bool Matches(T entity);
    
       public Specification And(ISpecification specification)
       {
          return new AndSpecification(this, specification);
       }
    
       public Specification Or(ISpecification specification)
       {
          return new OrSpecification(this, specification);
       }
    
       private class AndSpecification : Specification
       {
          private readonly ISpecification left;
          private readonly ISpecification right;
          public AndSpecification(ISpecification left, ISpecification right)
          {
             this.left = left;
             this.right = right;
          }
          public override bool Matches(T entity)
          {
             return (left.Matches(entity) && right.Matches(entity));
          }
       }
    
       private class OrSpecification : Specification
       {
          private readonly ISpecification left;
          private readonly ISpecification right;
          public OrSpecification(ISpecification left, ISpecification right)
          {
             this.left = left;
             this.right = right;
          }
          public override bool Matches(T entity)
          {
             return (left.Matches(entity) || right.Matches(entity));
          }
       }
    }
    

    And I suppose we'll make a sample entity and a couple specifications. These are admittedly very anemic (setters are usually work of the devil) and contrived. It's illustrative folks!

    public class Customer
    {
       public decimal TotalOrders { get; set; }
       public bool Active { get; set; }
    }
    
    public class StatusSpecification : Specification
    {
       private readonly bool active;
       internal StatusSpecification(bool active)
       {
          this.active = active;
       }
       public override bool Matches(Customer entity)
       {
          return entity.Active == active;
       }
    }
    
    public class TotalOrdersSpecification : Specification
    {
       private readonly decimal amount;
       internal TotalOrdersSpecification(decimal amount)
       {
          this.amount = amount;
       }
       public override bool Matches(Customer entity)
       {
          return (entity.TotalOrders > amount);
       }
    }
    

    With all this in place I can now chain specifications together to achieve a composite -- if not somewhat awkward and noisy -- syntax. Example? Okay, sure:

    var specification = 
       new TotalOrdersSpecification(42m).And(new StatusSpecification(true));
    
    var customer1 = new Customer() { Active = false, TotalOrders = 41m};
    Console.WriteLine(specification.Matches(customer1));
    // False
    
    var customer2 = new Customer() { Active = true, TotalOrders = 43m};
    Console.WriteLine(specification.Matches(customer2));
    // True
    Console.ReadLine();
    

    Bring the Hotness

    Update Nigel Sampson describes a similar technique using lamdas and operator overloading. It's a slightly different spin on the same problem, but he also uses the operator overloading trick for clarity. I'd encourage you to check it out; his blog is new but there's some good stuff there already.

    I have some issues with the syntax immediately above. Namely we've got a pretty limited means of expressing complex orders of operation in our specifications. If, in pursuit of complex expressions, we pull the AndSpecification and OrSpecification out then we get an even noisier syntax:

    var specification = 
        new AndSpecification(..., ...).Or(...);
    

    I think I can do better. If we're pursuing the DDD goal of "the model is the code" and we're trying to bring our model to evermore expressive heights we need to eliminate some of the parenthesis junk. We can do this by using that most magical (and dangerous) feature of C#, operator overloading.

    Let's send my specification base class to wardrobe and makeup, stat!

    public abstract class SexySpecification : ISpecification
    {
       public abstract bool Matches(T entity);
    
       private class AndSpecification : SexySpecification
       {
          private readonly ISpecification left;
          private readonly ISpecification right;
          public AndSpecification(ISpecification left, ISpecification right)
          {
             this.left = left;
             this.right = right;
          }
          public bool Matches(T entity)
          {
             return (left.Matches(entity) && right.Matches(entity));
          }
       }
    
       private class OrSpecification : SexySpecification
       {
          private readonly ISpecification left;
          private readonly ISpecification right;
          public OrSpecification(ISpecification left, ISpecification right)
          {
             this.left = left;
             this.right = right;
          }
          public override bool Matches(T entity)
          {
             return (left.Matches(entity) || right.Matches(entity));
          }
       }
    
       private class NotSpecification : SexySpecification
       {
          private readonly ISpecification specification;
          public NotSpecification(ISpecification specification)
          {
             this.specification = specification;
          }
          public override bool Matches(T entity)
          {
             return !(specification.Matches(entity));
          }
       }
    
       public static SexySpecification operator &(SexySpecification left, ISpecification right)
       {
          return new AndSpecification(left, right);
       }
    
       public static SexySpecification operator |(SexySpecification left, ISpecification right)
       {
          return new OrSpecification(left, right);
       }
    
       public static SexySpecification operator !(SexySpecification specification)
       {
          return new NotSpecification(specification);
       }
    }
    

    Now we have a much more natural and terse syntax. You have to use the & and | operators because you can't overload binary operators such as && and ||. I'm OK with this; I get less line noise:

    var specification = 
       new TotalOrdersSpecification(42m) & new StatusSpecification(true);
    

    Admittedly it's a little thing, but as we move into more complex composite specifications little differences like these really start to reduce the mental tax associated with parsing a model which, to me, is a big, big deal. And, when all is said and done, isn't it the little things in life that really matter?

  • Entity Framework: Our Albatross

    Looks like another Entity Framework barfight! Hell, I'll join the fray started by Jeremy. I feel compelled given that I'm part of the NHibernate Mafia.

    Ah! Well a-day! What evil looks
    Had I from old and young!
    Instead of the cross, the Albatross
    About my neck was hung.

    The Entity Framework is the Albatross of ALT.NET. We're forever doomed in podcasts (two I've been on have devolved into this rat hole), blogs, and twitter to have to rail against the machine that is the EF. Let's work toward an elevator pitch, explain why we won't use it, don't believe it will work, and get the hell on with our lives.

    I remember being in Redmond at the original meeting. Yes it's true that this is the genesis of all this ALT.NET business, but come on! There's more to it than NHibernate vs. EF, but we keep coming back to this same, tired subject.

    I made an observation that EF (back then "LINQ to Entities") isn't an ORM way, way back:

    ...EDM (Entity Data Model) is a logical representation of a data model. The framework will permit various “services” to be attached to this model such as domain objects/models containing behavior (which is what we want to test and test-drive after all) replete with LINQ queries, reports, mock and test data generation, entity aggregation type service endpoints, etc.

    Ah... the youthful exuberance of past me (March, 2007). Clearly this is very initial analysis on a beta of a beta of a beta, which is to say: not very deep. I'll admit it. But there's an initial flame of recognition in there.

    An ORM can't be a mere facility to a "data platform." Platforms are old school, we're buckling under the weight of cumbersome frameworks and the myriad scaffolding needed to get an app running on a platform. The Java folks are headed toward MicroKernel architectures and we see this evolution starting in the lightweight containers that tend to germinate as IoC tools. Pick your flavor. So now we're talking platform?! Why on earth would we start with bloat?

    Furthermore and perhaps more immediately, Jimmy Bogard hits the bell with a sledge hammer:

    I think it's a mistake to share a data model with anyone outside your bounded context (see Evans, Domain-Driven Design). It's also a mistake to share a conceptual model or a EDM or whatever we're calling this.

    This is an enterprise architect's vision. All that time enterprise architects are thinking about the single platform to rule them all, well they should consider more how their production lines (e.g. teams in a lean sense) are organized and how to achieve flow, pull, leveling, etc.

    Silver bullets are, in fact, an illusion. We learned this long ago. Let's refresh our memories and move on.

    Okay?

  • Design: Paul Rand & Ubiquitous Language

    The Ubiquitous Language is an important concept in Domain-Driven Design. Some time back, I found this video of Paul Rand talking about his views on the essence of design and art. I love it and see an immediate parallel between his thoughts and the style of language oriented design a good modeler strives toward.

    Consider this quote right from the opening:

    When you say design, everybody has a definition which doesn't coorespond to yours... there are many good definitions: one is the synthesis of form and content. In other words without content there's no form. So without form there's no content. A work of art is realized when form and content are indistinguishable. When form predominates meaning is blunted, but when content predominates interests lag. But the genius comes in when both of these things fuse.

    Wow; that bit directly expresses my approach to and concept of successful software design.

  • The ALT.NET Podcast!

    Mike Moore (aka blowmage) has started a new podcast dedicated to all issues ALT.NET. Mike's an interesting cat. If you haven't checked out his excellent Rubiverse Podcast, do so; fascinating stuff as he gets cool guests. I think people who are in this community will be well served by his efforts. 

    In the inaugural episode Jeremy Miller, Chad Myers, and I (the most over-podcasted developer ever) have a free flowing discussion on how we tackle the need for continuous improvement in our own ways. A lot of the conversations in ALT.NET center on this topic. It was a super fun conversation for me; it's always fascinating to hear about how other people tackle the problem of learning and betterment.

    So pull up a chair and listen in. Looking forward to hearing some great content targeted at our budding community in the near future!

  • Hallway Conversations

    One of the cool things about ALT.NET events and Open Spaces in general is that you encounter interesting hallway conversations at every turn.

    Take this video as a good example. We've got Udi Dahan, Chad Myers, and ScottGu discussing issues around Microsoft and Open Source from varying perspectives.

    How can conversations like this not lead to shared understanding when we multiply this conversation by a hundred or thousand times?

  • Audio/Podcast Help!

    File this one under housekeeping and crowd-sourcing.

    Troy DeMonbreun asks in a comment on one of my video posts:

    Will there be an MP3 version available -- for those that like to listen on work commutes?

    Great idea and I'm totally up for it. My concern is that the audio quality is pretty poor. That and I don't know where to host this stuff. Can anyone recommend a simple (key) audio cleaning tool? Does such a thing exist? Where is a good place to host an audio that produces an RSS feed so I can syndicate this easily?

    If you wouldn't mind, leave a comment below! Thanks very much in advance.

More Posts Next page »