November 2004 - Posts

The problem with annual performance reviews

Esther Derby has a great post on an alternative to the yearly performance review.

She also gives a great suggestion for dealing with what most employees want out of a review, money. I'm sure if it wasn't for the salary tie-in, employees would revolt at the notion of going though the typical annual review.

I wonder what would happen if salaries were treated like mortgages and you could choose a base salary plus a fixed annual increase, say 2% or an adjustable rate salary, say median salary + 5%.

Ken Auer of RoleModel Software told me once about the system he uses at his company. New hires can choose to have a market rate salary and minimal/no bonuses or a low salary and a proportionate percentage of revenue sharing. So a programmer could sign on for a $90,000/year salary with no bonuses or a $30,000/year salary + 10% of annual profits.

The only issue I have with either of these systems is that the rest of your life dictates which of these is acceptable, and some people will need to switch at some point. Allowing people to renegotiate their employment agreement would allow that, but doing it to often leads to people speculating on the business climate. I'm not sure if this is good or bad for the employee, but I can see it being an administrative and budgeting challenge for the employer.

Has anyone participated in a salary scheme such as these? How did it work and what did you like and dislike about it?

Posted by Wayne Allen | 6 comment(s)
Filed under:

Where Do I Put The Logon Code?

Given that you have a dialog that is used to collect user credentials, where should the code that actually checks the credentials go? I have been given answers such as:

  1. In the OnClick of the OK button
  2. A private method of the dialog
  3. In the code that opened the dialog
  4. In a separate class that is neither the dialog nor the code that opened the dialog.

Lets look at each of these options.

Option 1: In the OnClick of the OK button

This is probably the most common place to find the credential check logic. Unless you are writing throw away code this is also one of the worst places to put it. Most likely the code shows up here because our visual IDEs make it easy for us to put it there. And until you run into problems you don't have anything to worry about. What kind of problems? How about testing? With the code located in the event handler you have to either test manually or simulate the event with some kind of GUI test package such as Rational Robot. Also you've mixed your UI validation logic with your credential check logic. A better approach would be to separate the two.

Option 2: A private method of the dialog

This is a little better, but not much. You've separated out the credential check logic, but it is still hard to test. Maybe we should just let the dialog be responsible for the user interaction.

Option 3: In the code that opened the dialog

So now we've moved the code out of the UI and into the workflow. This is getting better, but how are we going to test the credential check logic without testing all of the workflow logic as well?

Option 4: In a separate class that is neither the dialog nor the code that opened the dialog

Now we're cooking with gas! I can test the credential check logic by itself without having any other code running. The code is highly cohesive and loosely coupled. Even better would be to provide the workflow component with parameters that are the components for obtaining the credentials and validating the credentials. An even further refinement would be to create interfaces that represented these services so that your workflow would still be valid even if the credential store is moved from SQL to Active Directory, or the credentials are provided as command line parameters, in a config file or come from the Windows identity.

Anyone have any other options that would be better?

Posted by Wayne Allen | 1 comment(s)
Filed under:

The Difference Between Class & Instance Members

Recently I've run across several instances of confusion regarding class and instance members.

Typically I get a question like "I defined a new method in my class, but the compiler complains when I try to call it. Why?" The code usually looks something like this (C#):

public class MyApp
{
private static int Main(string[] args)
{
int x = foo();
}






private int foo()
{
return
1;
}
}

If you have been around OOP for a while the problem is obvious, however, to others the mystery static doesn't mean a lot.

Class Members

Here's what is going on. The C#/C++/Java keyword static ("shared" in VB.NET) tells the compiler that this method (Main) belongs to the class (or type) not to the instance of the class. Another way of looking at this is that you don't have to create an instance of the object to use a class (static) method. Since the Main method doesn't have an instance associated with it, it cannot refer to any members that aren't also class members. Since foo() isn't declared static, Main can't see it. In C# the static keyword can be applied to fields, methods, properties, operators, events and constructors, but cannot be used with indexers, destructors, or types.

As a programmer you access class members by pre-pending the class name to the member, i.e. Class.Member, rather than the typical object variable i.e. object.Member.

Class members play a large role in most modern frameworks and are typically used for creating other objects such as:

int i = int.Parse("1");

Another common usage of class members is getting access to a singleton such as the UTF8 encoding:

string result = Encoding.UTF8.GetString(buffer);

The last need for statics is getting access to things not under the control of the framework, typically the operating system or external libraries since they don't have an object oriented approach.

int t = Environment.TickCount;

Instance Members

Since foo() isn't declared static it is an instance member by default (no keyword for non-static). Instance members must have an object instance otherwise they don't exist. To further confuse the issue foo() can see Main() and can call it without specifically indicating the class that Main() belongs to since it is defined in the same class. I.e. the following is valid:

private int foo()
{
        Main(new string[0]);
        return 1;
}

But the following is not:

private int foo()
{
        MyApp app = new MyApp();
        app.Main();
        return 1;
}

Because Main() is not a part of the instance of MyApp.

Summary

To summarize, class members are defined as belonging to the class and only to the class. Instance members belong to an instance of a class. Class members are essentially the globals of object oriented programming and caution should be exercise in the creation of them for the same reasons we know to avoid globals.

Posted by Wayne Allen | 2 comment(s)
Filed under:

The Insanity of Management Foot Dragging

An organization I once worked for had hired a CIO/VP of Engineering who played nice for about 3 months before showing his true colors. 15 months later after firing 25% of his staff (one at a time, not as a group) alienating the departments and causing another 25% to seek alternate employment he is finally asked to "resign". The remaining staff had an interesting reaction - as a group they celebrated his resignation the same day it was announced. Knowing what a dark cloud this person cast on the entire organization, why did the management team wait so long and waste do much employee potential putting up with this individual?

I expect it is the same mentality that prevents us from canceling obviously failing projects - somehow we expect that if we just wait long enough things will somehow start to get better - until we're finally faced with the awful truth.

Is there some cure for this particular for of insanity or are we doomed to live with these kinds of things forever?

 

Posted by Wayne Allen | 3 comment(s)
Filed under:

Ben Hyde goes wonky

Ben Hyde posted about wanting the blue states to secede. Besides being a childish reaction to losing did he ever consider that most of the blue states voted in the 40% range for Bush and vice versa? Who's going to secede from who?

Why do those left of center have this huge overreaction when they loose the presdency lately? Do you remember all the Hollywood stars who were going to leave the country when Bush won in 2000?

Don't just whine, get involved (and I don't mean join the lawyers at the ACLU).

 

Posted by Wayne Allen | 3 comment(s)
Filed under:

Dan Appleman goes wonky

Dan posted about the elections and gave us advice to go join the ACLU because they protect everyone's rights (unless you're conservative). And yes I am proud to have Bush represent my party.

As to looking forward to business as usual, what does he think would be different if Sen. Kerry had been elected? Quoting the tired left mantra of increased debt, the poor environment, big corporations etc. isn't useful since it arguably isn't true. Kerry with a republican congress would have gotten so much accomplished.

Posted by Wayne Allen | 5 comment(s)
Filed under:

Election Day - Enblogment

Dave Winer has a interesting idea he is calling enblogment. Here is my choice.

Whatever your choice, exercise your opinion and go vote!

Posted by Wayne Allen | with no comments
Filed under:

StringBuilder.Equals

Interesting note: StringBuilder instances are only considered equal if Capacity, MaxCapacity and the string value are all the same. I guess it makes sense in a way, but it means I can't do a if (a == b) check because who knows what could have changed Capacity or MaxCapacity. So rather I have to do a if (a.ToString() == b.ToString())instead - messy.

Since StringBuilder is supposed to be a mutable string I would expect to be able to do comparisons on it like a string and not have internal state not related to the actual value of the object play a role.

Posted by Wayne Allen | with no comments
Filed under:

Angle brackets must go away

I was talking with Scott Hanselman (gratuitous name drop) about the difference between rpc and document style. It took me a moment since I don't deal with SOAP internals much any more. It occurred to me shortly thereafter that I don't really care other than I have a bias towards document style.

My take is that the angle brackets need to go away from the average developer's day to day experience. I've had a similar argument with cohort Scott Came over how much developers should really know about XML. He says everyone should know and understand the details of infoset and schema, where I just see this stuff as file formats. Angle brackets are already starting to go away as the various tools are coming of age. XML is a great file format and will exist for many years to come, but I don't expect to read it on a day to day basis any more than I expect to pop open my favorite word processor and start typing RTF control words.

Posted by Wayne Allen | 1 comment(s)
Filed under:
More Posts