* Screen Count
Leads to the idea that Google.com can be replicated in 2 days if you can knock out 1 screen per day. Not all cases are Google, but seriously, estimation by screen count is a horrible idea.
* Number of Objects/Classes
For one, it implies you know the design up front, which as we know, we almost never do. This is especially true since I tend to be writing estimates during and/or prior even to doing requirements, and therefore, speculating what classes and objects we will have and estimating them is the pinnacle of silliness. Don't do it.
* Number of Database Tables
Like the above, but even worse, unless the app is total CRUD, in which case, you should be using MOSS/Infopath of some other generator technology.
At the last Chicago alt.net user group meeting, Bobby Norton* of ThoughtWorks moderated a fantastic discussion after his presentation on Cruise. I am told we will soon have video of this conversation, but the essence was that we all have estimation FAIL on our resume, and we need to get better at it. My big question, which is what I alluded to in a previous post, is that I am curious about how people actually do agile estimation. The whole idea finally clicked for me that has been around for awhile - estimate by user stories (think use cases, only different), assign "story points" for use case complexity, and if a use story is above a certain "story point" threshold, break down the story into something more manageable.
This is different than screens based estimation because IMO it does a better job of capturing the complexity of a screen when you are talking in user understood language. One screen may happen to be the place where a user will experience a great variety of stories. It also gets away from enumerating the design prematurely - as it states things from the perspective of the user, without trying to assume what artifacts are going to be developed to meet that complexity.
The real benefit, though, is on the measurement side. The key metric is how accuratley a given estimator can pin story points to complexity. Once you are storing information and graphing it - so you have some history about how much time goes into, say, an "Aaron Erickson story point" or a "Your Name Here story point", you get better at being able to predict what you can accomplish in a given time frame.
Is it perfect? No. But remember the word we are using here - that word being estimation. By continuously improving your estimates by using evidence of accuracy in the past to guide your future estimates - you do your client a great service. You have evidence you can base your estimates from, which in turn, gives you the real "predictability" you are looking for.
Evidence based estimation is where, I believe based on, well, evidence (HA!) the world is going.
* Apologies, got my thoughtworkers confused last time
A quick update of what I have going on for the speaking agenda.
* Michiana .NET Users Group, South Bend, IN, Aug 19th, "F#, The Business Case"
* Codeapalooza, Sept 6th, Chicago, IL, "Super-Optimized LINQ - Indexed Objects"
* ACM: Chicago Chapter, Sept 10th, Chicago, IL, "Microsoft's F# - Functional Programming meets the Mainstream Software Developer"
* Twin Cities Code Camp, Oct 11th, Minneapolis, MN, "The Intersection of F# and LINQ"
* VSLive Las Vegas, Week of Oct 12th-Oct 17th, Las Vegas, NV, "F#, The Business Case" and "Super-Optimized LINQ - Indexed Objects"
* Lehigh Valley .NET Users Group, Center Valley, PA, November 17th, "F#, The Business Case"
* Austin .NET Users Group, Austin, TX, December 8th, "Indexed LINQ"
Check this thread often, as schedules over this timeframe can change. As always, my favorite parts of being in this business is getting out and meeting people.
I am very pleased to announce that I am now officially writing a book, through Addison Wesley, about ins and outs of the technology consulting business. The best way to think of the book is as an operating manual for your career as a technology consultant.
My motivation for writing a book like this is, frankly, I want consultants to understand this business, so they can make better career decisions. Decisions about where you work (aka don't work for BOZO, FEAR, or other swindlers) - how you get paid, how clients select consultancies, how the sales process works, and really, what makes a place like Magenic, or any other consultancy, tick.
It is an ambitious effort, to be sure. And the schedule is aggressive. We are hoping to have a book out in stores mid-2009, which in book publishing, isn't that far away, given I need to have a manuscript done at the end of January.
Here is my current plan for my table of contents. Note that this is very tentative, but should give you a sense for what this is going to be about:
Chapter 1: Going to battle
Chapter 2: Why consulting?
Chapter 3: The consultancy taxonomy
BOZO
Consulting
Somewhat
bumbling and conservative, yet makes a practice of selling dollars for eighty
cents and expecting the consultants to pick up the slack. Nice people who, generally, are not going to
go very far or expand beyond their core market.
FEAR
Consulting
Manages
consultants by fear – uses tactics that Machiavelli would blush at to keep
consultants in line. Biology – that is –
bathroom breaks go on your time report.
You would leave, but your self-esteem is so low from working there, that
you don’t.
... and so forth, you have seen these entries before... look for a dozen or so more :)
Chapter 4: The secret guide to how geek
consultancies work
Chapter 5: Getting in – secrets to what
consulting firms look for
Chapter 6: What you need to ask before you
join
Chapter 7: Surviving
Chapter 8: Thriving
Chapter 9: Some Typical Career Arcs for
Technology Consultants
Chapter 10: The Payoff
Chapter 11: How to know it’s not for you
Chapter 12: Thoughts on Consulting from Real Consultants
Appendix A: A Consulting Lexicon
The deal is done - now the big task is actually writing about 11 more chapters, an appendix, and generally, making it worth your time to purchase and read. Now the hard part.. getting it all done and written! I will say that it is an honor among honors to get a chance to not only write a book, but to get to write one on a topic that I am this passionate about.
If you can't write a design until you write some code, how do agilists (or agilistas - you decide where you sit) - do estimation?
I am really curious. I have, and do, do the COCOMO thing, function points, and other techniques. Occasionally, if I think the app is CRUD enough, I go down to "screens" based estimation... but more or less, I am interested in the details that drive you to think "40 hours" versus "8 hours". And if you are doing agile and TDD, how you can ever come up with an estimate at all, at least before you write some tests which allow you to know... perhaps... what classes, and even more perhaps, what the FP of those classes will be, in your estimate.
I ask this not because I think estimation of effort up front is a good idea. Largely, I think, it is a guess that we do given the information we have at the time, which, more often than not, is usually insufficient. But every agilista is making a living, and if you are doing so, the people that, I dunno, pay you, are asking how long you think something will take, even before you have written the HOLY tests.
Just curious... cause I am stumped.
My friends and colleagues Chris Williams and Jason Bock - with the graphics/UX help of Anthony Handley - are putting on an event that can only qualify as EPIC.
No, its not yet another user group, code camp, or something like that. No, this one is strictly fun for charity - that is - Charity Fragathon.
If you can be in Minneapolis on September 24th, you should definitley go. If not, at least a donation will help. Magenic is matching the first 3K donated.
Some of my colleagues at Magenic, Justin Chase and Rocky Lhotka, have developed a very nifty framework for unit testing Silverlight apps - UnitDriven.
In particular, it is optimized for testing asynchronous code in Silverlight, which is virtually impossible with existing unit test frameworks - both from Microsoft and elsewhere. More details are available from the CodePlex site.
Video: What the F#
In this video from TechEd Online, recorded at Teched last month, Amanda Laucher (aka Pandamonial) and I talk about what F# is, why you should care, and why functional programming matters.
In an amazing coincidence, Amanda happened to have printed a F#TW t-shirt (i.e. F# For The Win, for those unaccustomed to the meme) - which is particularly ironic given that is an anagram of our interview :)
Chris has done the hard work of compiling a very
interesting interview series with some notable, not to mention
fairly obscure, people in the .net community. Definitely worth checking out to get a sense for who all those folks are that you meet at TechEd and similar events.
Scratching another itch, and after reading some feedback from mihailik on my previous post - I decided to implement some additional functionality in DuckCallLib to make it more useful. As before, the bits are available on codeplex.
So, again, with great fanfare, I introduce my first cut at an dynamic proxy mechanism that works generally for objects that leverages the duck typing mechanism we previously built. The purpose of this is to allow a consumer of an object to recognize when an object they don't control has certain behavior, and without having to implement a wrapper on your own, simply apply an interface to the object at runtime, whether it explicitly supports the interface or not.
Usage is generally as follows:
interface IEggable { string LayEgg(); }
class Platypus { public string LayEgg { return "egg"; } } //notice it does not implement IEggable
//we don't know for sure if a platypus can lay eggs, since we are dealing with it as an object, but we can try
object someObjectThatMightLayEggs = new Platypus();
var eggLayingPlatypus = someObjectThatMightLayEggs.As<IEggable>();
Assert.IsTrue(eggLayingPlatypus.LayEgg() == "egg");
Still a work in progress. I doubt I handle generics well, and I need to something other than crash on method missing, but the hardest part (for me) - generating the dynamic proxy that implements the interface dynamically using Reflection.Emit (ugh) is done.
Enjoy, and as always, feedback is appreciated.
Update, duh moment, I just realized I started to re-implement this (Jason Bock) and this (Castle Project). Ah well, if nothing else, going through creating one of these has given me a much better sense for how to do nifty stuff with Reflection.Emit.
Scratching an itch today, thinking about code I have written in the past to attempt to do duck calls in C# (that is, call a named method without explicitly knowing that it even supports the method) - I decided, what the heck, why not just write the extension method over object required to do duck calls.
So, with great fanfare (ha!) - I have published DuckCallLib on codeplex (codeplex.com/duckcalllib). This is hardly a big project, more like a handy piece of code that allows you to not have to dig through reflection yourself every time you need to handle a duck typing scenario from C# code.
Let say we have a simple class, such as this:
public class RandomClass
{
public int AddNumbers(int op1, int op2)
{
return (op1 + op2);
}
public double AddNumbers(double op1, double op2)
{
return (op1 + op2);
}
}
Now, lets say we want to call "AddNumbers" without knowing anything about RandomClass:
object rndClass = new RandomClass();
object two = rndClass.DuckCall("AddNumbers", new object[] { 1, 1 }, null);
Assert.IsTrue((int)two == 2);
Or, a more complex and meaningful scenario, we want try to make a call, but have a lambda get invoked if the method is missing:
Func<object,string,object[],object> methodMissingHandler =
(source, methodName, theParameters) =>
(decimal)theParameters[0] +
(decimal)theParameters[1];
object rndClass = new RandomClass();
object two = rndClass.DuckCall(
"AddNumbers",
new object[] { 1m, 1m },
methodMissingHandler );
Assert.IsTrue((decimal)two == 2m);
As you can see, ruby this isn't. It is not nearly as clean syntactically as I would like it to be. However, given the current limitations of the C# language, this is what I have been able to come up with. If anyone has other ideas, I certainly encourage anyone to send em my way.
Enjoy!
This Summer, I am very excited to be doing a couple talks on F# around the midwest.
On July 8th, I kick things off in Bloomington Illinois, where I will be covering the overview and the details about not only how to do useful things in F#, but why you should do useful things with F#. It is a talk that, I hope, gets people excited about functional programming in general, and F# in particular.
In August, I visit South Bend, Indiana, where I will hopefully reach another audience to again spread the good word about F#.
Then in early September, I come back to Chicago, where I will be doing a couple sessions at the upcoming Chicago Day of .NET (tentative title), one of which will be about F# :)
In all cases, if you can make it, I very much look forward to meeting you and having not only a talk, but ultimatley a dialog about what functional programming in general, and this language in particular, means to you as a software developer.
My talk last April on Business Intelligence is up on the Technology Executives Club website.
Business Intelligence continues to be an enterprise that, in my humble view, tends to be too tied to particular products, and not to specific domains. When people look for BI experts, they look to expertise with some variant of a tool, rather than expertise in a relevant domain. This, and the fact in general that BI is tightly coupled to persistence technology (i.e. databases) I believe is a barrier to doing effective BI, as when the limiting factor becomes technology expertise rather than domain expertise, it limits the talent pool greatly.
Similar to those who see SOA through the lens of product companies that push SOA solutions, rather than as a broader architectural concern that should be technology independent, it seems BI should be seen not in the lens of Oracle, Microsoft, or any other software vendor, but through a more outcome oriented lens. That is, BI solutions should be things that you buy to help you achieve particular functional goals (i.e. increase sales) - with BI technology competing on the basis for efficiency in enabling those goals.
Well, it's about time, but after a hiatus to work on implementing indexing in CSLA.net, I have provided some very badly needed updates to i4o.
Added are the following:
* POCO support
Indexable collections can be done over existing classes. Indexes are added using the AddIndex(string property) method, where by adding the index by naming the property, an index gets created for current items, and all future items. RemoveIndex(string property) is also added.
* Remove fixed
The remove method has been properly implemented.
* Unit test suite
A unit test suite that achieves over 90% code coverage has been added. Future development will be done via Red-->Green-->Refactor. :)
* VB String queries supported
An issue where VB queries that use strings were not being indexed due to VB replacing a standard string compare with it's own string comparison method call. That corner case is now handled.
As always, you can download the new bits by going to codeplex.com/i4o
After some flight delays and the normal fun one has while navigating airports, yours truly is back home.
Next on the agenda technology-wise is an refresh with a couple of minor bug fixes for i4o, as well as dynamic indexing capability. I found an issue with i4o in how it handles VB string comparisons and it not recognizing it can take advantage of the index on those (darned conversion of x == y to String.Compare(x,y)) - issue is resolved (had to for the demo) - but given I am already in there again, it is a good occasion to do some other updates as well that I have been putting off for too long.
As well, I am pleased to announce that myself and Amanda Laucher (aka Pandamonial) did a very fun video cast from the TechEd Fishbowl appropriately called "What the F#", that should be published soon and explains some of the reasons that developers and their bosses ought to be interested in this new, exciting technology coming from Microsoft (link will be forthcoming when they publish it).
All in all, an amazing experience as usual.
P.S. If you are ever at Universal Studio, the Simpsons Ride is a must see.
Spent some time at the C# booth, managed to catch Hanselman's talk on MVC, caught David Platt's "Why Software Sucks" talk, which was pretty neat and engaging. The latter was interesting for me as I have been of the same opinion for some time, especially since the reason that it often does is related to very poor user interaction design.
Which really gets me to the biggest development, in my view, that has occurred with .NET this year. No, it's not LINQ, it's not EF, and it's not even F# (that will be next year :p) It is WPF and Silverlight finally giving control of the UI to a user experience person. Platt's talk, which reminds us that people use software as a means to an end, not as the end in itself, reminds you that yes, you need to really think hard about how usable your application is. In the end, unless you are writing Lord of the Rings Online or World of Warcraft, most people want to spend as little time in your application as possible.
A lot of corporate software, frankly, goes unused. And a big reason is that there is a lot of really unusable corporate software (not to mention "shelfware" commercial software). Providing good UX is a critical factor to actually realizing your technology investment. The days where UX is considered "extra fluff" are long gone.