If you don't hear the siren, police are sure you'll feel the Rumbler
-
The Los Angeles Police department announced its intention to install the
low-frequency Rumbler siren into 20 black-and-white vehicles before a
larger exp...
Wednesday, October 06, 2010
Soothsaying based on spellchecker vocabularies
Outlook 2007 did not recognize "codemonkey". I thought this was bad news for Microsoft until my Android phone didn't recognize it either. I'm not in a position to check an Apple product just now. Nonetheless, I'm going to go on record (such as it is, in the blogosphere): whichever platform recognizes this word first will also dominate the mobile OS wars.
Thursday, September 23, 2010
Planning of costs that the customer can't see
A friend asked,
You know the joke that goes, "The first thing you need to know about recursion, is recursion"? The first thing you need to know about clear agile answers is that agile has no clear answers. Every answer is, "It depends." The rap is that you're making up as you go along, which is not really a fair summary; but it's also true in some ways and is the source of much of its value.
For me, what makes an agile solution agile, is rapid increments with honest re-evaluation, plus as much empirical evidence as can be gathered at low cost. It's the equivalent of numerical analysis through successive approximation.
Okay, I'm two paragraphs in and still haven't addressed the specifics. I've seen architectural overhead/engineering costs addressed several ways. AFAIK there's no general consensus. I don't have any personal preference.
1. Don't measure overhead at all. The point of doing stories with some sort of scoring system, is that you eventually get an approximate team velocity, which helps you predict what you can commit to and when you're behind. The overhead costs of refactoring, deployment, vacation, research, training, conferences, organizational reports/meetings, nosepicking, etc., will come out in the wash. This is why velocity is calculated on actual points delivered; the metric doesn't really care what impedes the delivery. It makes you very empirical, very quickly. The don't-measure approach works well when there's a fairly random distribution of overhead. It also has an enviably low cost of bookkeeping. The downside is, if things get bursty and you flop an iteration due to unusual overhead, there's not much paper trail for management. Usually depends on how much trust and track record you have.
2. Budget X items per iteration for overhead, where X is capped. This is sort of a service-level agreement approach. It acknowledges that devs never get as much time as they wish they could have to do things right. But, like an SLA, it also keeps them from starving. It won't work well if the dev's can't contain themselves, i.e, they "estimate" Y hours but invariably do every task to completion, regardless of budget. Also, there's a risk that the time taken to argue about what should be at the top of the dev list will eat up a significant portion of the budget. (Agile's not too hot, IMO, at dealing with lack of consensus, or any other issue that requires actual personnel management skills. It's an engineering practice that has a few social dimensions, but it doesn't really help you figure out what to do when teams are dysfunctional. Its main contribution on that front is that it will yield empirical evidence, fairly rapidly, that they ARE dysfunctional.) (It also doesn't dust your cubicles or clean little bits of food out of your keyboard. In other words, hard problems remain hard, and grunty problems remain grunty.)
3. Attach dev costs to customer-visible tasks. This doesn't always have sensible semantics. Deferred dev costs can get suddenly bursty and have their own crosscutting urgency ("the server has 4GB of disk left; avg response time has already increased by 60X and in 18 hours it will crash dead dead dead"). I'm told it works okay if you don't have deferred maintenance--but I've never worked on a project that didn't.
4. Let dev tasks compete straight up in the planning game (or whatever budgeting scheme you use) against customer-visible tasks. Maximal visibility, at the cost of added complexity to planning. Many non-dev stakeholders will just wish the dev costs would go away, and wonder (loudly) why devs don't just work dev magic and get everything instantly right. It's the most honest, empirical, manageable way to go, but it's vulnerable to a number of not-too-rational, impulsive responses and political infighting that developer-types are not usually good at winning.
Okay, I said I didn't have a preference, but the most sensible approach I've actually been a part of was a hybrid of 2 and 4. This was actually a Lean or Kanban kind of agile, where we organized work around queues that pulled tasks forward, from planning to work-in-progress to demo to deployed-and-done. Most of the dev effort was devoted to the mainline queue, but there were two auxiliary queues: one for pure dev tasks, and another for customer-support issues that we couldn't itemize at the beginning of the iteration, but based on experience, we knew were likely to crop up at some point mid-cycle. The overall experience of that scheme was not especially better than any other, but it did deal rather sensibly with overhead. Dev overhead and emergent customer-support tasks had enough visibility in the metrics that management could see how they impacted velocity. And, the advocates for any given task--both devs and the poor bastards who had customers waiting for them to return their calls--had some visibility into how much work had already happened per iteration on their queues, plus ready access to they pending queue so that they could quickly prioritize new items relative to old. (We kept tasks on 3x5 cards, in physical queues on a wall full of magnetic whiteboards.) The easy visibility had a rather natural self-governing effect toward the end of any iteration: people have a hard time standing up in the open, asking for the 13th special favor of the month.
We organize our work around stories, that are supposed to present a user requirement, and tech spikes, that we use to figure out how to do something. How do you get architecture/infrastructure work into a sprint? I mean things like "re-implement X using our nifty new architecture" or "set up a new server for QA"?
You know the joke that goes, "The first thing you need to know about recursion, is recursion"? The first thing you need to know about clear agile answers is that agile has no clear answers. Every answer is, "It depends." The rap is that you're making up as you go along, which is not really a fair summary; but it's also true in some ways and is the source of much of its value.
For me, what makes an agile solution agile, is rapid increments with honest re-evaluation, plus as much empirical evidence as can be gathered at low cost. It's the equivalent of numerical analysis through successive approximation.
Okay, I'm two paragraphs in and still haven't addressed the specifics. I've seen architectural overhead/engineering costs addressed several ways. AFAIK there's no general consensus. I don't have any personal preference.
1. Don't measure overhead at all. The point of doing stories with some sort of scoring system, is that you eventually get an approximate team velocity, which helps you predict what you can commit to and when you're behind. The overhead costs of refactoring, deployment, vacation, research, training, conferences, organizational reports/meetings, nosepicking, etc., will come out in the wash. This is why velocity is calculated on actual points delivered; the metric doesn't really care what impedes the delivery. It makes you very empirical, very quickly. The don't-measure approach works well when there's a fairly random distribution of overhead. It also has an enviably low cost of bookkeeping. The downside is, if things get bursty and you flop an iteration due to unusual overhead, there's not much paper trail for management. Usually depends on how much trust and track record you have.
2. Budget X items per iteration for overhead, where X is capped. This is sort of a service-level agreement approach. It acknowledges that devs never get as much time as they wish they could have to do things right. But, like an SLA, it also keeps them from starving. It won't work well if the dev's can't contain themselves, i.e, they "estimate" Y hours but invariably do every task to completion, regardless of budget. Also, there's a risk that the time taken to argue about what should be at the top of the dev list will eat up a significant portion of the budget. (Agile's not too hot, IMO, at dealing with lack of consensus, or any other issue that requires actual personnel management skills. It's an engineering practice that has a few social dimensions, but it doesn't really help you figure out what to do when teams are dysfunctional. Its main contribution on that front is that it will yield empirical evidence, fairly rapidly, that they ARE dysfunctional.) (It also doesn't dust your cubicles or clean little bits of food out of your keyboard. In other words, hard problems remain hard, and grunty problems remain grunty.)
3. Attach dev costs to customer-visible tasks. This doesn't always have sensible semantics. Deferred dev costs can get suddenly bursty and have their own crosscutting urgency ("the server has 4GB of disk left; avg response time has already increased by 60X and in 18 hours it will crash dead dead dead"). I'm told it works okay if you don't have deferred maintenance--but I've never worked on a project that didn't.
4. Let dev tasks compete straight up in the planning game (or whatever budgeting scheme you use) against customer-visible tasks. Maximal visibility, at the cost of added complexity to planning. Many non-dev stakeholders will just wish the dev costs would go away, and wonder (loudly) why devs don't just work dev magic and get everything instantly right. It's the most honest, empirical, manageable way to go, but it's vulnerable to a number of not-too-rational, impulsive responses and political infighting that developer-types are not usually good at winning.
Okay, I said I didn't have a preference, but the most sensible approach I've actually been a part of was a hybrid of 2 and 4. This was actually a Lean or Kanban kind of agile, where we organized work around queues that pulled tasks forward, from planning to work-in-progress to demo to deployed-and-done. Most of the dev effort was devoted to the mainline queue, but there were two auxiliary queues: one for pure dev tasks, and another for customer-support issues that we couldn't itemize at the beginning of the iteration, but based on experience, we knew were likely to crop up at some point mid-cycle. The overall experience of that scheme was not especially better than any other, but it did deal rather sensibly with overhead. Dev overhead and emergent customer-support tasks had enough visibility in the metrics that management could see how they impacted velocity. And, the advocates for any given task--both devs and the poor bastards who had customers waiting for them to return their calls--had some visibility into how much work had already happened per iteration on their queues, plus ready access to they pending queue so that they could quickly prioritize new items relative to old. (We kept tasks on 3x5 cards, in physical queues on a wall full of magnetic whiteboards.) The easy visibility had a rather natural self-governing effect toward the end of any iteration: people have a hard time standing up in the open, asking for the 13th special favor of the month.
Friday, July 02, 2010
ViewModel in .NET
[Changed very little from a sizeable post to PADNUG today:]
For observable objects like view models, I usually have a base class
that provides INotifyPropertyChanged and IDisposable. Change-tracked
properties are held in a PropertyBag, which is a souped-up Dictionary
that maps properties to backing values. It detects changes, so can invoke PropertyChanged intelligently.
Indeed, if you want to get elaborate, and are comfortable with generics, there's quite a bit that the base class can do for you. A nice pattern is
This lets your base ViewModel class know the type of its subclass. Once it has that, it can do slick things with lambdas, like
and
That's quite a mouthful, but when you use it, the generic parameters become implicit, so the syntax is just:
It's not quite as simple as automatic properties, but it's the same number of lines; you don't have to declare a backing variable for each property. And, you get change tracking, lazy loading, and INotifyPropertyChanged. It's (reasonably) safe from problems if you rename your properties, because the lambda are compile-time checked. I say "reasonably" safe b/c you can still screw it up if you do something like:
There's a dozen little tweaks you can do. For example, I've overloaded the Set() to accept a MethodBase, which allows the syntax
In other words, you never get copy and paste errors from the setter. 50% reduction in risk surface area.
Other things:
* Make PropertyBag smart enough to notice when it's got an IList<> or IEnumerable<>; in that case, the default values are empty collections, not null ones. For assemblies involve in UI, I've got an ObservablePropertyBag specialization that knows to initialize ObservableCollections, too.
* Give the base class two generic parameters: one for the concrete subclass, and one for an interface that the subclass implements. If you define the lambda expressions for Get() and Set() in terms of the interface, the lambdas in your properties won't compile until you put the properties on the interface. In other words, the compiler will force you to keep your interfaces up to date. It's not for everyone, but I figure if I'm going to work in a statically typed language (haven't moved to C#4 yet), I might as well make the compiler work for me.
* I don't show an example here, but since Set() returns a boolean indicating whether the value changed, you can call it as an argument to an if statement and do additional processing. Note that by the time Set() returns, the INotifyPropertyChanged event has been raised. If you want to do pre-processing before an event, you can register the pre-processor during construction. (That's kinda hacky; AFAIK, there's no contract that the framework will maintain the first-registered, first-notified order on event subscribers. But it's been true so far.)
Using generics this heavily isn't for everyone. My actual ViewModel base looks like
before you get to the opening bracket!
In sum, this can be a moderately deep topic if you want it to. I didn't even touch on keeping the PropertyBag threadsafe...
For observable objects like view models, I usually have a base class
that provides INotifyPropertyChanged and IDisposable. Change-tracked
properties are held in a PropertyBag, which is a souped-up Dictionary
that maps properties to backing values. It detects changes, so can invoke PropertyChanged intelligently.
Indeed, if you want to get elaborate, and are comfortable with generics, there's quite a bit that the base class can do for you. A nice pattern is
abstract class ViewModel<TViewModel> where TDerived : ViewModel<TViewModel>
{}
class ConcreteViewModel: ViewModel<ConcreteViewModel>
{}This lets your base ViewModel class know the type of its subclass. Once it has that, it can do slick things with lambdas, like
protected TProperty Get<TProperty>(Expression<Func<TViewModel, TProperty>> propertyLambda)
{
return mPropertyBag.Get(propertyLambda);
}and
// the return value is true iff the property changed
protected bool Set<TProperty>(Expression<Func<TViewModel, TProperty>> propertyLambda, TProperty value)
{
return mPropertyBag.Set(propertyLambda, value);
}That's quite a mouthful, but when you use it, the generic parameters become implicit, so the syntax is just:
public IValueConverter EventDateConverter
{
get { return Get(x => x.EventDateConverter); }
private set { Set(x => x.EventDateConverter, value); }
}It's not quite as simple as automatic properties, but it's the same number of lines; you don't have to declare a backing variable for each property. And, you get change tracking, lazy loading, and INotifyPropertyChanged. It's (reasonably) safe from problems if you rename your properties, because the lambda are compile-time checked. I say "reasonably" safe b/c you can still screw it up if you do something like:
public IValueConverter QuantityConverter
{
get { return Get(x => x.EventDateConverter); } // oops, now the lambda points to the wrong property
private set { Set(x => x.EventDateConverter, value); }
}There's a dozen little tweaks you can do. For example, I've overloaded the Set() to accept a MethodBase, which allows the syntax
public IValueConverter QuantityConverter
{
get { return Get(x => x.EventDateConverter); }
private set { Set(MethodBase.GetCurrentMethod(), value); }
}In other words, you never get copy and paste errors from the setter. 50% reduction in risk surface area.
Other things:
* Make PropertyBag smart enough to notice when it's got an IList<> or IEnumerable<>; in that case, the default values are empty collections, not null ones. For assemblies involve in UI, I've got an ObservablePropertyBag specialization that knows to initialize ObservableCollections, too.
* Give the base class two generic parameters: one for the concrete subclass, and one for an interface that the subclass implements. If you define the lambda expressions for Get() and Set() in terms of the interface, the lambdas in your properties won't compile until you put the properties on the interface. In other words, the compiler will force you to keep your interfaces up to date. It's not for everyone, but I figure if I'm going to work in a statically typed language (haven't moved to C#4 yet), I might as well make the compiler work for me.
* I don't show an example here, but since Set() returns a boolean indicating whether the value changed, you can call it as an argument to an if statement and do additional processing. Note that by the time Set() returns, the INotifyPropertyChanged event has been raised. If you want to do pre-processing before an event, you can register the pre-processor during construction. (That's kinda hacky; AFAIK, there's no contract that the framework will maintain the first-registered, first-notified order on event subscribers. But it's been true so far.)
Using generics this heavily isn't for everyone. My actual ViewModel base looks like
public abstract class ViewModelBase<TInstance, TViewModel, TView> : ViewModelBase, IViewModel<TViewModel, TView>
where TInstance : ViewModelBase<TInstance, TViewModel, TView>, TViewModel
where TViewModel : class, IViewModel<TViewModel, TView>
where TView : class, IView<TViewModel>before you get to the opening bracket!
In sum, this can be a moderately deep topic if you want it to. I didn't even touch on keeping the PropertyBag threadsafe...
Patenting business methods: Bilski v. Kappos
Just started following Stephen Forte when I ran into his take on the Supreme Court decision re business method patents.
> I could go and patent my implementation of Scrum since it is a business process and then turn around an sue all of you since I think you are using it.
This is a common misperception. There are some important hurdles to clear before you can patent something; they keep 99% (though clearly not all) of the frivolous stuff out. You can't hold a valid patent on something you didn't invent yourself (or in collaboration with all named inventors), and you have to conceive of it (and then claim it) before others had already begun practicing your invention. In fact, once you've been practicing your invention in public for a year, even YOU can't patent it. That's the US; in many countries, the moment you go public, you've lost your chance to patent.
Thus, even if you manage to find a Scrum style you can claim as yours, and patent it, and go to court, if the party you're suing demonstrates that they were already practicing your method before your "claim date", then not only do you lose the suit, but your patent gets invalidated. An invalid patent is worthless. You can't collect license fees on it, and you can't sue anyone else ever again with it.
So, there are some reasonable limits to the system, and that's one of my favorites. Every time you take your patent to court, there's a risk you might blow it up.
> [Bilski] did not invent anything, just a creative way to hedge commodities.
Well, the case turned on the fact that he did not invent any thing. Methods of doing things are entirely patentable, if they have a tangible output. The problem with a business method is that its components and output are too "meta": it's a way of organizing and running an abstraction (which is basically what a business, certainly a corporation, is). Bilski apparently had a new, useful, and original method, since all of those are required to obtain a patent; but there was no physical component, so it was not patentable.
Patent law is historically all about tangible products, or methods of doing things to tangible products. Software was considered unpatentable until someone hit on the idea of claiming them as instructions coded for a tangible machine to perform. In other words, you don't claim the algorithm; you claim the execution of the algorithm by a machine. Business methods are still trying to find their breakthrough angle into the realm of the patentable. The Bilski decision was a setback, and a moment of sanity, but it hasn't really settled much.
> I could go and patent my implementation of Scrum since it is a business process and then turn around an sue all of you since I think you are using it.
This is a common misperception. There are some important hurdles to clear before you can patent something; they keep 99% (though clearly not all) of the frivolous stuff out. You can't hold a valid patent on something you didn't invent yourself (or in collaboration with all named inventors), and you have to conceive of it (and then claim it) before others had already begun practicing your invention. In fact, once you've been practicing your invention in public for a year, even YOU can't patent it. That's the US; in many countries, the moment you go public, you've lost your chance to patent.
Thus, even if you manage to find a Scrum style you can claim as yours, and patent it, and go to court, if the party you're suing demonstrates that they were already practicing your method before your "claim date", then not only do you lose the suit, but your patent gets invalidated. An invalid patent is worthless. You can't collect license fees on it, and you can't sue anyone else ever again with it.
So, there are some reasonable limits to the system, and that's one of my favorites. Every time you take your patent to court, there's a risk you might blow it up.
> [Bilski] did not invent anything, just a creative way to hedge commodities.
Well, the case turned on the fact that he did not invent any thing. Methods of doing things are entirely patentable, if they have a tangible output. The problem with a business method is that its components and output are too "meta": it's a way of organizing and running an abstraction (which is basically what a business, certainly a corporation, is). Bilski apparently had a new, useful, and original method, since all of those are required to obtain a patent; but there was no physical component, so it was not patentable.
Patent law is historically all about tangible products, or methods of doing things to tangible products. Software was considered unpatentable until someone hit on the idea of claiming them as instructions coded for a tangible machine to perform. In other words, you don't claim the algorithm; you claim the execution of the algorithm by a machine. Business methods are still trying to find their breakthrough angle into the realm of the patentable. The Bilski decision was a setback, and a moment of sanity, but it hasn't really settled much.
Tuesday, April 13, 2010
My Biased Coin: What's the Co-Author Line?
My Biased Coin: What's the Co-Author Line?
An excellent post and excellent comments on Michael Mitzenmacher's blog. I replied and found I'd written so much I might as well blog. By now the topic is whether the identification of a "good" problem is a material contribution to its solution--originally, does a person deserve authorial credit for framing (but not providing) a solution? I'm riffing onto the notion of what a good problem is.
My wife did her graduate work in English literature at a school with a strong engineering program. She noticed a certain type of student every semester: undergrads, usually engineering or pre-med, who had registered for her literature course only to satisfy distributional requirements and were very smart, very diligent--but could not manage "interesting" ideas, no matter how hard they tried. She found this heartbreaking--especially the ones who thought that med schools would sneer at a B+. Kids would come to office hours and ask, sometimes in tears, what they can do to turn a logical, systematic, earnest, but dry B+ paper into an A. She'd explain that by the standards of her profession--literary criticism--that it's not enough to be thorough or precise or clear or even persuasive. If you can't pick a topic that a reader would find interesting, you haven't done all your work. In some sense, if criticism isn't interesting, if only to other critics, then it's not valuable.
Worse, a sense of the interesting is the last thing to fall into place. She could work with them on clarity, on use of evidence, on logical structure and rhetorical devices... and there were many kids who, over the course of a semester, could make great leaps forward in those areas. But the judgment of what a finding "meant", of how it contributed to the field, or how one idea seemed more central or intriguing or revealing than another, was too much. She suspected it was because they were excellent at grasping and re-creating rule-based outcomes, but she couldn't give a rule of thumb for what made something interesting.
Myself, I am conflicted about how to value interestingness. I have sympathy for the argument that it's fuzzy, subjective, and sometimes just a codeword for "conventional" or "mainstream" or, relatedly, in the mainstream of the latest fads and trends within the field. At the same time, I'm also moved by the argument that a profession, by definition, has standards, and that for the typical case there's a wisdom of crowds. If you show an idea to 10 researchers and none of them is intrigued, isn't there something we can conclude?
Put another way, as an empiricist, how can you possibly value interestingess? And as a curator of an intellectual discipline, how can you not?
An excellent post and excellent comments on Michael Mitzenmacher's blog. I replied and found I'd written so much I might as well blog. By now the topic is whether the identification of a "good" problem is a material contribution to its solution--originally, does a person deserve authorial credit for framing (but not providing) a solution? I'm riffing onto the notion of what a good problem is.
If you take the view that generating a good problem is a non-trivial contribution then isn't what happened to Michael akin to plagiarism?
My wife did her graduate work in English literature at a school with a strong engineering program. She noticed a certain type of student every semester: undergrads, usually engineering or pre-med, who had registered for her literature course only to satisfy distributional requirements and were very smart, very diligent--but could not manage "interesting" ideas, no matter how hard they tried. She found this heartbreaking--especially the ones who thought that med schools would sneer at a B+. Kids would come to office hours and ask, sometimes in tears, what they can do to turn a logical, systematic, earnest, but dry B+ paper into an A. She'd explain that by the standards of her profession--literary criticism--that it's not enough to be thorough or precise or clear or even persuasive. If you can't pick a topic that a reader would find interesting, you haven't done all your work. In some sense, if criticism isn't interesting, if only to other critics, then it's not valuable.
Worse, a sense of the interesting is the last thing to fall into place. She could work with them on clarity, on use of evidence, on logical structure and rhetorical devices... and there were many kids who, over the course of a semester, could make great leaps forward in those areas. But the judgment of what a finding "meant", of how it contributed to the field, or how one idea seemed more central or intriguing or revealing than another, was too much. She suspected it was because they were excellent at grasping and re-creating rule-based outcomes, but she couldn't give a rule of thumb for what made something interesting.
Myself, I am conflicted about how to value interestingness. I have sympathy for the argument that it's fuzzy, subjective, and sometimes just a codeword for "conventional" or "mainstream" or, relatedly, in the mainstream of the latest fads and trends within the field. At the same time, I'm also moved by the argument that a profession, by definition, has standards, and that for the typical case there's a wisdom of crowds. If you show an idea to 10 researchers and none of them is intrigued, isn't there something we can conclude?
Put another way, as an empiricist, how can you possibly value interestingess? And as a curator of an intellectual discipline, how can you not?
Tuesday, March 09, 2010
Pure WPF
This was prompted by a discussion on Padnug.
"Pure" is not a word I'd use often with regard to WPF. WPF rethinks many things, and not all of them have come into flower yet. Which is an optimist's way of saying, parts are missing today. To me, some of its big-picture rethinking has been biased toward massive empowerment of the developer, at the expense of off-the-shelf functionality. DIY over prefab. (I'm thinking especially of its debut without a DataGrid. In WPF you can write dazzling things, and when you know what you're doing the dazzle is just as easy or easier than WinForms... but you have to write them. The OOBE excitement is pretty sparse.) It's also been slow to build a comfort level in the dev community. To some, MVVM goes hand in hand with WPF, but I see senior developers still wary of MVVM or puzzled by it, and there are big areas where reasonable people disagree what it requires. [For example, the eventing between View and VM can be done in several ways, including at least two distinct patterns--classic .NET events vs routed events. Reactive.net (on its way to WPF) reworks the async pattern. Some people abstract the views in ways that the VM can manipulate; others are horrified by that. One's ideas about that are sometimes influence by whether you're using DI or not. In short, there's a fair amount of flux.] Junior devs, or old guard devs who aren't especially current, are mystified if not scared. Plus, of the total .NET workforce, there's more people on the web side than the desktop, I think--so lots of people who've stayed on the cutting edge of .NET as much as they've needed to, haven't touched WPF yet.
That's a long way of saying that to my mind, WPF feels too diffuse to be pure.
"Pure" is not a word I'd use often with regard to WPF. WPF rethinks many things, and not all of them have come into flower yet. Which is an optimist's way of saying, parts are missing today. To me, some of its big-picture rethinking has been biased toward massive empowerment of the developer, at the expense of off-the-shelf functionality. DIY over prefab. (I'm thinking especially of its debut without a DataGrid. In WPF you can write dazzling things, and when you know what you're doing the dazzle is just as easy or easier than WinForms... but you have to write them. The OOBE excitement is pretty sparse.) It's also been slow to build a comfort level in the dev community. To some, MVVM goes hand in hand with WPF, but I see senior developers still wary of MVVM or puzzled by it, and there are big areas where reasonable people disagree what it requires. [For example, the eventing between View and VM can be done in several ways, including at least two distinct patterns--classic .NET events vs routed events. Reactive.net (on its way to WPF) reworks the async pattern. Some people abstract the views in ways that the VM can manipulate; others are horrified by that. One's ideas about that are sometimes influence by whether you're using DI or not. In short, there's a fair amount of flux.] Junior devs, or old guard devs who aren't especially current, are mystified if not scared. Plus, of the total .NET workforce, there's more people on the web side than the desktop, I think--so lots of people who've stayed on the cutting edge of .NET as much as they've needed to, haven't touched WPF yet.
That's a long way of saying that to my mind, WPF feels too diffuse to be pure.
Tuesday, March 02, 2010
ViewModel rationale
Nikil Kothari had a great couple posts this week, notably this one.
He makes a good case for ViewModel, especially the idea that it's the next step up from codebehind. But there's more to be said. First off, UI is expensive, and not just mildly--it's basically as expensive as a software feature can be without being prohibitive (e.g., voice recognition). In my experience, whether on WinForms, HTML, Ajaxy and CSSed HTML, WPF, WebForms, or Silverlight--even my little tastes of Ruby on Rails--UI just takes developers longer to get a feature done-done. Often 4 or 5 times longer. There are some inherent and perhaps intractable reasons for this: UI is often what product owners feel most acutely, so there's lots of micromanaging, fiddling, and rework; the human eye is trained by evolution to absorb visual information quickly, with an especial emphasis on inconsistencies, so the tolerance for error is different; and everything in a UI tends to be intricately and sensitively connected to its neighbors, in time and in space, resulting in the wonderfully correct and illustrative metaphor of "the ripple effect".
There are also some regrettable reasons why UI is so hard: most notably that even the best tools, theories, and mindshare are still in their infancy. Many concepts that are getting some traction these days ("MVVM", "UX design") had effectively zero presence in commercial software even 15 years ago.
Since UI is expensive, a major trend among MV* patterns (MVC, MVP, MVVM, and other flavors of SupervisingController) is to make the UI dev burden as light as possible, and to provide more and framework/scaffolding that makes much of the plumbing just happen. The eventing and data binding in WPF and SL are important steps forward; so are codegen and reflection, which assist metaprogramming.
It's significant that ViewModel mindshare didn't really take off until the codebehind pattern matured a bit and there was framework support (primarily .NET) to knit the view's document-orientedness to its logic and state, as coded in... um, well, code.
I think the rise of CSS also played a crucial role, convincing millions of developers of the wisdom of separating visual markup from the containment tree--preferably in a reusable way that makes application-wide look-and-feel not only achievable but flexible and maintainable. CSS wasn't a step toward MVVM, but it cleared away some of the underbrush.
JavaScript is another factor that might have scared some devs straight, spending too much time repairing "clever" code integrated into a page.
So, some more drivers toward MVVM:
* stateless view --> one set of concerns (represention of state) out of the expensive UI
* passive view --> another set of concerns (choosing the next state, and transitioning to it) out of the expensive UI
* styles --> a third set of expensive concerns mitigated, at least partially. And MVVM handles most major tasks well, EXCEPT for styles, so it needed that task taken off the board
* scar tissue from browser scripting
* declarative code vs imperative/programmatic code, coexisting harmoniously via codebehind
* "conventions", base classes, and other forms of code leveraging/reuse that allow recurring problems to have recurring solutions, with minimal additional developer effort
He makes a good case for ViewModel, especially the idea that it's the next step up from codebehind. But there's more to be said. First off, UI is expensive, and not just mildly--it's basically as expensive as a software feature can be without being prohibitive (e.g., voice recognition). In my experience, whether on WinForms, HTML, Ajaxy and CSSed HTML, WPF, WebForms, or Silverlight--even my little tastes of Ruby on Rails--UI just takes developers longer to get a feature done-done. Often 4 or 5 times longer. There are some inherent and perhaps intractable reasons for this: UI is often what product owners feel most acutely, so there's lots of micromanaging, fiddling, and rework; the human eye is trained by evolution to absorb visual information quickly, with an especial emphasis on inconsistencies, so the tolerance for error is different; and everything in a UI tends to be intricately and sensitively connected to its neighbors, in time and in space, resulting in the wonderfully correct and illustrative metaphor of "the ripple effect".
There are also some regrettable reasons why UI is so hard: most notably that even the best tools, theories, and mindshare are still in their infancy. Many concepts that are getting some traction these days ("MVVM", "UX design") had effectively zero presence in commercial software even 15 years ago.
Since UI is expensive, a major trend among MV* patterns (MVC, MVP, MVVM, and other flavors of SupervisingController) is to make the UI dev burden as light as possible, and to provide more and framework/scaffolding that makes much of the plumbing just happen. The eventing and data binding in WPF and SL are important steps forward; so are codegen and reflection, which assist metaprogramming.
It's significant that ViewModel mindshare didn't really take off until the codebehind pattern matured a bit and there was framework support (primarily .NET) to knit the view's document-orientedness to its logic and state, as coded in... um, well, code.
I think the rise of CSS also played a crucial role, convincing millions of developers of the wisdom of separating visual markup from the containment tree--preferably in a reusable way that makes application-wide look-and-feel not only achievable but flexible and maintainable. CSS wasn't a step toward MVVM, but it cleared away some of the underbrush.
JavaScript is another factor that might have scared some devs straight, spending too much time repairing "clever" code integrated into a page.
So, some more drivers toward MVVM:
* stateless view --> one set of concerns (represention of state) out of the expensive UI
* passive view --> another set of concerns (choosing the next state, and transitioning to it) out of the expensive UI
* styles --> a third set of expensive concerns mitigated, at least partially. And MVVM handles most major tasks well, EXCEPT for styles, so it needed that task taken off the board
* scar tissue from browser scripting
* declarative code vs imperative/programmatic code, coexisting harmoniously via codebehind
* "conventions", base classes, and other forms of code leveraging/reuse that allow recurring problems to have recurring solutions, with minimal additional developer effort
Wednesday, January 27, 2010
Raising .NET events
This is a recycling of something I posted to Fabulous Adventures in Coding, in conversation with Pavel Minaev. Necessary background: the official .NET pattern for standard events (as opposed to, say, WPF routed events) recommends invoking them with a method along the lines of:
I thought of a few reasons for the "protected virtual OnFoo(FooArgs)" pattern. I can't come up with an aha moment, though.
There should be some way for a derived type to invoke its parent's event. That supports "protected" and the args.
There shouldn't be a way for nonderived types to invoke an event. That rules out "protected internal".
There shouldn't be a way for nonderived types to inspect the underlying delegate chain. Subscribers can put delegates to nonpublic methods in there; there's an expectation of privacy. That underscores why the backing delegate is private.
This is almost more of a mechanical problem than a logical one, but: there's a syntax problem in C#, at least--a logjam around accessibility. An event already has a modifier that is shorthand for its Add and Remove methods. How would we express accessibility of the event raiser, distinct from the accessibility of add/remove?
That covers everything but the reaons for "virtual". Leo mentioned the template method pattern. I think I'd call this a hook more than template--I think template implies both virtual and nonvirtual steps, where the base class performs the invariant steps nonvirtually. In this case, there is no invariant behavior, is there? Derived classes can suppress the actual raising of the event altogether. But the larger point stands: derived classes can decorate the base behavior.
If a derived class provides its own Add/Remove, it has to invoke its own local event; the base event is private. So there's an in-for-a-dime-in-for-a-dollar reason.
By making OnFoo virtual, you allow derived types to do a bit of covariance. Derived classes can read all the data from the FooArgs object and invoke an event that passes a SubFooArgs instead. It's cowboyish but possible. (I'm not coming up with a compelling example why you'd WANT to do this, but...)
Maybe this is a more realistic motivation: with a virtual OnFoo, you can precede (or simply replace) the base classes's event with a cancellable event of your own.
Okay. That's plenty of offtopic speculation from the likes of me. I'd still like to know if there's an aha-moment explanation, though. This is beginning to feel like an interview question...
protected virtual OnFoo(FooEventArgs e) {...}I thought of a few reasons for the "protected virtual OnFoo(FooArgs)" pattern. I can't come up with an aha moment, though.
There should be some way for a derived type to invoke its parent's event. That supports "protected" and the args.
There shouldn't be a way for nonderived types to invoke an event. That rules out "protected internal".
There shouldn't be a way for nonderived types to inspect the underlying delegate chain. Subscribers can put delegates to nonpublic methods in there; there's an expectation of privacy. That underscores why the backing delegate is private.
This is almost more of a mechanical problem than a logical one, but: there's a syntax problem in C#, at least--a logjam around accessibility. An event already has a modifier that is shorthand for its Add and Remove methods. How would we express accessibility of the event raiser, distinct from the accessibility of add/remove?
That covers everything but the reaons for "virtual". Leo mentioned the template method pattern. I think I'd call this a hook more than template--I think template implies both virtual and nonvirtual steps, where the base class performs the invariant steps nonvirtually. In this case, there is no invariant behavior, is there? Derived classes can suppress the actual raising of the event altogether. But the larger point stands: derived classes can decorate the base behavior.
If a derived class provides its own Add/Remove, it has to invoke its own local event; the base event is private. So there's an in-for-a-dime-in-for-a-dollar reason.
By making OnFoo virtual, you allow derived types to do a bit of covariance. Derived classes can read all the data from the FooArgs object and invoke an event that passes a SubFooArgs instead. It's cowboyish but possible. (I'm not coming up with a compelling example why you'd WANT to do this, but...)
Maybe this is a more realistic motivation: with a virtual OnFoo, you can precede (or simply replace) the base classes's event with a cancellable event of your own.
Okay. That's plenty of offtopic speculation from the likes of me. I'd still like to know if there's an aha-moment explanation, though. This is beginning to feel like an interview question...
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
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
I could use an abstract property:
But I'd still be stuck on how to map my child class's sole
So, when in need, inject a fix! (This is a more commendable motto in software design than in, say, intravenous drug use.)
Now any child type must provide a real (or at least non-null) value for ValueExtractor; otherwise it won't even instantiate.
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.
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".
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...
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.)
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:
Somewhere else are your helpful extensions:
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.
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
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
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?
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.
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.
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.)
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.
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.
Subscribe to:
Posts (Atom)