Myth: Product Owners Can’t Handle the Truth

I’ve long been taught and believed that the truth will set you free. But fear is a powerful counter to belief, especially when that fear is rooted in the compellingly powerful human instinct to survive, to preserve your livelihood.

I was reading Ken Schwaber’s The Enterprise and Scrum today and came across the following passage which I deeply appreciated. Ken is writing about to the development team’s fear of telling the Product Owner that they cannot deliver on their commitments for a Sprint.

When I discuss this kind of fear at the courses I teach, the attendees’ own fear is palpable. The soon-to-be Scrum users don’t think that the transparency, or truth, is acceptable where they work. They tell me that they will be fired if they tell the truth. Truth isn’t what their customers want to hear. They tell me their customers will find someone else who will lie to the them if they don’t. I have seen this in class after class for five years. People in product development think that their customers want to hear news only if it is good news and would rather hear a lie than the truth. “Lying” is a harsh word. But what else do you call saying that something is true when you know it not to be true? What else do you call misleading someone with information or holding back information that would have led them to better decisions? The Product Owners want to believe in magic, and the developers support their belief by lying. “Can you do this project by this date?” “Sure, no problem.”

The developers are aware of the complexities that cause changes to their original estimates. They are aware that the customer is unhappy. If a project manager is approached by a customer 60 percent of the way through a project and asked how the project is going, the project manager doesn’t really know. She knows that some things are going well. She also knows that some things are not going so well. She also knows that she hasn’t checked up on some things that could prove critical. However, saying “I don’t’ know” is unacceptable, so project managers have learned to say, “Right on,” “Right on target,” “Piece of cake,” or anything equivalent that will get the customer to go away and leave them to try to get everything on time, on cost. Basically, they lie. It is simpler than exposing all the nuances and complexities that add up to “I don’t know.”

Project managers might also believe that lying saves time. But because Scrum relies on transparency, misrepresentation undercuts the entire application of Scrum. If the Product Owners do not know exactly where things stand at any point in time, they will be unable to make the best decisions possible about how to achieve their goals. They need the best information possible, whether they view it as good or bad.

I don’t know anyone in this business who cannot relate to Ken’s assessment. I am coming to the conclusion with every additional year I spend in the role of code monkey that anyone, with proper preparation and context, can handle the truth, even non-technical folk. I am learning to reject the often held notion that these people are just not able to appreciate the nature of complexity.

Yes, Product Owners not only must have the truth but in fact they can handle the truth even when the truth is not welcome news. I have seen Product Owners ignore the truth but I have never been fired because I told the truth. What Product Owners have a very difficult time handling is the sudden discovery of the truth after having been lied to for long periods of time.

Whether we choose to tell the truth from the start or to lie to ourselves and our Product Owners, eventually, as the Bard would be wont say, the truth will out.

So I still believe that the truth will set you free. Fear will leave you miserable and in chains with the secret knowledge that the truth will be discovered sooner or later by those from whom you’ve hidden it. Freedom is so much easier than we sometimes think.

Deep Null Coalescing in C# with Dis.OrDat<T>

The other day, a friend and I were reviewing some code like this and decided we deeply disliked it.

// var line1 = person.Address.Lines.Line1 ?? string.Empty;
// throws NullReferenceException: 
//    {"Object reference not set to an instance of an object."}

// The ugly alternative

var line1 = person.Address == null
        ? "n/a"
        : person.Address.Lines == null
        ? "n/a"
        : person.Address.Lines.Line1;

If you have ever written code like that or even worse, with the if (obj != null) statements, then you can certainly relate to our lack of love for the constructs required to avoid the dratted NullReferenceException.

So we experimented with a solution and nearly got there. Tonight I finished that up and the new Dis class is born with the OrDat<T> method so you can now write this instead.

var line2 = Dis.OrDat<string>(() => person.Address.Lines.Line2, "n/a");

Here’s the full example and if you’re patient enough to scroll down, you’ll also find the full implementation of the Dis.OrDat class and method.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DeepNullCoalescence
{
  class Program
  {
    static void Main(string[] args)
    {
      var person = new Person();

      // var line1 = person.Address.Lines.Line1 ?? string.Empty;
      // throws NullReferenceException: 
      //    {"Object reference not set to an instance of an object."}
      
      // The ugly alternative
      var line1 = person.Address == null
              ? "n/a"
              : person.Address.Lines == null
              ? "n/a"
              : person.Address.Lines.Line1;

      // A cooler alternative
      var line2 = Dis.OrDat<string>(() => person.Address.Lines.Line2, "n/a");

      Console.WriteLine(line1);
      Console.WriteLine(line2);
      Console.ReadLine();
    }
  }

  internal class Person
  {
    public Address Address { get; set; }
  }

  internal class Address
  {
    public AddressLines Lines { get; set; }
    public string State { get; set; }
  }

  internal class AddressLines
  {
    public string Line1 { get; set; }
    public string Line2 { get; set; }
  }
}

And for the patient reader, here is the actual magic.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace DeepNullCoalescence
{
  public static class Dis
  {
    public static T OrDat<T>(Expression<Func<T>> expr, T dat)
    {
      try
      {
        var func = expr.Compile();
        var result = func.Invoke();
        return result ?? dat; //now we can coalesce
      }
      catch (NullReferenceException)
      {
        return dat;
      }
    }
  }
}