Tuesday, December 15, 2009

Inheritance pattern: contract via constructor

In C# and the C-ish object oriented languages, if you want a family of types to implement a property, with each implementation particularized to each type (i.e., you care that everyone implements it, but you don't want one implementation cascaded to all), the big two techniques get lots of press: object inheritance from an abstract base and interface implementation. Here's another technique that's unsurprising when you think about it, but I've never seen it discussed as such: I'll call it contract via constructor. It's a little more stringent than the two classic approaches, since a subclass can't dodge the contract (in C#, at compile time, anyway) by implementing the required property as
throw new NotImplementedException();
And, it's feasible for a non-abstract class.

The idea is for a base class to require a value via its constructor(s) rather than requiring it via abstract property. Obviously, this is not universally advisable. But I find I have at least one rather substantial object hierarcy in most apps: say, one for persistable objects, maybe another for DTOs, and if a UI is involved, often several flavors of controls or containers, plus architectural base types if we're doing MVVM or such. Often, there's something I'd like to code out once, in a base class, with slight variations for each leaf. There's usually a generic type parameter or two that expresses the type-specific variations, but sometimes there's additional metadata, staticly known to each leaf but not knowable in the general case up at the base. It's the sort of thing where a VB programmer would write an enum into the base class and ride to putative glory on a switch statement. Not so great for framework programming or for, really, any code that shouldn't make you want to fire someone.

In the few hours since I really noticed this and have been salting it around my current project before deciding to blog it, contract via constructor is particularly useful if the property you seek is metadata about each subtype, e.g., so that you can handle it universally in the base type.

For example, suppose I want to specialize IntBindingPair into a family of types, each associated with an IEntity<int>. (An IEntity<int> here is a persistable object with an int primary key, and a string property suitable for display. The "binding pair", therefore, is basically a key/value pair for UI binding.) My base class's constructor takes an int and a string. I want each new subtype to be constructable from just the IEntity reference, so I need each subtype to specify how to choose its string value. (No, it's not time to override ToString(). Go sit in the corner.)

I could use an abstract property:

public abstract Func<TEntity, string> ValueExtractor { get; }

But I'd still be stuck on how to map my child class's sole IEntity argument to my base class's int and string; the instance property isn't available to be used in constructor args, for obvious reasons.

So, when in need, inject a fix! (This is a more commendable motto in software design than in, say, intravenous drug use.)


public abstract class IntBindingPair<TEntity> : IntBindingPair
  where TEntity : class, IEntity<int>
{
  protected IntBindingPair(TEntity entity, Func<TEntity, string> valueExtractor)
    : base(entity.PrimaryKey1, valueExtractor.Invoke(entity))
  {
    ValueExtractor = valueExtractor;
  }

  public Func<TEntity, string> ValueExtractor { get; private set; }
}


Now any child type must provide a real (or at least non-null) value for ValueExtractor; otherwise it won't even instantiate.

public class FooDisplay : IntBindingPair<IFoo>
{
  public FooDisplay(IFoo foo)
    : base(foo, f => f.Bar)
  {}
}
public interface IFoo : IEntity<int>
{
  string Bar { get; }
}


This same syntax solves another, possibly more general problem: how to transform constructor signatures from child types to suit the requirements of a base type.

Wednesday, October 28, 2009

Law of Grammarian Outrage

Much as Godwin's Law predicts the eventual invocation of Hitler in any sufficiently long internet discussion, I'd like to propose an axiom in the same sociological vein. There is a correlation between A, the number of commenting readers of a blog that are of an analytical (not to say hairsplitting) bent, and B, the likelihood that any blog post that mentions "beg the question" will get more responses to this controversial point of usage than to the original intended topic. (A for analytical, B for beg.) I'd say that on average, you need about 3 such readers for a 50% likelihood and perhaps 6 for 95%.

Relatedly, the number of grammarian posts is probably big omega of n^2, where n is the number of such readers: each such reader tends to respond to every other at least once. This far outstrips the usual number, which is, what, n log n, maybe? That is, the rate of response per reader would be log n. Or perhaps it would be "blog n".

Wednesday, August 19, 2009

App vs framework design

Another rebroadcast, this time of a response to Eric Gunnerson on differences between app and framework design.

Good post. I think your distinction between designing framework APIs versus wholly-owned application code is important. Not sure what Peter Ritchie is trying to get at by disagreeing; the differences between API and application design are so large that I'm inclined to say that anyone who disagrees has never designed an API that got released into the wild and made it to v2.

One of the few .NET books worth having as a physical book, IMO, is the "Framework Design Guidelines" by Cwalina, Abrams, et al. As good as it is, though, it's very much tuned to fx level (and is very frank about that; note the title). I've had several discussion with devs who've read that and think it's scripture for app design. Most recently, I had someone tell me that we shouldn't use underscores or case-sensitivity as part our C# naming conventions for nonpublic members, because the book cautions against language specific names b/c there are .NET languages that are case-insensitive or that may not have the same support for underscores. Of course, this guy also thought FxCop was the universal standard, too. I asked him why they didn't just name it FxPope and remove the ability to turn rules off. I'm glad not to work there anymore...

Wednesday, July 22, 2009

The Uncle Who Won't Shut Up

Following is a rebroadcast of my comment on Hanselman's blog.

Looking forward to hearing Uncle Bob again. I find him very insightful on coding issues, less so on community issues like how software developers should carry themselves, envision the job, etc. Then there's his politics, which I only mention because it is a large fraction of his tweets (i.e., he mentions it first and puts it in the public sphere). The farther he gets away from technical questions and the closer to sociological theories, he gets less empirical and more loopy. Worse, he also gets more strident, or at least no less so.

I guess he's not the first geek to go a little crackpot when outside his tech strengths. Noam Chomsky, anyone?

Anyway, here's a few questions I'd like someone to ask him. Maybe in part 4?

1. He's pretty big on craftsmanship lately. For the most part, the lesson of history has been, when craftspersons compete with engineering (i.e., industrial processes and capitalist management), the craftspersons get crushed. ("Outcompeted.") The industrial products are more reliable, they scale better, they don't have single-source dependency risks, etc.--and having scaled, their unit cost is cheaper. The "craftsmen" he mythologizes never got around to looking at their products that way; instead, they sat around, pretty happy with themselves, their traditions, and their traditional notions of "quality" and "reliability" until engineers came along and ate their lunch. The engineers innovated, while the "craftsmen" celebrated the past. Given the lessons of history, therefore, why on earth would we want to emulate craftsmen? Or does the "craftsmanship" vision only work for boutique shops, authors, and consultants?

2. He seems pretty ignorant of history with his "professionalism" speeches, too. Strictly speaking, a profession is something that is licensed by the state: doctor, lawyer, even plumber, and (notably) every sort of engineer except software engineer. A profession usually has generations of lore and experience behind it, and a core association (the AMA, the state bars, etc) that maintains "professional standards" and a code of ethics. Thus, in general, an industry has to be a couple generations old AND coalesced around a consensus set of practices before it can even THINK about becoming a profession. (Indeed, that's why the phrase "world's oldest profession" is actually quite a bit funnier, in a dry way, than most people realize today, now that the modern usage of "professional" has stretched to mean "white collar" and/or "not qualifying for amateur status".) I'm pretty sure that if Uncle Bob thought about it, he wouldn't want the government or anybody else telling him who's qualified to write software, or what his ethics should be. Ergo, either he hasn't thought about it, or he doesn't understand the connotations of the words he uses. Either way, he sounds unconvincing.

3. From what I can gather in his tweets and blogs, he's emphatically against not only health care reform, but regulation of the health sector in most any form. I'd love for you, Scott, to ask him how an unregulated insurance market would serve insulin-dependent diabetics, or anyone else who's acutely or chronically dependent on medical treatment. I'd love for you to look him in the eye and ask him what carrier would cover you, and whether you'd ever be able to work for a company smaller than Microsoft and still have coverage. (Of course, maybe you'd rather not entangle your blog and podcasts with that much off-topic drama. It would be quite professional of you, so to speak, to avoid it. But I have several close relatives with diabetes and other health issues, so I'm pretty tired of Uncle Bob's free ride. If he wants to evangelize ideas that would have awful human consequences, I think people should stand up. Your decision is yours, of course.)

Monday, July 13, 2009

INotifyPropertyChanged, C# lambdas, MethodBase.GetCurrentMethod()

I'm on a WPF project at the moment, and Silverlight before that. Both have this notion of INotifyPropertyChanged for bindings, whose only requirement is that you implement
event System.ComponentModel.PropertyChangedEventHandler PropertyChanged
and fire it off whenever any of your properties changes. So far so simple.

The downside is, the PropertyChangedEventArgs payload is not just a typewashed object, it's merely a string of the name of your property, so you see a lot of

public Foo Bar
{
get { return _bar; }
set
{
_bar = value;
OnNotifyPropertyChanged("Bar");
}
}

which works dandy until you rename something or forget to update your copy-and-paste. ReSharper will look in your literals for you, but I'm usually too impatient and sloppy to trust that.

Instead, I've been on a kick to use lambdas and MethodBase.GetCurrentMethod().

First you need a base class like ViewModelBase. Add the following:





   1:   

   2:          protected bool Set<TProperty>(Expression<Func<TViewModelInterface, TProperty>> expression, TProperty newValue)

   3:          {

   4:              TProperty oldValue = _propertyBag.Get(expression);

   5:              string propertyName = expression.GetPropertyName();

   6:              return SetObservable(oldValue, newValue, t => _propertyBag.Set(expression, t), propertyName);

   7:          }

   8:   

   9:          protected bool Set<TProperty>(MethodBase setter, TProperty newValue)

  10:          {

  11:              TProperty oldValue = _propertyBag.Get<TProperty>(setter);

  12:              string propertyName = setter.GetPropertyName();

  13:              return SetObservable(oldValue, newValue, t => _propertyBag.Set(setter, t), propertyName);

  14:          }

  15:   

  16:          private bool SetObservable<T>(T oldValue, T newValue, Action<T> updater, string propertyName)

  17:          {

  18:              bool changed = HasChanged(oldValue, newValue);

  19:              if (changed)

  20:              {

  21:                  updater.Invoke(newValue);

  22:                  // don't fire property change until oldValue is updated

  23:                  OnPropertyChanged(propertyName);

  24:              }

  25:              return changed;

  26:          }

  27:   

  28:          private static bool HasChanged<T>(T oldValue, T newValue)

  29:          {

  30:              bool changed;

  31:              if (ReferenceEquals(null, oldValue))

  32:              {

  33:                  changed = !ReferenceEquals(null, newValue);

  34:              }

  35:              else

  36:              {

  37:                  changed = !oldValue.Equals(newValue);

  38:              }

  39:              return changed;

  40:          }



Somewhere else are your helpful extensions:



   1:   

   2:          public const string GetterPrefix = "get_";

   3:          public const string SetterPrefix = "set_";

   4:          private static readonly int _prefixLength = GetterPrefix.Length;

   5:          

   6:          public static IList<Type> GetInheritedInterfaces(this Type type)

   7:          {

   8:              IList<Type> direct = type.GetInterfaces();

   9:              IList<Type> results = direct;

  10:              foreach (Type implemented in direct)

  11:              {

  12:                  results = results.Union(implemented.GetInheritedInterfaces()).ToList();

  13:              }

  14:              return results;

  15:          }

  16:   

  17:          public static string GetPropertyName<TInstance, TProperty>(this Expression<Func<TInstance, TProperty>> expression)

  18:          {

  19:              return ReflectionHelper.GetProperty(expression).Name;

  20:          }

  21:   

  22:          public static string GetPropertyName(this MethodBase method)

  23:          {

  24:              if (method.Name.StartsWith(GetterPrefix)

  25:                  || method.Name.StartsWith(SetterPrefix))

  26:              {

  27:                  return method.Name.Substring(_prefixLength);

  28:              }

  29:              throw new ArgumentException("Method was neither a setter or a getter.", "method");

  30:          }



where ReflectionHelper is basically lifted wholesale from Fluent NHibernate under BSD. It's not rocket science, though, just some manipulation of C# expression trees to extract the name of a property from a lambda that uses it.

Also, _propertyBag is basically a Dictionary where the strings are the names of the properties. Actually it's a Dictionary to keep some other stuff like original values, dirty bits, etc., but that's another topic.

The implementation of Get is like Set, only simpler.

The net-net of all this is that you can have

interface IMyClass
{
Foo Bar { get; set; }
}

class MyClass
{
public Foo Bar
{
get { return Get(x => x.Bar); }
set { Set(MethodBase.GetCurrentMethod(), value); }
}
}

which is fewer lines, no backing variable (e.g, _bar), and ReSharper-izable. Plus it breaks at compile time until you expose Bar on your interface, so it's as close to idiotproof as I've been able to get so far.


Against software "craftsmanship"

Lots of talk on web lately, esp from Object Mentor types like Uncle Bob and Michael Feathers, about the need for software developers to be more like craftsmen. This is true in small ways, I suppose, but it also seems false in large ones.

The decline of craftsmen, when possible, has usually been industrialization. One can get into frets about alienation of workers from their product, and in fact I usually agree or at least learn from such Marxist critiques. The moral core of those arguments, though, is the degree to which workers are left without meaningful tasks, in the aftermath of initial industrialization. That's a valid point when it applies, but it goes too far when you're just talking about how a software developer who's a dev today, and will be a dev tomorrow, should work.

So I don't think industrialization is evil or without useful lessons in this context. Mostly I think it's an important turning point in technical practices, a sort of coming of age. An inflection point, to use the modern parlance.

Back to software as craft: one of the revolutionaries of the Industrial Revolution was Eli Whitney, he of the interchangeable part. He famously figured out that an army could fight better if its rifles were each made from a finite number of said parts which could be carried into battle, pre-fabricated, rather than requiring a slew of blacksmiths and metallurgists to repair everything on demand. Or, more chronologically, he figured out that this was a better way to make a rifle, then he made a fortune selling rifles of that description to the U.S. Army, because the Army realized he was so, so right.

From interchangeable parts, computer scientists later borrowed the metaphor of subassemblies and, more broadly, decomposition. It's a natural enough idea mathematically, but making it intuitively clear to beginners almost always involves some example from the physical world--especially, the manufactured world.

From decomposition, we get the encapsulated object and the component. From these, we got to the unit test.

Would the craftsman have invented the unit test? To me, the answer is tautologically no. To break a task into subsitutable, commodity parts is, by definition, anti-craft. It is industrial. It is engineering. It's applying arguments (or motivation) of scale; ideas of aggregate, statistical value; perspective at the macro, systemic level; appreciate for complexity, emergent behavior, and the like. By definition, craft appreciates fuzzy essences, "things in themselves," metaphysics rather than physics. Those essences, those things, those human endeavors are valuable, but they are not engineering. I'd argue that the products they produce are not reliable in the way that an industrial product is, and therefore, that software developers should not be craftsmen.

Software needs ideas from the 21st century; the 19th already played out, and the craftsmen lost.

Postscript: Is it me, or is Uncle Bob's software advice, at least as it involves the community of developers (as opposed to pure technical practices like SOLID) getting progressively more hidebound, verging on counterrevolutionary and possibly trending toward stupid?

Monday, June 15, 2009

Odd final sentence in Fowler on UI Architecture

Fowler's overview of UI architectures is pretty much the standard article on the subject. I stumbled on it most recently when MSDN linked there from its Prism docs.

The final sentence has an odd little error, though--odd because this is an important sentence in a widely read article, and the error is quite apparent. The sentence reads, "Mappings will tend to be smaller for Supervising Controller than for Presentation Model as even complex updates will be determined by the Presentation Model and mapped, while a Supervising Controller will manipulate the widgets for complex cases without any mapping involved." (emphasis mine)

Clearly, the highlighted word should have been "simple". The Presentation Model is a stricter mediator of updates than the Supervising Controller is.

I suppose one could make the case that final sentences are so often overwrought, to the point of emptiness, that nobody really reads them anymore. But am I really the first person to be anal enough to notice this? Or is Fowler simply too busy to deal with web errata?

Like many motorists' failures to use turn signals, or the paving of our sidewalks with chewing gum and cigarette butts, overwrought final sentences are yet another symptom of the inexorable collapse of civilization as we know it, or would have known it, had we survived.

Thursday, June 11, 2009

WinMerge in VS2008

James Manning has an MSDN post for VS2005 that still helps when configuring alternative merge and compare tools.

Sunday, May 31, 2009

Silverlight.FX 2.1 navigation

Honestly, I'm torn between loving the declarative emphasis of Silverlight.FX--expressive, implementation-agnostic, terse--and recoiling in horror from how much it depends on string literals for commanding and now addressing/navigation. Also of concern, the MVC stuff follows ASP.MVC's conventions that make type name and file location semantically significant. (E.g., to have a Product controller, you need a type named ProductController in your /Controllers directory. Urgh.) There's a point at which convention-over-configuration strays into anarchy, and I think the ASP.NET pattern has passed it.

Granted, Silverlight is tangled up with xaml and must remain so, if only so it can roundtrip through Blend until something better comes along. This keeps its content quite close to text. And, maybe my love of Resharper has addicted me to static typing to an unhealthy degree, to the point that I want everything reflectable and typed, and I want it yesterday. But am I wrong to be creeped out by the strings? What makes this palatable? Is the theory: "It's acceptably safe to use strings for bindings, so long as they are sufficiently prominent, because their prominence implies that they are unlikely to fail without someone noticing?" (Much as many teams don't unit-test UI's, because the cost of high-fidelity testing is high, and manual testing gives it "enough" coverage.)

I don't get it.

Of course, xaml strings are not always strings. You can do some nifty things with type converters. But then again, type converters are a form of imperative code that's sufficiently subtle to let you THINK you're declarative and whatnot, when in fact you're nearly as entangled with imperative implementations as you ever were. Indeed, ever since a serendipitous typo, I refer to them as "type coverters".

And really, to the extent that they seem "nifty", most things you do with type converters seem so only because there isn't more elegant support in xaml for polymorphism. A richer language would erase (or at least subsume them) in a righteous flash of holy fire.

Monday, May 11, 2009

Uncle Bob, professional opinionator

Uncle Bob is back to his version of talk-radio for the blogosphere. Kernels of truth, whole gallons of certainty.

It's remarkable how many people get into definitional tugs-of-war over "professionalism" without citing the original, technical (if you will) meaning of professional.

Classically, if your vocation doesn't have an professional organization, government licensing requirements, and a code of professional ethics, among other things, you're not a professional. Plumbers are; coders aren't.

In my favorite clarifying example, there's a deep undertone of dry humor to the phrase "oldest profession", probably lost on most people today.

Thus, in the classical sense, anyway, an appeal for professionalism is an appeal to become establishment, institutional, blessed by the powers that be. Culturally (though perhaps not politically) it's conservative. I don't know that Uncle Bob intends this, but if so, it's seems to me this is not what Agile needs.

Craftsmanship, yes; ethics, of course; Marick's Artisanal Retro-Futurism x Team-Scale Anarcho-Syndicalism, very possibly. Speechifying and invective... no thanks.

(Note that I haven't read his actual keynote. Perhaps the speechifying is less in the speech than in the blog.)

Friday, April 10, 2009

Obsolete attribute in .NET

More from the note-to-self category: the [Obsolete] attribute generates compile-time warnings (or errors) but is not enforced by the framework at runtime. This is pretty obvious when you realize its purpose (backwards compatibility that warns but does not break) but spooked one of my coworkers.

Tuesday, March 10, 2009

Bulk unblock in Vista

Vista's UAC suspicion of downloaded code (and other files) manifests itself as a warning on each such file, cropping up when you open them. I usually see this when I download sample code, open the VS .sln, and collapse under the slew of warning windows.

Ideally, my antivirus software would have a setting to remove these values after a successful scan, or at least prompt me. It doesn't.

The fix, like so many fixes, comes from SysInternals. The underlying problem is that the downloaded files have been associated in NTFS's mind with the "main unnamed data stream". Si's streams utility strips off this association, and will do it recursively:

streams -s -d .

The "." for current directory is necessary.

I must have Googled and re-learned this a dozen times.