Rediscovering the Obvious

…stumbling in the footsteps of greatness

That’s not X!

without comments

Mark Graban has a great post [1] over at Lean Blog today. His overall premise is one we see over and over again in software: People take a good tool, apply it poorly or in the wrong context, and then blame the tool. Worse, they occasionally broadcast their blame, causing people to have a lower reputation of the tool.

In software, this is most recently seen in the certification discussion and in the “Scrum vs. kanban” conversation. As a result, I very much want to call out a couple of things Mark says in the healthcare context that apply equally well in the software context:

But the difference I draw from the Lean critics:

  1. They see L.A.M.E. and leap to the conclusion that Lean is inherently bad. They throw Lean under the bus and take the tone that these leaders are “idiots.”
  2. I see that Lean works well when leaders learn about and embrace the full management system. I work to try to educate healthcare leaders who are smart, but have a different viewpoint on management.

This is absolutely what I see with agile, lean, scrum, and kanban quite frequently. Teams try, fail, and blame the tool. Yes, it’s quite possible the team tried the wrong tool. It’s also quite possible they didn’t actually use the tool the way it was intended. [2] It could be their context is wrong for that tool in the first place, or that they changed their labels but didn’t change anything they actually do, or that they did things right but ran into a management wall, or faced struggles scaling out to other teams, or any of the hundreds of other reasons that adoptions “fail”.

We amplify this with the way our labels and language creates lines rather than identifying a body of perspectives and tools. It’s time to take a cue from BDD and define some scenarios and well-formed outcomes of the adoption. Mark presents a great list from a nursing perspective…

Why would nurses WANT Lean? When organizations really embrace Lean:

  1. Nurses say, “Finally! Management is seeing the problems we face every day and we’re going to work together on fixing things.” Instead of feeling neglected, they are being properly supported and involved in process improvement.
  2. The culture changes to fix routine “Every Day” problems – instead of jumping through hoops and constantly fighting the same fires, they get to focus more time on patient care.
  3. Lean helps support save care – proven documented examples include reduced patient falls, fewer infections, and fewer cases of V.A.P. — nurses want the best for their patients.
  4. With Lean, the space is designed and sized to match the processes for nursing care, instead of nurses being forced into spaces that don’t have enough bed/equipment storage space, for example.
  5. They get to design their own standardized work and can improve it through daily huddles and kaizen boards.
  6. The nurses get to work as part of a team (such as ThedaCare’s Collaborative Care model, where the RN helps direct doctors and pharmacists.
  7. Nurses work less overtime because they have more time during the day to do proper charting instead of batching it at the end of the day.

These sure feel like things I can see and validate against when they happen. What’s our list look like for software? Here’s a few that come to mind immediately:

  • When a stakeholder asks for a release, it’s done quickly, easily, and with a minimum of fuss.
  • When a stakeholder identifies an opportunity related to the current application [3], it’s not painful to make it into reality.
  • When a problem is discovered with the app, it’s professionally and quickly fixed without attacks or defensiveness.
  • Simple and appropriate improvements are accepted and implemented with a minimum of fuss regardless of source.
  • Teams work in ways that suit them while still respecting their organization
  • People go home, have families, and maintain good balance despite loving their jobs
  • People care about the end result, not just their own specific job
  • Individuals are respectful across specializations, and attempt to use a shared language and goals rather than engaging in “legalese” or “geekspeak”.

What else?


[1] All quotes attributed to “Mark” are from this post, used with permission: http://www.leanblog.org/2010/11/why-nurses-should-reject-lame-and-demand-lean/

[2] Personally, this is where I stop because I feel like I’m approaching the “If it works, it’s Scrum, if it doesn’t, you did it wrong” perspective, but that’s not useful, so I’ll continue.

[3] Using “application” as shorthand for “software stuff we build” including systems, services, apps, etc.

Written by erwilleke

November 9th, 2010 at 4:00 pm

Posted in Uncategorized

EntityCommandShim<T> – Silverlight MVVM helper

without comments

I received a question yesterday around the shim pattern that I used, and I thought I’d clean it up a bit and share it. Again, if you’re used to reading about agile and lean here, this isn’t one of those posts (in case the title didn’t make that clear).

Refresher

The situation I’m addressing is that I have an element in my XAML that uses an ItemsSource (e.g. ItemsControl, ListBox) and want to receive an event specific to one item. This post will assume that I’m working with an items template like this, which will be bound against a DTO or Entity that has a property descriptively named “Value” containing the content to display.

<DataTemplate x:Key="TemplateSelectionItem">
   <HyperlinkButton Content="{Binding Value}" 
   />
</DataTemplate>

Now, whenever the user activates the hyperlink, the “Click” event will be raised. Without MVVM, I’d just add a handler in my code-behind that attaches to the click event and performs the logic. The testability and separation of concerns aspects of MVVM suggest this is a very bad idea. Instead, we should set up something that is called in response to the click. This leads to two options: put handling code on the bound entity, or put handling code in the ViewModel containing the ItemsControl. Since polluting the entity seems like a bad idea for a behavior local to a single view, let’s plan on putting it in in the ViewModel. And, since I like command objects for the flexibility they offer for a wide variety of scenarios, let’s target calling a Command instead of a method. Avoiding Prism-specific code, I’d write something like this:

        <DataTemplate x:Key="TemplateSelectionItem">
            <HyperlinkButton Content="{Binding Value}" >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <i:InvokeCommandAction Command="{Binding Command}" CommandParameter="{Binding }" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </HyperlinkButton>
        </DataTemplate>

Unfortunately, the “Command” binding will always fail, because the DataContext is currently set to my entity. Well, that’s fine, let’s just use a named source like this:

        <DataTemplate x:Key="TemplateSelectionItem">
            <HyperlinkButton Content="{Binding Value}" >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <i:InvokeCommandAction Command="{Binding DataContext.Command, ElementName=myListBox}" CommandParameter="{Binding }" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </HyperlinkButton>
        </DataTemplate>

Unfortunately, this is entirely too brilliant to keep working. It’ll work great as long as you don’t modify the ItemsPanel of your ListBox [1]. As soon as you do that, the binding will fail, and it took me far too long to figure out why the first time. Remembering back to my early programming education when I was taught things like “there’s no problem that can’t be solved with another level of indirection”, I decided to just put something in the middle that puts the Command where I need it. Thus the introduction of the shim, or as it’s now called, the EntityCommandShim. The comment prompted me to do some aggressive refactoring of what I was using, so thank you… here’s what it looks like now:

    public class EntityCommandShim<TEntity>
    {
        public EntityCommandShim(TEntity sourceObject, DelegateCommand<object> command)
        {
            Debug.Assert(command != null && sourceObject != null);

            this.Command = command;
            this.Entity = sourceObject;
        }
        public DelegateCommand<object> Command { get; private set; }
        public TEntity Entity { get; private set; }
    }

There’s not much to it. The Command and Entity references aren’t meant to change for the lifetime of the object, so no INotifyPropertyChanged implementation. The passed in Command is just a reference to one declared on the ViewModel, and doing the wrapping is quite simple with a line like this:

            this.AvailableTemplates = service.AvailableTemplates.Select(item =>
                new EntityCommandShim<FilterData>(item, TemplateItemSelectedCommand)).ToObservableCollection();

Once this is done, I’m all set. The ItemsTemplate becomes: [2]

        <DataTemplate x:Key="TemplateSelectionItem">
            <HyperlinkButton Content="{Binding Entity.Value}" >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <i:InvokeCommandAction Command="{Binding Command}" CommandParameter="{Binding Entity }" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </HyperlinkButton>
        </DataTemplate>

and the repeater can be as simple as this:

            <ItemsControl
                ItemTemplate="{StaticResource TemplateSelectionItem}"
                ItemsSource="{Binding AvailableTemplates}"
                >
            </ItemsControl>

Or as complicated as this: [3]

<input:AutoCompleteBox 
    FilterMode="Contains" 
    MinimumPopulateDelay="250"
    ItemsSource="{Binding Clients}"
    SelectedItem="{Binding SelectedClient, Mode=TwoWay}"
    ItemTemplate="{StaticResource ProviderSelectionItem}"
    IsDropDownOpen="{Binding IsSelectionActive, Mode=TwoWay}"
    ValueMemberPath="Entity.Value"
>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged" SourceName="autoCompleteBox" >
            <ic2:InvokeCommandWithArgsAction 
                Command="{Binding SelectionChangedCommand}" 
                CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=InvokeParameter}"
                />
        </i:EventTrigger>
        <i:EventTrigger EventName="DropDownClosed" SourceName="autoCompleteBox" >
            <ic2:InvokeCommandWithArgsAction 
                Command="{Binding SelectionConfirmedCommand}" 
                CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=InvokeParameter}"
                />
        </i:EventTrigger>
        <i:EventTrigger EventName="DropDownOpened" SourceName="autoCompleteBox" >
            <ic2:InvokeCommandWithArgsAction 
                Command="{Binding BeginSelectionCommand}" 
                CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=InvokeParameter}"
                />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</input:AutoCompleteBox>

[1] I haven’t tried this with ItemsControl, and I don’t know where this issue comes from… any thoughts? I also haven’t tried this in SL4, maybe it’s fixed? Will check that out soon, and if it works, all of this can be removed, making it a true “shim” in the sense that it goes away when the floor’s fixed.

[2] When I need to synchronize against SelectedItem in a list box, I often use CommandParameter={Binding} so I get the instance of the shim to reassign back to a property that’s Mode=TwoWay bound against SelectedItem.

[3] InvokeCommandWithArgsAction is adapted from http://weblogs.asp.net/alexeyzakharov/archive/2010/03/24/silverlight-commands-hacks-passing-eventargs-as-commandparameter-to-delegatecommand-triggered-by-eventtrigger.aspx and is a way of passing the arguments of an event as the CommandParameter. Check it out!

Written by erwilleke

October 25th, 2010 at 3:15 pm

Posted in Uncategorized

How does Google know this stuff?

without comments

I get this – it’s a satellite picture of my condo building in Indy

image

On the other hand, how do they know where the individual units are inside? (Oh, and they’re RIGHT).

image

And it’s done for the apartments nearby…

image

 

What feed is this from?

Written by erwilleke

October 24th, 2010 at 7:21 pm

Posted in Uncategorized

Silverlight AutoCompleteBox and MVVM

with 2 comments

First, a warning

This is not an introduction to the AutoCompleteBox. If you’re looking for a basic overview of the there’s nothing better than Jeff Wilcox’s intro at http://www.jeff.wilcox.name/2008/11/autocompletebox-missing-guide/. Read that, then come back. It’s where I learned by example.

There’s no direct anchor, but about half way down the page you’ll find a section titled “Building a custom search filter” and I’ll be picking up from there. His advice is “Here’s a sample item filter, set in the Loaded event of my page”, which is the first indicator that this isn’t the way to go if you’re doing MVVM… what follows is a way around that.

Next, the backstory

One pattern I’ve adopted in Silverlight development with MVVM is to introduce a helper object when I’m binding to a ListView or ItemsControl’s ItemsSource property. I call this object a “Shim” because it a slightly hackish way of solving what would otherwise be a much bigger problem creating a lot of rebuilding needs. Essentially, the Shim becomes the new DataContext that sits behind each bound item, becoming a mini-ViewModel that matches the mini-View defined by the DataTemplate/ItemTemplate. My typical need is that I need to accomplish two goals:

  1. Bind to the data in a DTO or Domain Object in some interesting way
  2. React to a user’s operation against that item in some way specific to the data instance.

Unfortunately, markup like this doesn’t work in the ItemTemplate because the DataContext is now set to your specific DTO instance rather than to the original ViewModel instance.

<HyperlinkButton Content="{Binding Value}" 
             command:Click.Command="{Binding ItemSelectedCommand}" 
             command:Click.CommandParameter="{Binding}" />

Instead, I introduce the Shim with an assignment something like this:

this.Clients = insurer.Clients.Select(client =>

    new ClientSelectedShim(client, SelectionChangedCommand)).ToObservableCollection();

and then bind as follows:

<HyperlinkButton Content="{Binding Value}" 
             command:Click.Command="{Binding ItemSelectedCommand}" 
             command:Click.CommandParameter="{Binding OriginalData}" 
             />

The Shim instance simply exposes the provided DelegateCommand as a property, along with the original DTO and often an intended display value. (Thus, I bind to “Value” instead of “OriginalData.Value”).

Overall, this feels like the cleanest of several different approaches I’ve tried to get around this binding issue in Silverlight. [1] I tend to do this using the Prism library, but it’s also applicable to other simple MVVM approaches. For example, the same would apply with using an EventTrigger and InvokeCommandAction to activate the command as such:

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="Click"> 
        <i:InvokeCommandAction Command="{Binding ItemSelectedCommand}" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers>

Finally, the Point

All this rambling is a lead up to the challenge I hit today: I added a Shim into the list of items used to populate an AutoCompleteBox, because I needed to respond to the user with some item-specific behaviors in the popup that contains the matching values. As soon as I added the Shim, I couldn’t use the simple FilterMode=”Contains”, because it was comparing against the type of the shim rather than the much simpler string I was giving it before. Because I suddenly had a Shim involved and couldn’t dodge the complexity of having a DTO by just yielding the display value any longer, I was forced to use FilterMode=”Custom”. {EDIT [3]} Problem is, MVVM strongly discourages me from writing code anywhere that looks like Jeff’s sample:

MyAutoCompleteControl.ItemFilter = (txt, i) => Stock.IsAutoCompleteSuggestion(txt, i);

The good news is that binding is incredibly powerful, so here’s what I can do instead:

<input:AutoCompleteBox  
   FilterMode="Custom" 
   MinimumPopulateDelay="250" 
   ItemsSource="{Binding Clients}" 
   SelectedItem="{Binding SelectedClient}" 
   ItemTemplate="{StaticResource ClientSelectionItem}" 
   ItemFilter="{Binding ShimFilter}" 
/>

<!—In Resources –> 

<DataTemplate x:Key="ClientSelectionItem">  
   <StackPanel Orientation="Horizontal" > 
      <HyperlinkButton Content="{Binding Value}" 
         command:Click.Command="{Binding ItemSelectedCommand}" 
         command:Click.CommandParameter="{Binding OriginalData}" 
      /> 
    </StackPanel> 
</DataTemplate>

And, in the ViewModel: [2]

public AutoCompleteFilterPredicate<object> ShimFilter 
{ 
    get 
    { 
        return new AutoCompleteFilterPredicate<object>( 
            (str, item) => { return IsFilterMatch( str, item ); }); 
    } 
}
private bool IsFilterMatch(string valueToCheck, object item) 
{

    ClientSelectedShim shim = item as ClientSelectedShim; 
    if (shim == null) 
        return false; 
    return shim.Value.Contains(valueToCheck); 
}


It wasn’t immediately obvious to me, but this definitely lets me put my comparison code in the ViewModel where it belongs while keeping the expression of the UI structure and behavior. Now I can wire the special effects!

 

[1] One of the most promising ways I’ve otherwise tried involved binding using ElementName to get “out of” the ItemTemplate and back to an element on at the parent level, typically the containing list itself. This will work as long as you don’t change the ItemsPanel to a non-default panel. Making that change hits some bug (feature?) in Silverlight I can’t properly characterize and causes lots of pain figuring out what happened. Be warned!

[2] The property has to stay templated to the <object> type or there will be a binding expression error when the View is first bound against the ViewModel… covariance doesn’t apply here. More info here. Second, it appears it must be an actual property, the binding failed when I tried to have a simple field initialized to the Predicate.

[3] After figuring this all out, I did of course come across the incredibly useful ValueMemberPath property, which allowed me to revert to a simpler design for my specific case. However, if you are doing custom filters (especially if you’re checking against multiple properties, which I’ve done in the past), this technique will still be quite valuable.

Written by erwilleke

October 24th, 2010 at 7:07 pm

Posted in Uncategorized

More good ideas or more labels?

without comments

What do you care about?

An off-kilter venn diagram with three overlapping spaces titled Kanban, XP, and Scrum. They all sit superimposed on a much larger circle titled Good Ideas, along with a call to action to focus on what is important, not about the labels.

Written by erwilleke

October 8th, 2010 at 10:45 am

Posted in Uncategorized

Beyond (Measurement)

without comments

Context

At the “Scrum Beyond Software” in Phoenix, Tobias (@tobiasmayer) challenged us to get beyond the words, and I echoed him. Now it is time to put action behind my words!

This morning, my inbox was freshly loaded with an opportunity to help an unknown find a better way of doing things, and it started like this:

Confession: In all my years of software development I’ve never successfully and usefully estimated, tracked, or measured anything.
I get the impression that measurement is one of the keys to improvement.  If that is so, where should we begin?  What useful statistic should we collect first?  What value can we derive from that info?  How can we apply the information to help us do better? – Alan Baljeu [1]

My challenge to myself: answer this without using any loaded words like “cycle time” or “velocity” or “takt time”, and do so in a way that allows the reader to use the results for self-driven, meaningful improvement at a team level. Here we go!

What do I measure?

I’m going to use a basic physics metaphor. For each of the levels, track things as simply as possible at the item level, aggregate for clarity and perspective, manage any single item out of the ordinary as a special case. Keep the results big and visible in the team’s shared space, whether that’s physical or virtual. Please note, there’s nothing really new here, the basic ideas and metaphor have been around longer at least as long as I’ve been doing software.

1 – Position: What’s being worked on, what’s completely done, what’s going to be worked on next (for a very limited scope of "next" ).

2 – Motion: Take the above, add in time dimension: How long did each item take, when did it start, how many other things were being worked at the same time.

3 – Acceleration: Take the above and start looking for changes in the trends over time. If the "how long" is decreasing, and you didn’t do anything intentionally to make it do so, figure out why and (likely) celebrate!

How do I introduce it?

In my experience each of these levels provides its own, distinct benefit if you do them in order. Start with level 1, figure out a way to effectively track it in your team, get people used to seeing it for a few days, and observe the changes it makes in how the team interacts. Tweak how you’re tracking position and ensure the team’s comfortable before you move forward trying to track and use the next layer of information. Typically, this step is a basic physical or virtual task board, although it could be a shared Google spreadsheet or any number of other tooling-based solutions.

Next, start putting dates along with the work. At its easiest, just jot down the day work starts on something, and the day it’s done, then do a “week-day math” subtraction to find out how many days it was actually being worked on. See what this awareness does to the team, how they react, if the information’s in the right spot.  Finally, start tracking those numbers over time. How many things are typically being worked on at once? Does this number seem to be going up, down, everywhere, etc? How about the time things tend to take? Is it getting smaller? How about rework on things that “could” have been right? Is it in balance with the time it would have taken to discover the right way in the first place? Is Quality high? Start mapping the perceptions against the numbers and see if they match up, figure out what patterns are in there.

Throughout these steps you’ll start seeing things you want to change about how you approach your work. Do so! Try things, see if they work, and be willing to put things back the way they were if you don’t like the results. Foster an attitude within the team to make these experiments a Good Thing ™. Treat them as experiments… success and failure isn’t the goal, learning a better way is the goal, and it takes both “success” and “failure” to achieve that learning.

Finally, remember to look back at the old numbers once in a while, and celebrate as a team just how much better the new numbers are, and how far you’ve come as a team.

Good luck!

 

[1] – I normally would avoid applying attribution to something that sounds potentially negative. In Alan’s case, I greatly respect the courage it takes to publically state something like this, and I also recognize that finding a quote is trivially easy and he deserves the respect that courage deserves.

Written by erwilleke

October 5th, 2010 at 11:52 am

Posted in Uncategorized

Aspirations

without comments

Join a community of thinkers,
engage teams and organizations,
unfetter human potential,
inspire through my contributions,
create safe, successful environments,
facilitate amazing outcomes,
learn from the successes of others,
deliver amazing experiences,
maximize value, and,
in short, realize my vision of helping everybody involved with a project sleep better at night.

Written by erwilleke

July 22nd, 2010 at 8:02 pm

Posted in Uncategorized

Agile 2010 – The words we use

without comments

As I was looking through the schedule for Agile 2010 today, I thought I’d take a look at how many lean and kanban talks there were. As I was searching, I noticed a few other words that kept coming up, and thought I’d check out the actual distribution of words among all the session titles. Thus, I took the session list from http://agile2010.com/schedule.html, cleaned it up to remove the extra columns, headers, footers, etc, and then ran it through the tool at http://textalyser.net/ to see what was in there.

First, it appears that “Agile” is the most popular word in the English language, at least based on our sample. At least we’re buzz-word compliant in this case!

image

Next, there are definitely some clues as to what our community finds important during the selection process… here are all non-trivial words appearing seven or more times. Does this mean anything? I don’t know. Maybe we need to forbid the use of the word “Agile” at agile conferences (and Lean at lean conferences, etc). image

Written by erwilleke

July 1st, 2010 at 8:09 pm

Posted in Uncategorized

Define: ScrumMaster

without comments

image

It seems that everybody already assumes they know what a ScrumMaster’s supposed to do! Let’s try the non-trademarked version.

 

image 

Ahhh, so all I need to know, according to what I do first when I want to learn what something means, is that a ScrumMaster is equivalent to a project manager. Perfect. Let’s get started.

Please note, I have no desire to imply any criticism of Scrum (in this post), this is just an observation of what people “outside the bubble” might happen to find when we throw around our terms.

[EDIT]

It seems you can order ScrumMasters off the shelf, too. They even include free shipping if you spend more than $25 on one!

image

Written by erwilleke

June 28th, 2010 at 5:40 pm

Posted in Uncategorized

Test post

without comments

This is a test post to see how quickly google picks up the #lssc10live tag from this post.

Written by erwilleke

April 18th, 2010 at 10:41 am

Posted in Uncategorized