CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Eric Wise

Business & .NET

December 2005 - Posts

  • Interesting Question

    So a contact of mine through this blog commented on the success of Codebetter today with our nice new visual appeal and ever increasing subscriber and visitor ratios.  He also followed up with a probing question on what we will be up to in the future.  The answer of course is to stay focused on quality content since that is what got us to where we are today and we are always looking to increase our readership.

    Interestingly enough this person asked whether we had considered doing some for profit activities like collaberating on a book, software, services, etc.  It's probably news to most of you readers out there but we have discussed this line of thought as a group before, and had collectively decided to focus on what we do best which is blogging what we hope is useful information to our readers.

    Still though, this question nags at my mind... Are we missing out on something special here?  Would CodeBetter branded products and services draw a high demand?  Could we all retire at 40?  (Except Sahil, because he's already 225 yrs old, filled with piss and vinegar)  Ah the MBA in me, always looking at potential opportunities.  =)

  • "Coding to Interfaces"

    Here's something I see time and time again from new entrants to the OO world in .NET.  If you want to make your code more stable, reliable, and extensible in certain aspects of enterprise systems you must embrace the concepts of coding to interfaces, not inheritance to keep yourself from digging into a nightmare down the road.  To better explain what I'm talking about, here's a very simple example to help show the concept:

    Let's say you have a system with a method that performs a calculation.  What the calculation is doesn't really matter, it could be a sales tax calc, or anything really.  The important point is that currently your company supports this calculation in Ohio.  So let's make a theoretical function that takes two double inputs and in Ohio the rules are that they should be added together.  So we end up with this in our Ohio calculations class:

        Public Function myCalc(ByVal x As Double, ByVal y As Double) As Double

            Return x + y

        End Function

    Now this is all well and good, but then the company expands into Michigan.  Luckily, Michigan handles this calculation the same way Ohio does.  So being a good little developer we decide to promote myCalc to an inheritable.

    Public MustInherit Class Calculations

        Public Function myCalc(ByVal x As Double, ByVal y As Double) As Double

            Return x + y

        End Function

    End Class

    Wonderful, now the ohio and michigan classes can inherit from this file and both of them can share the code.  Everything is lovely and grand and we all pat ourselves on the back for not having written the code in two places!

    However, our celebration is interrupted when the company again grows and moves into Indiana.  Indiana rules say that x + y is totally bogus, and it needs to be x * y.  Now we have a couple options:

    1. Start messing with our inheritance chain to try to override this function.
    2. Start putting conditional logic and edit the signature to take in state
    3. Code to an interface!

    Numbers 1 and 2 have some pretty critical flaws.  When you start messing with the inheritence chain and putting in conditional logic you run the risk of breaking existing functionality and in the case of the signature edit we now have to modify all the consumers of our inheritable.  This doesn't seem so bad on this small scale, but imagine if you had all 50 states and each one had a different way of performing this calculation?  This is where coding to interfaces saves your butt!  What we want to ensure is that we encapsulate our differing logic in such a way that when a change or addition occurs we do not have to modify our existing, working code base at all.

    How do we do this?  We take advantage of the power of inheritance and interfaces.  First we need an interface to enforce the method and an inheritable class that can hold a pointer to our interface.  Like so:

    Public MustInherit Class StateStuff

        Protected calcs As ICalculations

    End Class

     

    Public Interface ICalculations

        Function myCalc(ByVal x As Double, ByVal y As Double) As Double

    End Interface

    So now we have required that every state can hold an ICalculation, the implementation of which we can define at will.  Now we need a couple classes that implement the interface that hold the differing logic.  Per our story above we have addition and multiplication.  So we'll do something like this:

    Public Class AdditionCalculation

        Implements ICalculations

     

        Public Function myCalc(ByVal x As Double, ByVal y As Double) As Double Implements ICalculations.myCalc

            Return x + y

        End Function

    End Class

     

    Public Class MultiplicationCalculation

        Implements ICalculations

     

        Public Function myCalc(ByVal x As Double, ByVal y As Double) As Double Implements ICalculations.myCalc

            Return x * y

        End Function

    End Class

    Now for the states.  Per our story above we have 3 states and 2 cases, one case is addition and one is multiplication.  Therefore we can go a couple routes.  One route is to make the various states have their own classes.  This has the downside of creating a lot of classes, but ends up being fairly clean if there are a lot of differences between states.  In the constructor of the state class we will set the ICaculation that state should use like so:

    Public Class OhioStuff

        Inherits StateStuff

     

        Public Sub New()

            calcs = New AdditionCalculation

        End Sub

    End Class

     

    Public Class IndianaStuff

        Inherits StateStuff

     

        Public Sub New()

            calcs = New MultiplicationCalculation

        End Sub

    End Class

    Notice how our constructor properly lets the type of calculation that should be performed.  All we would need to expose this to the system is an accessor method!  Even more powerful, we can now create methods elsewhere in the system that take in the generic StateStuff as a parameter, and inside that method we can call calcs.myCalc and it will always perform the proper calculation regardless of what state is in use.  No conditional logic needed!  That's flexibility!  In addition, we can guarantee that if we add new types of calculations, like subtraction, and new states that the changes will never break existing code!

     

    The second way to approach this from the end class model is to have one generic class and a factory that assigns the various interface classes based on whatever conditional logic you have.  The factory method would look something like this:

    Public Class StateStuff

        Public calcs As ICalculations

     

    End Class

     

    Public Class StateFactory

        Public Shared Function GetState(ByVal stateName As String) As StateStuff

            Dim s As New StateStuff

     

            Select Case stateName

                Case "OH" Or "MI"

                    s.calcs = New AdditionCalculation

                Case "IN"

                    s.calcs = New MultiplicationCalculation

            End Select

     

            Return s

        End Function

    End Class

    So at the end of the call you get a state class with its custom calculation implementation.  A new state or interface class would require editing the factory, but all the other code should be unchanged and protected from breakage!

  • GPA as a hiring metric

    Someone from the Joel forums asked how useful GPA is as a hiring metric for developers.  I was interested enough that I decided to blog my response:

    I had my first hiring company request a transcript, once I had > 1 yr experience no one has ever asked again.  It does make sense that companies are more interested in what you can do, versus what classes you took in college.

    What do good grades tell you?

    1. You show up to class (meet committments and deadlines)
    2. You can follow directions.
    3. You can adapt to the style of a teacher/boss/peer.

    What don't grades tell you?

    1. Whether you'll actually be a good programmer, since only a small % of your degree is related to coding.  In my Information Systems degree I think I took a total of 20 credit hours out of 134 that were actually programming and relational database related.  The rest of the coursework was Accounting, Finance, Marketing, Management, and electives like European History and Multicultural Literature.  This is why I personally ask for their core gpa and their overall.  If someone got straight A's in computer stuff but C's in electives, I really don't care about those C's.

    2. Whether you're a creative problem solver.  Most A's at the undergrad level are just regurgitation with very little original thought.

    3. Whether you're a team player or good culture match.


    Overall, grades are a marginally useful filter for entry level positions.  Certainly programming is a mixture of science and art, and depending on the type of your applications coursework will be more or less important.  There are tons of examples of poor scholars who have done quite well (Einstein for one).  However, unless you are the next Einstein or Bill Gates, best try to keep your grades up.  If you have bad grades, don't post it on your resume and try hard to get in touch with the technical person doing the hiring instead of the hr inbox.  Also, one of the best ways to overcome lower GPAs is lots of relevant internship work and code samples / open source project participation to show your passion for development.

  • Advice for Quitting your Job

    One thing I often get questions about from friends and coworkers is how to gracefully exit their positions (or handle a position that is falling apart, ie leaving on "bad terms").  So here's some thoughts on the termination process.

    How much notice do I give?

    As much or as little as you feel comfortable with.  Employers like to tout the "2 weeks notice" as the defacto standard but frankly the majority of states have this whole legal policy that says an employer can terminate you at any time for no reason whatsoever.  So frankly if employers are willing to toss you on your ear with no notice then I don't really see the logic behind feeling compelled to give two weeks notice.  So yes, if you're changing jobs and your new employer wants to start you early, do not feel bad about giving short notice because it's not them you're trying to please anymore but your new employer.  That being said however, you really don't want to burn your bridges so if it doesn't cause hardship go ahead and give that 2 weeks notice.

    In addition, especially in IT, be prepared to be terminated the moment you give notice.  Many companies for liability purposes have  policy that says as soon as you give notice they need to disable your accounts and escort you to the door.  They may or may not give you severance pay up to your notice, though it is known to happen and in my opinion is the classy thing to do.  In other words, do not give notice unless you are comfortable losing your job and income that day.  If you've accepted another offer pending anything (background check, etc) then do not give notice until all that stuff clears.

     

    Don't burn your bridges!

    More often than not in the business world success depends upon your contacts.  When you leave an organization make sure to be civil and get contact information from anyone who is skilled and/or you got along with.  You never know when you might be able to help someone find a job in your new organization or when they might come across an opportunity that suits you.  In addition, if you're leaving and disgruntled, do refrain from having a bitch-fest at your exit interview.  As much as you'd like to tell the HR rep what an asshole your boss was, or how your coworkers made your life miserable, it does absolutely nothing for you.  You're leaving, it's no longer your problem or your battle to fight.  Let nature take its course... if people in your position keep quitting eventually upper management will put two and two together.

     

    Accepting a counter-offer

    Many career advice types will tell you never to accept a counter offer.  Being that you've already announced your intentions to quit, even if you accept a counter offer there is a legitimate fear that it will be held against you sometime in the future.  Do you blame them?  You've shown yourself at this point to be "disloyal" since you were out job hunting.  If you are quitting because you are getting an advancement opportunity or more salary elsewhere a better way to handle the situation running up to the resignation is to schedule a frank talk with your manager.  Tell them that you really want a promotion path or that you do not feel like you are being compensated at your market value.  Be prepare to back up these statements by highliting your accomplishments and cost savings you bring to the organization.  If they are unreceptive or make promises and don't keep them then it is time to move on.

     

    What to do when things are going poorly

    Is someone "out to get you"?  Do you feel like you are going to be terminated?  Probably the best thing you can do in this situation is to start documenting.  You should know that it is difficult to collect unemployment compensation if you were terminated for cause, so if you expect to be out of work for a while your best defense is to start documenting that your termination was not for cause.  This includes printing out hard copies of email communications, copies of your performance reviews, and any other information.  You'll want to document both the good and the bad.  Performance reviews are particularily helpful since if you can show that you got high marks and then were suddenly terminated for an unjust cause you can use it as evidence.  This is particularily helpful in harassment and discrimination coverups.  A friend of mine once was sexually harassed by a boss and when she complained got the run around and was eventually fired.  Because she had documented evidence of outstanding performance for her last few years of service she was able to litigate and win a wrongful termination lawsuit.

    Also, try to examine why things are going so poorly.  Are you too blunt?  Do you make people uncomfortable?  If you're on the way out there's no reason why you shouldn't go around and ask for some information from coworkers on how you are perceived and what they think you can do better.  Sure it's a pride pill to swallow, but if you can take those lessons into your next position you'll be a better person for it!

  • Self Documenting Code

    One of my major goals when embarking on a development project is to structure the application such that the code documents itself.  Does this mean that I don't comment my code?  Of course not!  But I find that if you take on development tasks with the mindset of "Could a developer with nothing but a business requirements document work in this environment semi-effectively if all of my comments vanished?" you would be amazed at the impact it has on your coding style.

    That being said, the biggest concept of self documenting code comes down to naming.  There are two rules of thumb to self documenting code in this aspect:

    1. If it looks like a cow and acts like a cow, call it a cow.
    2. Once you call it a cow, make sure you always call it a cow.

    Or in other words, name things as meaningfully as possible and once you settle into a naming convention do everything you can to not step out of that convention.  One big readability/documentation pet peeve I have is when developers slip into using non-standard abbreviations.  I have no problem with abbreviations that are commonly accepted like avg for average but I do have a problem when looking through source code I see a plethora of either completely unknown abbreviations or variations of a concept.  An example of variations I commonly see is for datetime values.  Date, dte, dt, dtm, all intermixed in the code.  Certainly most of us are intelligent enough to figure it out, but it does jar the thought patterns of someone browsing through the code when you change things up on them.

     

    Methods

    When you name a method, do try to describe its intent.  Please don't use generic names like "GetValue", or "GetNext", or "GetAvg".  They are obscure and require the reader to actually drill into the logic to determine what the method actually does.  Instead use something like "GetCustomerId()" or "GetNextCustomer" or even "CalculateAvgPrice". 

    In addition, when naming methods, since they are "actions" I try to use the verb-noun naming convention.  A good example of this is "DisplayHourlyReport", a bad example is "HandleOutput".

    Another advantage to implementing this type of specific naming in your code is that it can give you an excellent heads up when a method is trying to do too much.  Many coders, including myself, advocate that a method should be responsible for only one task, and related tasks even if called in line should be abstracted to their own methods.  When you are attempting to name a method and you find it difficult because of the scope of the method you should definitely examine it and see if you can break it up into smaller more specific pieces.

     

    Variables

    Simliar to the principles for naming methods, name your variables explicitely as to what they accomplish.  The worst case scenario of this would be using a variable "d" which tells me absolutely nothing.  Slightly less harsh would be using "dt, dte, or date".  What is most beneficial to the reader is using a name like "CurrentDate" or "MeetingDate".

    Something many are guilty of, including myself, is the use of counters like i or j.  This is mostly the fault of our coding book authors since it seems to be in almost any sample code that has a loop counter.  However i and j tell us nothing about the loop.  This also ties to the use of magic numbers in loops.  For example, if we were going to loop the days of the week, many samples would look like so:

    for i = 1 to 7

    In this case i doesn't mean anything, and 7 is a "magic number".  Certainly we can infer that someone is looping the days of the week, but how much more self documenting is this:

    for dayInWeek = 1 to NUM_DAYS_IN_WEEK

    Yes, it's more verbose and people will whine, but the clarity you gain in the code is worth having to type NUM_ then ctrl-space to populate the rest through intellisense.  =)

     

    Failing all else, just be consistent

    It is what it is.  If in C# you decide to write an if statement like this:

    if () {

       // stuff

    }

    Then do it all the time.  Don't arbitrarily switch to:

    if ()

    {

       // stuff

    }

     

    Conclusion

    Writing self documenting and easily readable code isn't hard to do, it just require dedication.  What you will find upon doing it is that:

    1. Other people will enjoy working with your code more
    2. It will make you look more professional since it seems you care about others touching the code
    3. It will help you write better code since it forces you to clearly define what you are doing
More Posts