Wednesday, June 20, 2007

Context Switching...

A small conversation struck up at the office today, ironically in the middle of the morning, about Context Switching, and the effect on develoepers.

I recalled an old post from Johanna Rothman on this topic and looked it up. It's here (be sure to read the comments too).

It's kind of related to the post I did a few days back about developers taking support calls.

And there are heaps of others having their input:
  • As usual, Joel has something sensible to say on this here and here.
  • This one sparked a bit of discussion
  • And here's a pretty simplistic example that is referenced in some of the above posts.
So what's the right answer - especially in a small company with just 3 developers, 1 and 1/2 support people - you just can't help it. There is lots of work to be done, at the same time.

My current solution, as manager who has to do development work as well, is to delegate the longer term, complex development issues, remain as interruptable as I can to "shield" developers.

A scenario that puts a hole through this though, is when our support staff have to where other hats, and get out on site - leaving us short staffed back at the office, or during update times (once every quarter) when technical support is in demand - my solution - sacrifice one developer for a predefined time...at least we put all our interrutions into one basket.

Wednesday, June 13, 2007

Sub-pixel rendering

It's amazing what science goes into things you take for granted. Here's (www.grc.com) an great explanation of sub-pixel rendering and an insight into the techniques used to display characters and graphics...discovered from a link in this Joel post.

Thursday, June 07, 2007

abstract vs virtual

How's the confusion between whether to make functions in a class that is intended to be inherited, abstract or virtual.

I don't pretend to know the answer, so I "Googled". Here's a discussion I found...

It seems, while there are different opinions (how I'm not sure), that abtracts must be overrideen, but virtuals can be overridden.

Well, I have a base class (a form) doing a fair amount of standard work, and part of that standard work is to call two functions that must be overriddem by the child (descendant) form.

So, do I make them Virtual, or Abstract. Well it does in fact seem true, that if you are going to implement Abstract methods, the class must in fact be marked as abstract. But that's ok right? I can still mark my class as abstract, and implement the standard code I wish to, then mark the couple of methods I need the descendant to override, as abstract. (Big bonus here, the code won't comile if those methods aren't overridden, which is great because code in the base for call is, and relies on it.)

So then, I added a virtual method to my base form. It had to be filled in (i.e. it needed a body, unlike an abstract class, otherwise it won't comile). Good. Also, the code compiles fine when it is not overridden - I assume now, that unless it is overridden by a descendant form, the bahaviour defined in that base class, applies.

So here's my summary for now;
In a class intended as a base class...
  • Use private properties and methods where you want to contain functionality to the base class and hide it.
  • Use "virtual" methods if you want to define default behaviour that can be changed by descendants.
  • Use "abstract" methods if you want to force descendants to take some responsibility (if only it were this easy with our kids...now there's an idea for another post - until you're 18 years old, your "GetMoney() function is virtual - override it if you like but if not, it falls back to your parents, after that, it becomes abstract - you have to implement it yourself - some geek humour there). The catch with abstracts is, the entire class must then be marked as abstract and cannot be implement directly. This makes sense of course, because the very act of including an abstract method and calling it from code in your base class, means you are counting on it being inherited.

Thanks to this post for clearing it up in my head...

=================
Another valid point is made here, that "base" classes can call virtual methods, and use the default behaviouir, but if they are overridden by a child object, the code in the original base class, will still reference the overridden virtual method (in the child object's code) unless the "new" keyword is used in the definition within the child object. (Some code examples maybe useful, but I don't have time, and there's heaps of them everywhere else - follow some of these links for just Google "abstract vs virtual".

Wednesday, June 06, 2007

ReadOnly collections with Generics

Use ReadOnlyCollection<> instead of List<>

Thanks to here

It's in the System.Collections.ObjectModel namespace.

Tuesday, June 05, 2007

Developers doing support...Waste of time or not...

I work for a VERY small company developing software for the building industry. My main role is to lead a small team of developers (3) to continually roll out product enhancements (we aim for quarterly) and fixes. As luck would have it.we are also undertaking a major .Net rewrite at the moment...

Couple all this with, as anyone who works in a company of six people would know, you end up wearing a lot of other hats.

One hat, that is of particular annoyance to most developers, is the customer support hat. Now our developers are shielded from answering customer calls directly, by two others - a general manager who plays a major role in customer support, and a salesman, who handles support calls in his spare time.

To say we are undermanned in the support area is probably fair, and as soon as we can afford to do something about that we will. The basic goal here is to have the 3 developers and long term employee (business analyst) handle second tier support while two others handle the front lines.

Anyway, as I mentioned this doesn't always work. It only takes one of the front liners to be out of the office, say, actually selling the $10,000 a pop software and that front line work quickly falls to developers.

Now a ringing telephone and a customer who "Can't print their favourite report" or "doesn't understand the difference between a left and right click" is probably the single biggest (and damaging) distraction to a developer trying to get his head around C#'s implementation of Generics, or designing an Object model for Custom Business Entities that correctly reflects our problem domain - but what do you do?

As their "team leader" (with an Agile slant on things) I'm all for shielding them from all this, and removing all the barriers if possible. But I'm also for getting paid! Annual support fees make up a decent wack of our income and therefore customers must be made to feel loved when they ring with any problem, whether or not we can in fact help them.

Today, I received a call from a customer who'd just purchased a new printer. (There annual support is due in a couple of months.) Now, within the first mintue or so of this call I could tell there was some problem with the printer driver - this problem was nothing to do with our software. The problem was they'd already been on to HP about it. The rudimentary test they'd tried with Word, worked, so they'd (HP) washed their hands of it - "it's software".

Now we are not in a position to throw that one back in our customer's face - "sorry, it's HP's problem" is not going to cut it. We need that $1000 support in a few months more than HP need a happy "Ma and Pa" company, using one of their all in one printer/fax/scanners, in country NSW. So what do I do. I run through enough diagnositc type exercises on the phone, to convince myself of my earlier expectations, then run with, "email me a sample of what it's doing and also some details of the printer's settings".

Meanwhile I consult the great "Google". About the 15th hit on my obscure search for the product model and "printable area" found a review that mentioned how the new "double sided option", dramatically reduces the printable area. I quickly replied to the email they'd sent along the lines of, "there are known problems with double sided printing...try turning it off" - Presto. Reports print. A few more trees die - we have a happy customer, who will now pay that $1000 in a few months.

So, have I made the problem worse or better? Now we have a happy customer, who is far more likely to pay that support invoice, but far more reliant on us to fix anything "computer" at their office. But, there are posts everywhere that will point out just how much time I've wasted (more than the 1/2 hour it took for this to transpire). So I've earnt the company $1000 it may not have otherwise got (and maybe more over coming years when taking into account future years and good word of mouth). But, I've wasted time, and started down a slippery slope - it this continues to happen, just how many 1/2 hours (or more) will I blow? And also , what choice do I have? Don't support them and slowly go out of business. Support them, and keep making that grab for the $1000 rather than undertaking work with much greater long term profitability by building a far greater product that can bring in tens of thousands - not much use if the company has gone right?

So, this is just a conundrum facing such a micro-business. But I feel one thing is certain - we have to treat the customers well. Without them we don't even have a micro-comapny. If we can keep taking these small steps, eventually we'll become a "not-so-micro" company, and we'll have happy customers, and that will means we'll become a "even-more-not-so-micro" (maybe even just small), then not-so-small, then maybe medium! But we won't do it, by letting people down...

BTW - in that email reponse to our customer, I gave them a bit of ammunition to go back to HP with - at least for an update to the driver.

Many thanks to http://www.zdnet.com.au/reviews/hardware/printersscanners/soa/HP-OfficeJet-7410/0,139023422,139176157,00.htm

Covariance

Last night I tripped on something that after a little bit of Googling, I discovered was quite a trap for young players in the OOP / C# development arena...covariance.

This occurs when you build a nice little hierarchy of objects, with a base and several child objects then try to introduce Generics into the equation.

So I have a BaseEntity, and a class that exposes a collection of BaseEntity thusly;

public List MyList
{
... etc...
}

then, you try to cast a List set up like this...

private List myChildList = goGetAChildList();

It doesn't compile.

This is because casting the List, is not like casting the individual objects.

The point of this really hit home when it was described is that, if casting in this way was allowed, you could add objects of all different but inherited types, to your Base List.

Anyway, this post isn't meant to comprehensively explain the issue of co-variance, justremind me that it exists, and point me on to here...