Showing posts with label design. Show all posts
Showing posts with label design. Show all posts

Saturday, August 23, 2014

What you know and have impacts your design



Description

You can only design from what you know and/or have available to you. Here's a short video showing the evolution of a electric switch design based on new information.

Transcript

Shop equipment frequently have two push-button toggle switches to turn things on and off. I recently worked on a project where I wanted to replicate this behavior to control an appliance and do it inexpensively. My hope was to get by with junk bin parts.

Looking around at my spare parts, I found a project box, a couple momentary switches and a relay with contacts rated above what I wanted to control. So I started with these items.

It was a double-pole relay. My thought was to use one pole of the relay to hold itself energized and the other pole to switch my device. So, one switch energizes the relay and the relay then holds itself closed. This should allow me to turn on the device.

I figured a transistor could be placed between supply voltage and the relay's coil with the base wired to the supply voltage. The "off" switch could connect to the base of the transistor and ground. In this configuration, the transistor would normally be on allowing, the relay to be energized. But when the button is pressed, the transistor would turn off the power to the coil, switching the relay off.

I wired it all together and it worked!

The relay circuit was too big to fit in the project box though, so I wired the switches through a four conductor wire and put the circuit in a separate box next to the switched item.

Even though it worked, I wasn't too wild about having high voltage and low voltage running through the different poles of the relay. It seemed like a pretty bad hack.

While I worked on other aspects of the project, I ran across something called a "PowerSwitch Tail." This looks like a short extension cord but it has a twist. It has a solid-state relay built into it. Normally the outlets are turned off, but place a low voltage across these connectors and the outlets will turn on.

This seemed like a much better solution than my relay hack.

So I completely rethought my approach.

I could have simply replaced the high voltage side of the relay circuit with a low voltage source going to the power tail's connectors. This would work, but now the relay seemed way overkill. I had a low voltage circuit controlling another low voltage circuit through a relay.

Instead I replaced the relay based circuit with a flip-flop circuit. These can be built from discrete components, but I had a quad NAND gate chip in the parts box and this would shrink the size significantly.

I wired up the new circuit and it worked. A much cleaner approach.

As I worked on other aspects of the project, I had a realization: that flip-flop circuit was small enough it could fit in the project box with the switches. If I reconfigured the 4-conductor wire to have voltage, ground and signal, I could move the circuit to the box.

In the end, I did this as it allows future changes to the switching mechanism. Right now I have the two push button toggle switch configuration. But at some point, I'm thinking I want to have a current detecting switch to turn one appliance on and off based on another appliance being on or off. This is easily done with the new configuration but wasn't so convenient with the old.

So, that's my story about how this design evolved over time as I discovered new resources and thought about the problem at a deeper level.

Catch you next time.

Wednesday, April 9, 2014

Are enumerations evil?

Or, How to refactor an enumeration to multiple classes

I ran across this article about how to refactor a switch statement to a data structure in JavaScript a while ago. This is not a terrible refactoring technique. I've used something similar with dictionaries in C# where the key was an enumeration and the value was an Action (or Func). It can be a minor refactoring to a single method that can help clean-up the code. Then this week I had a conversation with a fellow developer about the appropriateness of an enumeration in existing code from a couple different libraries he was reading.

This led me to wonder afresh if perhaps enumerated types aren't something that we as the development community should treat as an anti-pattern. In the days before class types, they were a means for the compiler to force integers to known values and provide more readable code for the developer. The compiler could check values better at compile time and catch usage errors earlier. I have worked on languages without them and embraced them when they became available. At that point they were a good thing.

Many times enumerations are used to change behavior of some code based on a variable's value. This is usually done through switch or if-then-else statements. Or, as discussed above, using some sort of dictionary like structure to store behavior associated with a specific enumerated value.

The problem is this pattern tends to get replicated within the class containing the enumerated variable. The class using the enumeration needs to do different things based on the various values the variable can have and these different things spread throughout the class (or classes) using the enumeration. Then, when a value is added to the enumeration, each place the variable is tested needs to be updated to handle the new value.

This can lead to a number of problems. With behavior based on the enum scattered throughout classes, the intent can be both obfuscated and duplicated. When adding a value to the enumeration, it's easy to miss a place that needs new behavior, introducing hard to detect bugs. The code is fragile in the face of changes. And because the state and associated behavior associated with the enumeration is mixed in with the class (or classes) using it, violation of the Single Responsibility Principle frequently is seen.

Refactoring to a data structure as mentioned above is a good first step. It helps address a number of the problems. But in today's object oriented world, there is a better way. In many (perhaps most) cases it's better to refactor to multiple classes, one for each value in the enumeration. Fortunately, this is fairly easily done.

Here's the original starting code:
enum SomeItemEnum = { one, two, three };
class A
{
  SomeItemEnum someItemValue;
  void SomeItemUser()
  {
    switch(someItemValue)
    {
      case one:
        // Some complicated code for case one
        break;
      case two:
        // Some complicated code for case two
        break;
      case three:
        // Some complicated code for case three
        break;
    }
  }
}
First, a base class is created as an ancestor for the enumeration.
enum SomeItemEnum = { one, two, three };

class SomeItemEnumBase
{
}

class A
{
  SomeItemEnum someItemValue;
  void SomeItemUser()
  {
    switch(someItemValue)
    {
      case one:
        // Some complicated code for case one
        break;
      case two:
        // Some complicated code for case two
        break;
      case three:
        // Some complicated code for case three
        break;
    }
  }
}
Then, each place where something needs to be done based on the value of the enumeration, a method is added to the class. If there is no default behavior for a method, it should be abstract, otherwise it should be virtual.
enum SomeItemEnum = { one, two, three };

abstract class SomeItemEnumBase
{
  abstract void ComplicatedCode();
}

class A
{
  SomeItemEnum someItemValue;
  void SomeItemUser()
  {
    switch(someItemValue)
    {
      case one:
        // Some complicated code for case one
        break;
      case two:
        // Some complicated code for case two
        break;
      case three:
        // Some complicated code for case three
        break;
    }
  }
}
A child class should be made for each value of the enumeration with the value specific behavior moved to the appropriate overridden method.
enum SomeItemEnum = { one, two, three };

abstract class SomeItemEnumBase
{
  abstract void ComplicatedCode();
}

class SomeItemEnumOne : SomeItemEnumBase
{
  override void ComplicatedCode()
  {
    // Some complicated code for case one
  }
}

class SomeItemEnumTwo : SomeItemEnumBase
{
  override void ComplicatedCode()
  {
    // Some complicated code for case two
  }
}

class SomeItemEnumThree : SomeItemEnumBase
{
  override void ComplicatedCode()
  {
    // Some complicated code for case three
  }
}

class A
{
  SomeItemEnum someItemValue;
  void SomeItemUser()
  {
    switch(someItemValue)
    {
      case one:
        // Some complicated code for case one
        break;
      case two:
        // Some complicated code for case two
        break;
      case three:
        // Some complicated code for case three
        break;
    }
  }
}
Change the type of the class' variable from the enumeration to the base type.
enum SomeItemEnum = { one, two, three };

abstract class SomeItemEnumBase
{
  abstract void ComplicatedCode();
}

class SomeItemEnumOne : SomeItemEnumBase
{
  override void ComplicatedCode()
  {
    // Some complicated code for case one
  }
}

class SomeItemEnumTwo : SomeItemEnumBase
{
  override void ComplicatedCode()
  {
    // Some complicated code for case two
  }
}

class SomeItemEnumThree : SomeItemEnumBase
{
  override void ComplicatedCode()
  {
    // Some complicated code for case three
  }
}

class A
{
  SomeItemEnumBase someItemValue;
  void SomeItemUser()
  {
    switch(someItemValue)
    {
      case one:
        // Some complicated code for case one
        break;
      case two:
        // Some complicated code for case two
        break;
      case three:
        // Some complicated code for case three
        break;
    }
  }
}
Instead of setting discrete values on the enumerated variable, now a class instance of the appropriate type can be set.

Old method:
someItemValue = SomeItemEnum.one;
someItemValue = SomeItemEnum.two;
New method:
someItemValue = new SomeItemEnumOne();
someItemValue = new SomeItemEnumTwo();
All the switch/if-else statements can now be changed to simple method calls that have polymorphic behavior based on the class type.
enum SomeItemEnum = { one, two, three };

abstract class SomeItemBase
{
  abstract void ComplicatedCode();
}

class SomeItemOne : SomeItemBase
{
  override void ComplicatedCode()
  {
    // Some complicated code for case one
  }
}

class SomeItemTwo : SomeItemBase
{
  override void ComplicatedCode()
  {
    // Some complicated code for case two
  }
}

class SomeItemThree : SomeItemBase
{
  override void ComplicatedCode()
  {
    // Some complicated code for case three
  }
}

class A
{
  SomeItemEnumBase someItemValue;
  void SomeItemUser()
  {
    someItemValue.ComplicatedCode();
  }
}
And finally, the unused enumeration declaration can be removed.
enum SomeItemEnum = { one, two, three };

abstract class SomeItemEnumBase
{
  abstract void ComplicatedCode();
}

class SomeItemEnumOne : SomeItemEnumBase
{
  override void ComplicatedCode()
  {
    // Some complicated code for case one
  }
}

class SomeItemEnumTwo : SomeItemEnumBase
{
  override void ComplicatedCode()
  {
    // Some complicated code for case two
  }
}

class SomeItemEnumThree : SomeItemEnumBase
{
  override void ComplicatedCode()
  {
    // Some complicated code for case three
  }
}

class A
{
  SomeItemEnumBase someItemValue;
  void SomeItemUser()
  {
    someItemValue.ComplicatedCode();
  }
}
Now, when a new value is added, only places that actually care about the new value specifically (e.g. where its value is set) need to be touched. As a bonus, the compiler will complain about any unimplemented abstract functions, ensuring all required behavior is implemented.

Finally, admittedly, in this toy example, the final result is more complicated and obtuse than the original. If production code is as simple as this example, then it doesn't make sense to make this change. However, when class A is larger and more complex, the increased clarity and robustness of the code can be significant. In my experience, the latter is more typical than the former and so in general, my conclusion is enumerations border on evil.

Friday, December 6, 2013

How to generate an alert tone from a computer

I recently read a Code Project thread that got into a discussion about beeps, internal speakers and alerting the user. This reminded me of a story from a previous life...

It was the early 90s and I worked for a company that provided software to E-911 dispatch centers. There was a machine room with racks of computers and then the actual dispatch center which only had user I/O devices. The monitors and keyboards were run through special extension hardware that allowed VGA, keyboard, mouse, serial and parallel ports to be removed from the computer by a fair distance. It seems like the system would drive them up to 100 feet away, but my memory could be faulty. In any case, we had all these extension boxes scattered throughout the center but all the built-in computer speakers were back in the server room.

A feature of the software allowed dispatchers to place calls in a pending queue. This was for low priority calls that didn't have resources available for immediate dispatch. After a timeout, things in the queue would start escalating. First they'd change color. Then they'd start flashing. The Chief wanted the next level to be an audible alert. And, with this being the fire department, audible alert didn't mean a simple "beep." It needed to be impossible to ignore, klaxon-loud and obnoxious. And of course there wasn't any budget for any significant hardware. I thought about it on the drive home and had an idea as I fell asleep.

The next morning I stopped by Radio Shack and picked up a $10 monophonic amplifier. Something simple. (Amazingly, I just searched for it and they still sell the same model 20+ years later, albeit at a slightly higher price.) I also got a 1/8" patch cord and power adapter. When I got to the dispatch center, I cut off one end of the patch cord and connected the leads to the ground and transmit pins on an RS-232 connector on one of the extension boxes. Then I plugged in the amplifier, turned the volume down low, created a short text file with some random characters and cat'ed it to the appropriate /dev/tty port. An earful of noise rewarded my efforts.

Now I knew my idea would work. Playing around with different repeating character sequences gave different patterns. Changing the baud rate would change the frequency. Eventually I came up with a combination that worked pretty well. It was loud, obnoxious and impossible to ignore. The Chief loved it. And it cost less than $20 and an hour or two of work.

Friday, May 3, 2013

Extension methods are cool

You are creating a vocabulary, not writing a program. Be a poet for a moment.

-- Kent Beck

When Microsoft first introduced extension methods to C#, my first reaction was "eh". I viewed them as a novelty without much use. As time has worn on, I've come to appreciate them more and more. Their biggest win for me is to add features to basic system defined types and to fix what I consider deficiencies in the .Net libraries.

Static methods that take as a parameter an instance of the class they are defined in really annoy me. One frequent irritation: string.IsNullOrEmpty(). Every time I go to use this I always start writing the variable I want to test and then realize the method is static and have to go back and insert the "string.IsNullOrEmpty" at the front. This is simply one of many, many other similar methods spread throughout the framework with this.

Shortly after extension methods were added, one day while I was again grumbling at the IsNullOrEmpty implementation, I realized this would be an easy thing to fix. About five minutes later, after figuring out the syntax for extension methods, I had something like:
public static class StringExtensions
{
     public static bool IsNullOrEmpty(this string target)
     {
          return string.IsNullOrEmpty(target);
     }
}

Now I could write tests in the much more natural (for me) "if (someString.IsNullOrEmpty())..." format. Personally I find this much easier to read.

Flush with this success I immediately added another library function I remembered from Delphi that, in my opinion, helps with readability:

public static class ObjectExtensions
{
     public static bool IsAssigned(this object target)
     {
          return target != null;
     }
}

Instead of "if (someObj != null)..." I could now say "if (someObj.IsAssigned())..."

There is a real downside I with this though: Resharper does not recognize this as a test for null and reports a possible null value warning on subsequent accesses.

I'll admit, these aren't earth-shaking, industry-changing algorithms. But in day-in, day-out coding, I find the resulting code much easier to read.

Today I threw together a couple extensions to simplify work with Points, Rectangles and ranges:
public static Extensions
{
     public static Point Center(this Rectangle bounds)
     {
          return new Point((bounds.Left + bounds.Width) / 2, (bounds.Top + bounds.Height) / 2);
     }

     public static double DistanceTo(this Point p1, Point p2)
     {
          return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));
     }

     public static int ConstrainTo(this int constrainedValue, int min, int max)
     {
          return Math.Max(min, Math.Min(constrainedValue, max));
     }
}

With these, I transformed a method where the purpose was lost in all the notation to one where the purpose was eminently clear. Extension methods truly enable the craftsman to apply the opening quote from Kent Beck. They easily allow the developer to introduce, at the application level, domain vocabulary to system and other 3rd party classes.

Yes, extension methods are pretty cool!

Monday, April 2, 2012

There and back again, again: Any resource's tale

Or, how to generically set and restore state when an exception is raised

I've written twice before (here and here) about making cursor changes more robust with the using statement in C#. These allow states to be reset to correct values regardless of whether or not an exception is raised during some processing. As promised at the end of the last article, today I explain how to use lambdas to easily protect any type of "resource" without having to create a new class or sprinkle your code with try/finally blocks.

To set things up and provide a bit of context, the other day in a code review, I found this:

someFlag = true;
someStartStateMethod();
// Do some work
someResetStateMethod();
someFlag = false;

Over the years, I've seen this pattern repeated, in different domains and different languages and not necessarily limited to setting a flag. Whenever I do, I ask "if an exception happens anywhere in 'do some work,' should the state be reset?" I won't say the answer should always be "yes," but I've not yet found a "no." And this case was no exception.

Since some of the places this was done was nested, I wanted a way to clean all this up that didn't involve adding try/finally blocks. Each try/finally would add another level of indentation; it would get pretty deep pretty fast. Also, it would clutter up the code with noise that didn't really have anything to do with the work needing to be done. In other words, I didn't want this:

someFlag = true;
try
{
   someStartStateMethod();
   try
   {
     // Do some work
   }
   finally
   {
      someResetStateMethod();
   }
}
finally
{
   someFlag = false;
}

In my last article, I separated the code actually handling the protection from the code controlling the invocation of that protection by using inheritance. I created a base abstract class to handle the general IDisposable pattern and descendent classes to handle the actual protection. In that article, I showed a class to handle changing a cursor and then changing it back to the current value.

I quickly realized this code was simply another example of that pattern. I could do the same thing as earlier and put the someStartStateMethod() and someResetStateMethod() in a descendant class. If I followed that pattern, the code under review could be something more along the lines of:

using(new ChangeSomeFlag())
using(new ChangeSomeStateMethod())
{
   // Do some work
}

This is somewhat better.

However, in this case, creating a new class for each thing needing protection didn't seem too appealing. There would be a lot of small special purpose classes, some of which might only be used once. It seemed like a sledgehammer to drive a brad. For this code, I wanted to emphasize composition over inheritance.

Enter lambdas. Because lambdas allow you to treat code as data, they allow easy composition. The LINQ and Rx libraries are great examples. They provide many generic methods (e.g. Where, Select, Any) that have the ability to compose in functionality through the use of lambdas to work on specific types for specialized purposes.

In this particular case, lambdas can be used to contain the code that handles the protection and passed to a class whose sole job is to handle the invocation of that code at the appropriate time. Rewriting the previous example with a new, as yet undefined ResourceProtector class, its use looks like:

using(new ResourceProtector(() => someFlag = true, () => someFlag = false))
using(new ResourceProtector(() => someSetStateMethod(), () => someResetStateMethod()))
{
   // Do some work
}

In this code, two expressions are passed to the constructor of the ResourceProtector class that handle the saving and restoring of state. Here is a single class that can be reused over and over in different situations to protect different types of resources. I think this is a beautiful example of the single responsibility principle combined with the power of lambda expressions to handle composition.

public class ResourceProtector : IDisposable
{
   private bool Disposed { get; set; }
   private Action EndProtection { get; set; }

   public ResourceProtector(Action startProtection, Action endProtection)
   {
      Disposed = false;
      EndProtection = endProtection;
      startProtection();
   }

   public void Dispose()
   {
      DisposeInt();
      GC.SuppressFinalize(this);
   }

   private void DisposeInt()
   {
      if (Disposed)
         return;

      EndProtection();
      Disposed = true;
   }

   ~ResourceProtector()
   {
      DisposeInt();
   }
}

If you have any questions, suggestions or comments, please feel free to leave them below. Until next time, subscribe to the Twitter feed to get notified of future articles and hear about other development related things.

Monday, March 12, 2012

There and back again, again: Several resource's tale

Or, how to safely change a cursor or other resource

In a previous article, I presented a simple class that utilized the IDisposable pattern to set the cursor to a specific value and then automatically reset it to the initial state when some work was accomplished. This simple class had two limitations: it only worked with WPF and it only worked on cursors.

To overcome these limitations, I refactored this to be more general. I changed the context to a generic type and added an abstract RestoreState method that's called when the class is either destroyed (preferred) or the finalizer is called. This allows all the basic plumbing regarding the IDisposable pattern to be contained in one class.

using System;

namespace ResourceProtection
{
    public abstract class ResourceChangeHandler : IDisposable
    {
        protected TContext Context { get; set; }
        private bool Disposed { get; set; }

        protected ResourceChangeHandler(TContext context)
        {
            Disposed = false;
            Context = context;
        }

        public void Dispose()
        {
            DisposeInt();
            GC.SuppressFinalize(this);
        }

        protected abstract void RestoreState(TContext context);

        private void DisposeInt()
        {
            if (Disposed)
                return;

            RestoreState();
            Disposed = true;
        }

        ~ResourceChangeHandler()
        {
            DisposeInt();
        }
    }
}

The beauty of this is it can be used as the base class for specific needs. The function of actually changing a resource is split out from the framework needed to manage the change. Here are three examples: one each for a WPF cursor changer, a WinForms cursor changer and a TreeView BeginUpdate/EndUpdate handler.

How to change a WPF cursor

public class WpfChangeCursor : ResourceChangeHandler{
    private Cursor OriginalCursor { get; set; }

    public WpfChangeCursor(FrameworkElement element, Cursor newCursor)
            : base(element)
    {
        OriginalCursor = Context.Cursor;
        Context.Cursor = newCursor;
    }

    protected override void RestoreState()
    {
        Context.Cursor = OriginalCursor;
    }
}

To use this, instantiate an instance of WpfChangeCursor in a using block, passing in the element who's cursor should be changed and the new value for the cursor. In this case, the context for the base class is the element containing the cursor to be changed. The descendant class has the responsibility to remember the current value and changing the cursor.

How to change a WinForm cursor

public class WinFormChangeCursor : ResourceChangeHandler{
    private Cursor OriginalCursor { get; set; }

    public WinFormChangeCursor(Cursor newCursor)
            : base(Cusor.Current)
    {
        Cursor.Current = newCursor;
    }

    protected override void RestoreState()
    {
        Cursor.Current = Context;
    }
}

This class is used by instantiating an instance of WinFormChangeCursor in a using block with the new value of the cursor passed to it. This is a little different from the WPF version since there is only one cursor for the application, rather than for each element. In this case, the context passed to the base is the current cursor value which is then used by RestoreState to put things back.

How to call BeginUpdate and EndUpdate safely

public class TreeViewUpdate : ResourceChangeHandler{
    public TreeViewUpdate(TreeView treeview)
            : base(treeview)
    {
        Context.BeginUpdate();
    }

    protected override void RestoreState()
    {
        Context.EndUpdate();
    }
}

And finally, here's a class to make sure EndUpdate is called for every BeginUpate on a TreeView. Like the WPF cursor changer above, the control is passed in as the context for the ancestor class. BeginUpdate is then called on the context. When the using block this class is controlled by finishes, the EndUpdate in RestoreState is called, again on the same context as the BeginUpdate.

This technique provides for a level of separation between the framework needed to safely do and undo things from the actual work of doing and undoing them. It works well for certain classes of problems, specifically fixed things that happen over and over again. The examples above of doing repetitive things on framework level items are good examples.

Sometimes though, one wants this type of functionality without the overhead of creating a new class each time. In the next article, I'll present a method of composing this type of behavior in a more adhoc manner.

Until then, subscribe to the Twitter feed to get notified of future articles and hear about other development related things. And if you have any questions, suggestions or comments, please feel free to leave them below.

Thursday, May 26, 2011

There and back again: A Cursor's tale

I've been working on UI code recently and have run into this quite a bit:
Cursor = Cursors.Wait;
SomeLongRunningTask();
Cursor = Cursors.Default;
Pretty straight forward code. I see this type of thing a lot, not just in the C# code I'm working on now, but I've seen this in the past. In other languages. On other platforms. It's a common practice. The problem is it only works in some cases.

This will have problems if any method in the "long running task" does the same thing. The cursor will be set back to default prematurely. Of course, this is easily solved by saving the old value prior to setting the new one.
var oldCursor = Cursor;
Cursor = Cursors.Wait;
SomeLongRunningTask();
Cursor = oldCursor;
This is an improvement but will still fail if an exception is raised. This can be fixed with a try/finally.
var oldCursor = Cursor;
Cursor = Cursors.Wait;
try
{
    SomeLongRunningTask();
}
finally            
{
    Cursor = oldCursor;
}
Ok. So now we have some code that works reasonably well. The issue now is one of code maintainability and clarity. Every method that needs to change the cursor needs to add nine lines before it can do any work of its own. It's nine lines where bugs could hide. It's nine lines obscuring the real purpose of the method. There's got to be a better way.

Way back in my Delphi days, I had a small class which handled this chore for me. The constructor took a parameter containing the new cursor. The current cursor was saved in a class field, the cursor was changed and the constructor finished. The destructor simply set the cursor back to the saved value. In that environment, interfaces were reference counted and destroyed when the reference went to zero. The compiler took care of all the bookkeeping automatically. So I could create an instance of this class, store it in a local variable and, when the variable went out of scope, the object was destroyed, resetting the cursor. It worked really well. One line to change the cursor to whatever I wanted and it automatically reset to the original value when done. Pretty sweet.

Unfortunately, C# does not have any deterministic way of handling object lifetimes. This is one of my biggest frustrations with the language. The closest thing we have is the hack that is the using statement. Since this is the best we have, I have put together a class, shown below, similar to the one I had before. The constructor takes the new cursor value and control whose cursor should be changed, saves the current one and, in the Dispose method, resets it back. Now we can have three simple lines with one code block rather than the nine lines with two blocks. It's a big improvement although still not the single line like I'd prefer.

In use, it looks like this:
using ChangeCursor(this, Cursors.Wait)
{
    SomeLongRunningTask();
}
Arguably, this is a bit cleaner than even the first code snippet we started with.

Since this takes a FrameworkElement, it's WPF specific. It'd be easy enough to change the type to work with WinForms, if needed. The same technique could be used to handle other things where a state needs to be set to one value and then reset when some unit of work is done. For example, if using TreeViews with BeginUpdate/EndUpdate pairs.

Hope this helps someone.
using System;
using System.Windows;
using System.Windows.Input;

namespace CursorResourceProtection
{
    public class ChangeCursor : IDisposable
    {
        private FrameworkElement Context { get; set; }
        private bool Disposed { get; set; }
        private Cursor OriginalCursor { get; set; }

        public ChangeCursor(FrameworkElement context, Cursor newCursor)
        {
            Disposed = false;
            Context = context;
            OriginalCursor = context.Cursor;
            context.Cursor = newCursor;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if(Disposed)
                return;

            Context.Cursor = OriginalCursor;
            Disposed = true;
        }

        ~ChangeCursor()
        {
            Dispose(false);
        }
    }
}

Friday, December 3, 2010

DRY vs KISS

Two developers are playing poker. The chips are all on the table and it's time to show their hands. One throws down the DRY hand. The other throws down KISS. Which hand wins? Who gets to take the pot home?

There are many guidelines in software development. These are two prominent ones: DRY and KISS. For those who haven't heard of them, DRY stands for Don't Repeat Yourself and KISS stands for Keep It Simple, Stupid.

The underlying principle behind DRY is that there should be one authoritative source for any artifact in a piece of software. This can take different forms depending on the context. One example might be a constant literal. If a literal, for example a numeric value or a string value, exists more than one place in a program, it's a bad thing. The duplication should be removed and replaced with a named constant. The constant becomes the authoritative source for the value. This also has the side effect of making the software more readable if a good name is chosen because the meaning can be conveyed, not just the value. Another example is duplicated code. If lines of code are copied and pasted, there becomes more than one authority for the code's behavior. Instead, those duplicated lines should be put in a function that can be called from the various places the behavior is needed.

The KISS principle is based on the idea that complexity makes code that's hard to understand, maintain and debug. Code that is hard to understand will have more bugs in it to begin with and take longer to get working properly. It will also be harder for the person who has to maintain it to make changes and hence will increase the cost of ownership over the lifetime of the product.

On the surface, I think most developers will agree that both these principles are good. However, I think there is disagreement upon which one trumps the other.

An argument could be made that removing duplication increases complexity. In the examples for DRY above, adding a function or constant declaration adds indirection. As you read the code, the value is not immediately obvious and the behavior is not readily apparent. You have to go somewhere or use some feature in the IDE to find the value or determine what the routine does. In addition to readability, as you write, you have extra work to make a separate function. It is much faster to simply copy what you need and paste it somewhere else.

I understand these arguments. I know first hand the temptation to grab a section of code and paste it somewhere else. I know the pain of slowing down and having to think deeply about how to not make the duplicate copy of the code. Given all that...

DRY trumps KISS every time.

When I look at the long term maintainability, having one place where behavior or values or anything else is defined is always the better thing. I've experienced first hand maintenance of code with high levels of duplication. I have made changes in one place without knowing about the duplication and not also fixing the same code elsewhere. I have seen others do the same thing. The testing and validation in these scenarios can get very painful. When maintaining software and making changes, dealing with a single authority is much more accurate and faster, even with increased indirection.

In addition to long term maintainability when behavior should be changed, not repeating yourself reduces the chance of copy and paste errors. More times than I care to count, I've found bugs where a block of code was copied and minor changes made throughout it. Missing even one thing that should be changed will result in insidious bugs setting up residence in your application. Many times these won't be caught until much later in the product's life-cycle, increasing the cost of fixing them.

Just today I violated this principle... even after thinking "do I really want to do this?"... even with the draft of this article fresh in my mind... and I introduced a bug that took me a minute to figure out. I had these two lines:
const string name1 = "value one" ;
var value1 = !computeValueForName(name1);
That I duplicated and changed to this:
const string name2 = "value two" ;
var value2 = !computeValueForName(name1);
See the error? When I did, I promptly refactored this to:
var names = new [] { "value1" , "value2" };
var values = from n in names select !computeValueForName(n);
So, yeah, when I see violations of DRY I have almost a compulsive need to fix it. How about you?

Monday, November 15, 2010

Apple Raves

About two months ago I ranted about some issues I had with my new Apple MacBook Pro. For the most part, after additional time with the machine, they are all pretty much still valid. I'm still not used to the keyboard layout; I keep reaching for keys that don't exist. The menus at the top of the screen still escape me.[1] As for finding other machines on the network, that could be a bigger issue than it is for me. Once things are mapped, the O/S seems to do a decent job of finding them. As long as the network topology is stable, it's not a huge issue. It's simply an occasional annoyance rather than a day-in/day-out frustration. And finally, the stability isn't as bad as it first appeared. Now that things are setup and working, I haven't had any crashes or freezes. I don't think it's good as Windows or Linux, but it's not as bad as it first seemed.

With that recap and update of what I don't like, this article is about what I do like. And there is plenty.

Battery life

The battery life on this thing is superb. I haven't actually timed it or have any hard data, but seat of the pants performance feels as good as any laptop I've had with much bigger and heavier batteries. If I was a real road warrior, the lack of being able to change batteries might be a problem, but in the last 10-plus years of using a laptop, I've really only needed a backup set of batteries a couple times. For my uses, if it lasts a day of off-and-on use, it's good. And this has done that and then several hours of continuous use in the evenings. Perhaps one of the reasons the battery lasts so long is because of the next item...

Sleep/hibernate

I've never had a laptop that is so consistent in it's ability to go to sleep and wake up when needed. This issue has been one of the biggest ongoing technical flaws in all the other laptops I've had in the past. They were either slow enough at it or crashed regularly enough that I didn't use this feature very much. The Mac does it so smoothly and seamlessly that I do it quite frequently. This might be part of the reason my battery life is better: I'll close the lid and put it to sleep in cases where in the past I'd leave it on. For example, those times when I know I won't need it for five minutes but don't want to shutdown. I guess these periods of inactivity were using more battery than I gave them credit for and they added up so the difference is note-worthy.

Networking

Wow, what can I say about the networking connectivity. It just works. Flawlessly. Everytime. It finds and connects to networks easily and intuitively. Once I've connected to a network, it remembers it and reconnects again without hassle. I can be connected to one network, sleep the machine, go somewhere else with an already known network and begin working again as if nothing has changed. I never knew how much of a hassle network connectivity was until I didn't have the noise anymore.

Delightful surprises

I just noticed this the other day and it's an example of the subtle attention to detail that is throughout much of the system: the Finder's date column adjusts the format based on the width of the column. If the column is narrow, it shows mm/dd/yy. Widen it a bit and it shows mm/dd/yy hh:mm. Some more space and it starts using abbreviations. It continues giving more detail like this until everything is spelled out completely.

Summary

So, all in all, it's a really nice machine. It's not so much nicer I'd never own anything else and, as I mentioned, there are some real annoying "features" about it. On a scale of 1 to 10, I'd give it a good, solid 8. Fairly comparable to the other high-end Dell's I've had in the past.

1. Literally, they escape my notice; I simply don't see the menus up at the top of the main screen. I'll be working with a program wondering how to do something, looking around frustrated. And then, when I'm about to give up thinking the s/w is brain dead, I remember to look at the top. This is particularly pronounced when working with multiple monitors. The menu isn't even on the same screen as the application.

Thursday, September 9, 2010

Apple Rants

I first played with an Apple computer in the early '80s at a local computer store. My next experience was with a Macintosh an employer purchased to play on. Over the years, I've worked on mini-computers, S-100 based computers, PCs with various versions of DOS, Unix and Windows. Despite friendly jabs I may give friends, I don't really consider myself a computer or operating system bigot. I've watched the maturing of Apple computers from the side-lines, fairly impressed by the changes I've seen over the last 10 or so years. I have a number of friends who are Mac fans and have observed the improvements over their shoulders. I saw a lot of Apples as Windows machines at a recent Microsoft conference. More than once I've heard that the MacBook was the best Windows laptop around.

Given all this, when I recently needed to get a new computer I decided to take the plunge and get a MacBook Pro. I was pretty excited to get something so different than my usual fare. It arrived last week and I've spent the better part of the weekend and last couple days configuring it and a new Windows server I got at the same time. Overall, I really like it. The hardware design, the look and feel, the fit and finish are superb. It feels really solid. It feels like a BMW or Mercedes compared to the Dell's Chevy or Ford feel. As good as the hardware is, the operating system software doesn't seem to match up. The following paragraphs rant about some of the issues I have with it.

The biggest issue has to be the Copy/Cut/Paste key mappings. Why are they different than Windows and Linux? What was the reasoning that said they should do something different from the rest of the industry that has no real value? To be different? In my opinion, this is a major impediment to people new to OS X feeling comfortable with it. On SuperUser.com I did find a hint to be able to remap the keys, so they now work as I expect. I wonder though how many people just put up with it as frustrated users.[1]

The next issues seems like a huge anachronism. Circa 1985, before windowing PC operating systems had multi-tasking, each application took over the screen. In those days, putting the Menu bar at the top of screen made sense. However, as soon as you could have more than one application open at a time and visible on screen, basic user experience guidelines dictate the menu bar should be with the window it controls, not at the top of the screen. Given their big emphasis on design in some areas, why Apple thinks violating basic user design principles of keeping similar functions close to where they're used as it relates to the menu bar completely escapes me.[2]

Microsoft has used the SMB protocol for computer discovery and file sharing for a long time. It has become the defacto standard. I find it incredible that there is no way to browse the network and find computers dynamically on the Mac. It seems one can only connect to a networked computer if you already know the name. And to connect to it you have to use a fairly cryptic "smb://computer_name:139" syntax. Really? ... Really? Linux has "just worked" in this regard for many years. And it's worked overall better than Windows itself has. It's about time Apple caught up to the real world.

Finally, Snow Leopard just seems less stable than Linux and Windows have in a long time. Its stability feels like Windows did for the Windows 95 release. Several times in last couple days things have gotten wonky that were fixed by rebooting. A number of times when this happened, shutdown didn't work. It just hung after clearing the screen; I had to power down by holding the power button until it powered off. I can't remember the last time that happened on a Windows or Linux box.

Given all these rants, I don't want to give the impression I don't like my new machine. It is speedy. It is solid physically. And really, overall, I haven't had a ton of problems. Perhaps the problems I have had are more remarkable and obvious given the cleanness of the rest of the system. I'm not yet ready to do as some have and install something else as the base operating system and run OS X in a virtual machine.

2. See "The Structure Principle" at Principles of User Interface Design. Many people talk about this principle such as this one and this one.

Friday, August 14, 2009

How to display items from a collection in one line of a DataGrid

Typically, data structures map closely to their representation in the user interface and so most display widgets work pretty well in this situation. In WPF, DataContexts and bindings expect the relationship between their controls and the bound data to be fairly similar. Recently, I had a weird requirement that caused me trouble getting information on the screen due to a mismatch between the data model and the view.

Requirements

For good reasons, the data needed to be modeled in a master-detail relationship. For equally good reasons, the user wanted this displayed on a single line in a grid control. I believe the model to be correct; I'm not too sure about the user interface. I understand the user's reasons for wanting a single line, but I expect that over time and as new features are added, they will want a change in how things are presented. Regardless of what happens in the future, for today, this is the current requirement that I had to implement.

So, the data model looked something like this: 

And, with the assumption that there will not be more than one instance for any particular descendant type of TestItem in Property3, the goal was to have a screen that looked like this:

The problem

Setting up the data structures was no problem, nor was getting the master's data on the screen. I used a DataGrid from WPFTools and simple binding sufficed for Property1 and Property2. But when it came to PropertyA1 and PropertyB1 I ran into problems. Reading the documentation for binding paths, I found I could use the slash character to indicate items in a collection. Going down this trail, I tried setting the paths for the last two columns to Property3/PropertyA1 and Property3/PropertyB1. This sort of worked:
As shown above, the correct data is displayed, but only for the first item in the list. If the order of things in the list is changed, the data changes appropriately. Through the binding path, I could find no way to select different items from the list for different columns in the grid. Perhaps it can be done and I didn't find how, but understandably, this is an odd thing to try to do and it's not a surprise if the framework doesn't support it. (See CollectionBinding1 in the source code.)

Solution: IValueConverter

I thought about trying to put the data in the cells directly without binding and, while searching how to do this, was reminded of IValueConverter. From the examples, the standard way of using this is to simply convert between types or to control formatting. However, I realized I could create one that takes the entire list and pulls out from it a specific field.

First, I changed the binding for the two problematic columns to be just Property3. Then I created a new converter class for each property, and finally instantiated and assigned them to the columns' bindings. This resulted in a one-to-one relationship between converter classes and each property. The converters iterated the list until an entry of its expected type was found and then returned the field value it knew about. A converter for each property: ugly, but it worked! (See CollectionBinding2 in the source code.)

After proving the concept, I looked to clean it up a bit. The only differences between the classes was the type it was looking for and the property it returned. I realized these two things could be parameterized. I could change the converter to a generic class and then use the generic type in the loop. Also, I could pass a lambda expression to the constructor that would later be used in the loop to get the property value if the given type was found. I made these relatively minor changes, eliminating the multiple classes and making the strategy effective for my real world scenario. (See CollectionBinding3 in the source code.)

Final thoughts

Typically, converters are instantiated and referenced in the XAML code with just the implementation residing on the C# side. This works because the number of types are relatively small. My original implementation would probably work with this usage pattern, however, in the real world situation, with its one-to-one relationship between properties and converter classes, I would have an inordinate number of classes to have to manage. By moving the instantiation into C#, I can use a single class to handle the different types of objects in the list and the multiple properties in each type.

Source code for the three stages of development is available in a zip file here.

Any comments are welcome.

Thursday, November 6, 2008

Splash screens are evil! 8 ways to improve them.

Ok, perhaps evil is too strong a word, but ideally splash screens should not be needed. They represent a failure on the part of the development team to make an application that can load fast enough that the user isn't left wondering what happened when they double click its icon. The best case is to make the program load fast enough that it's not needed. As a developer, I realize minimizing application start-up time can be a really hard problem, possibly hard enough that it's not worth the resources to invest in this area of optimization.

Faced with this reality, here are some guidelines, splash screen etiquette if you will, to make it less obnoxious. These are things I've come up with as a user of many different software packages over the years within the context of having done a fair bit of reading in the area of user interaction and experience. I find it interesting that after a bit of searching on the topic, both on the web and in some dead-tree resources, I have found many people talking about splash screens' visual design but no one describing their functionality.

1. Not centered: that's where I'm working!

I typically have a minimum of three applications open. Quite frequently I have two or three times that number. When I start an application, the odds are I have something else I'm working on, and want to continue working on, while the new application is starting. The center of the screen is where my focus is normally going to be for those other applications. Therefore, the center of the screen is the worst place the splash screen can go. It's going to be right in the way of my doing anything else.

2. Not modal: I'm trying to do something else.

The splash screen should should not be system modal. I am working on something else while the new application tries to get going. There is no reason to think the splash screen is more important than what I'm working on. The splash screen should not ever cover up my current work.

3. Not focused: I'm not typing to you.

The starting application should not grab focus unless no other application has it. If another application has focus, it should maintain it. If I'm typing, I'm not typing into the not yet started application, I'm typing to the existing application. (Microsoft Office Outlook team, do you hear me?!?)

4. Not too big: you're not that important.

All the splash screen needs to do is tell me it's working. To do this it just needs a small, unobtrusive animation. I'm willing to give splash screens 5% of my screen. If it can't let me know it's there in a 300 x 300 pixel box, the designers need to rethink what they're trying to do. Ideally, I should be able to size it to the dimensions I want, including minimized.

5. Not fixed: I want that space.

Even when it's not centered, I should still be able to move it where I want it so it's out of the way. No matter where the designers set it by default, there is always going to be the case where, for someone, that location is in the way. Make the silly thing movable, like any other window on my system.

6. Not default: remember what I've told you.

After I've told you where and how big, remember it! Next time I start the application, odds are my system is going to be about the same configuration. I've gone through the hassle of moving it and sizing it; I shouldn't have to do it again tomorrow.

7. Not a non-task: be on the task bar.

The splash screen should cause a button to appear on the task bar; preferably the same button that will be used by the main form when it finally appears. This way, one of the sizes I can give it (see #4 above) is minimized. This allows me to know the application is starting without it having to take any of my precious screen space.

8. Not needed: delay initialization.

Finally, the ideal is to not need a splash screen at all. Consider making the main form visible immediately with things disabled. As modules are loaded and initialized, then build the form and enable the various areas for the user.