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

Raymond Lewallen

Professional Learner

July 2005 - Posts

  • My overall top 30 draft picks in Fantasy Football 2005

    Updates:

    Top 20 Fantasy Quarterbacks for 2005 Based on TD Projections

    Top 20 Fantasy Running Backs for 2005 Based on TD Projections

    Top 20 Fantasy Wide Receivers for 2005 Based on TD Projections

    Top 10 Fantasy Tight Ends for 2005 Based on TD Projections

    Top 10 Fantasy Kickers for 2005 Based on Total Points Projections

    Ok, its pretty much the first of August.  4 weeks until my big fantasy draft.  I have 2 other drafts in 2 other leagues, but I always talk about my big money league in California when I talk about Fantasy Football.

    So here they are, my top 30 picks, which make up the first 3 rounds of a 10 team league.  Consider this, these are picks ONLY for a TD ONLY league, not a yardage league.  A yardage league would not have the same top 30 picks.  Needless to say, if I were to draft tomorrow, this is my first 3 rounds cheat sheet.

    Round 1

    1. L. Tomlinson
    2. P. Manning
    3. S. Alexander
    4. P. Holmes
    5. W. McGahee
    6. D. Culpepper
    7. E. James
    8. C. Dillon
    9. D. Davis
    10. R. Moss

    Round 2

    1. D. McAllister
    2. M. Harrison
    3. C. Portis
    4. C. Johnson
    5. R. Johnson
    6. T. Owens
    7. K. Jones
    8. J. Jones
    9. D. McNabb
    10. L. Jordan

    Round 3

    1. A. Gates
    2. R. Wayne
    3. J. Lewis
    4. T. Holt
    5. T. Bell
    6. A. Green
    7. J. Horn
    8. C. Martin
    9. S. Jackson
    10. T. Gonzalez
  • Chris Kinsman in Oklahoma City this coming Monday August 1st

     
    Monday, August 01, 2005 (PST) - August 2005 Meeting
    speaker: Chris Kinsman
    location: Hometown Buffet-North(Lunch - $3.50 Coupon) & Oklahoma City Downtown Library(Dinner - free pizza)
    Currently -
    Using Enterprise Library with ASP.NET 

    Chris Kinsman is one of the founders of Guided Design and formerly the VP of Technology for DevX.com, a web site that provides information for developers. He has extensive experience with ASP, Web Farms, Clustering, Data Access, and Scalability. He just finished writing “Visual Basic.NET Developer’s Guide to ASP.NET, ADO.NET and XML” and “C# Developer’s Guide to ASP.NET, ADO.NET and XML”. Chris has spoken at a variety of conference including VSLive and Microsoft TechEd.
  • Trying to pick my fantasy football keeper player

    I’m in a keeper fantasy league.  Our rules state that I can keep any 1 player, tagging that player with a franchise tag, for up to 3 years.  This only applies to players drafted in the 6th round or later.  Here are my choices

    • Eli Manning
    • Rod Smtih
    • Anthony Becht
    • Adam Vnateri
    • Buccaneers Defense/Special Teams
    • LaMont Jordan
    • Keyshawn Johnson
    • Billy Cundiff

    To me, this is a no brainer.  I’m keeping Jordan.  Of course, holding onto Vinateri isn’t so bad a thing, but kickers are easy to come by and Vinateri is really a 7th or 8th round pick, as most kickers are.  Jordan can go as high as the 3rd round, and since he is slated to be the starting running back on a much improved offensive squad (additions of Randy Moss and Norv Turner), holding onto him seems to be the best option.  Here is the latest fantasy outlook on Jordan:

    Jordan signed with Oakland in the offseason and will serve as the team's No. 1 running back. A bruiser who is a perfect fit for the Raiders' offense, Jordan has a fantastic chance to join Emmitt Smith, Stephen Davis, LaDainian Tomlinson and Ricky Williams on the list of backs who have found success under head coach and offensive coordinator Norv Turner. Oakland's pass attack could be one of the league's best with the addition of superstar wide receiver Randy Moss, so the opposition will have little chance to focus on Jordan with constant stacked fronts on the line of scrimmage. Barring injuries, the former Maryland back should rush for 1,200-plus yards and seven to nine touchdowns and is worth early-round consideration.

    I’m still concerned that he may only touch the ball 15–20 times per game because of Collins hooking up with Moss and Porter often, but Turner is a ground game coach.  With any draft pick, including your keepers, the game of football involves a lot of gambling and even more luck.

  • Boxing and Unboxing for Beginners

    Value types are created on the stack.  Reference types are created on the heap.  When something is created on the heap (an object) the variable assigned to that object holds a 4 byte “pointer” to the address space on the heap where the object has been allocated.  Every time you pass that variable as a parameter to another method, the 4 byte pointer is passed, not the object itself.  When you pass a value type (Integer, DateTime and such), a copy is made and the entire value type is copied to the method where its going to be used.

    In the near future, I have a post in the making on using value types versus reference types.

    Sometimes, you need to use a value type as if it were a reference type.  This is known as “boxing”.  Let’s say you wanted to create an arraylist that contains Integers.

        Public Sub Method1()

            Dim a As New ArrayList

            a.Add(10)

        End Sub

    If you examine the Add method of an arraylist, you see that it is not overloaded.  It only take System.Object as a parameter.  System.Object is a reference type is any objects are created on the heap.  In the first paragraph, we know that Int32 is a value type.  So what happens when we add an integer to an arraylist?  Let’s look at the MSIL

    .method public instance void Method1() cil managed
    {
          // Code Size: 23 byte(s)
          .maxstack 2
          .locals (
                [mscorlib]System.Collections.ArrayList list1)
          L_0000: nop
          L_0001: newobj instance void [mscorlib]System.Collections.ArrayList::.ctor()
          L_0006: stloc.0
          L_0007: ldloc.0
          L_0008: ldc.i4.s 10
          L_000a: box int32
          L_000f: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)
          L_0014: pop
          L_0015: nop
          L_0016: ret
    }

    At L_0008, you see that we load the 4 byte integer 10 to the stack, you see the IL instruction to box that value as the next instruction.  So what is actually being stored in the arraylist?  Well we know that since arraylist takes an object as its parameter, we know that it wants to store an address pointer, not the value ‘10’.  In order to get an address pointer to store in the arraylist, the integer has to be converted to an object and a reference to that object must be obtained.  This is called boxing.

    So what is really happening during boxing?  Just like any object, memory on the heap must be allocated for the object.  The Int32’s information is then copied to that new address space.  The address pointer of that location where the Int32’s information was copied to is returned.  The Int32, a native value type, is now an object: a reference type.  That address pointer is what actually gets passed to the Add method of the arraylist.

    So what about unboxing?  Unboxing is the exact opposite of boxing.

        Public Sub Method1()

            Dim a As New ArrayList

            a.Add(10)

            Dim b As Int32

            b = a(0)

        End Sub

    In this code, we create an Int32 and want to store the value from the first element of the arraylist to this Integer, in this case ‘10’.  Unboxing is defined as getting the address of the object, and then copying that information to a value type that has been created on the stack (b in the above example).  The MSIL is below:

    .method public instance void Method1() cil managed
    {
          // Code Size: 36 byte(s)
          .maxstack 2
          .locals (
                [mscorlib]System.Collections.ArrayList list1,
                int32 num1)
          L_0000: nop
          L_0001: newobj instance void [mscorlib]System.Collections.ArrayList::.ctor()
          L_0006: stloc.0
          L_0007: ldloc.0
          L_0008: ldc.i4.s 10
          L_000a: box int32
          L_000f: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)
          L_0014: pop
          L_0015: ldloc.0
          L_0016: ldc.i4.0
          L_0017: callvirt instance object [mscorlib]System.Collections.ArrayList::get_Item(int32)
          L_001c: call int32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.IntegerType::FromObject(object)
          L_0021: stloc.1
          L_0022: nop
          L_0023: ret
    }

    You can see at instruction L_001c, the FromObject method is called.  This does the work of unboxing that we mentioned above.  2 imporant exceptions to take note of when unboxing though.  If the reference that are “getting” from the arraylist is nothing, a NullReferenceException will occur.  If the reference type that you are “getting” isn’t an Int32 in the above example, let’s say its a System.DateTime, then a InvalidCastException will occur.

    So you’ve probably heard to avoid boxing and unboxing when you can.  Why?  Obviously, its costly to the speed and memory of your application.  Extra instructions and memory space are required when boxing and unboxing.  Also when you box a value type (recall this required allocating memory space on the heap), you always risk having the garbage collector run against the heap to clean up unused resources, which is an expensive operation.

  • Taking responsibility for plagarism

    Its nice to see SqlServerCentral taking responsibility and dealing with plagarism in a straight-forward manner. Hopefully something bad is happening to Kalpesh Thaker, the mentioned plagarist.

    I would like to personally and on behalf of Andy, Brian, and SQLServerCentral.com apologize to Ken Henderson for publishing his work without credit.

    It's a big statement, but one that I feel needs to be made. Recently I received a couple of emails from concerned members of the SQLServerCentral.com community. It seems that an article that we published in January was plagiarized from Ken Henderson's The Guru's Guide to Transact SQL. As I was on vacation, I couldn't deal with it for a few days, and I needed to find my copy of the book to check the allegation. Before I could, Mr. Henderson emailed and confirmed just that.

    I promptly removed the content and put a placeholder up there instead, noting there was a copyright issue. I then contacted Ken and he confirmed that two other articles submitted by Kalpesh Thaker were also plagiarized from his books and I removed them as well.

    I am truly sorry that this happened and there is no excuse to be made. I do not check the submissions we receive against any type of full text search to see if they have been copied and I'm not sure that I can, but I thought that this release could serve two purposes.

    First, a public apology to Ken Henderson for having his work out there for months without credit being given.

    Second, I would like to let the community know what has happened. I'm hoping that you who read these articles will keep an eye out for this horrible practice of copyright violation. Since many of you are reading more SQL books than I, or perhaps more recently reading them, you'll be in a better place to spot this than I.

    With the explosion of the Internet, the growth of SQL Server, and quite a few new book publishing companies, including ours, it's difficult to track down plagiarism. It's also created opportunities for many more people to write and publish works themselves. This means that many more people are out there creating articles and books than ever before.

    However publishing something carries a responsibility as well. If you put your name on something, it needs to be your original work. Rewriting someone else's work is acceptable only if you have added additional value and substantially changed their work. If I wanted to write my own "Internals" book, the language would need to be my own. The chapters would be what I decided and they shouldn't mirror what Kalen Delaney wrote.

    The same thing applies here. The author said that Mr. Henderson had done a better job of writing, so he just used what was in Mr. Henderson's book. That's not only illegal, it's very immoral. You are misrepresenting yourself and your knowledge as well as infringing upon someone else's work. If you didn't write it, don't take credit for it.

    I offer no excuses for what happened and if there is anything that I can do to prevent it in the future I will.

    Steve Jones

    Steve mentions about doing full-text searches.  I’ve read in the past that colleges are doing this type of very thing to fight plagarism and duplicated term papers and essays submitted by students.  But what kind of resources are required?  What type of matches are required?  Is it a ratio of matched words:total words per page when doing searches?  What qualifies as plagarism?  Total complete copies, or do partial copies qualify?  If partial copys qualify, what is the percentage of copied material that qualifies text as plagarism?

    These are questions I’m asking myself and would like your input.  What type of plagarism search solutions are out there?  I’m sure some of you in CS departments might be more aware, since I know that there are colleges that check this kind of stuff.  What can be done from SqlServerCentral’s capabilities to help them out to avoid these types of things in the future?  How are other publishing companies dealing with this?  If you’re a book author, how does your publisher, like Wrox, check for plagarism?

    I occasionally post code, like this one here, that I didn’t write.  But I never, ever fail to mention who the author is.  I don’t understand the purpose in taking credit for somebody else’s work.  I would not like somebody else taking credit for my work, although I don’t go out looking to see if it happening.  Not a big deal to me if somebody copies my stuff, but yeah, I would like credit where credit is due.

    Some topics, code samples etc are fairly generic, and have been written the same way by 100s of people.  Those don’t really count.  Aircode shouldn’t count.  Articles, complex pieces of code, like the sql example I gave, those should definately count as having been either original work of your own, or have credit given to the original authors ora bibliography or footnotes associated with them.

  • My top 5 picks in category for Fantasy Football 2005

    Its that time.  NFL Fantasy Football is just around the corner.  Those of you who know me personally know that fantasy football is very important to me, and I invest a lot of time and money into it.  Every year I even fly half way across the U.S. for a big live draft party (I used to live in California and am still part of that league, which is my biggest, most important and largest money league).  The rest of the leagues I am in are online, except one free league with 7 other guys from work.

    So what is my rundown for this year?  Stricly from my California league point-of-view, which is touchdown only league, these are my top 5 picks in their respective categories:

    Quarterbacks

    • Manning - no brainer
    • Culpepper - won't perform as well without Moss
    • McNabb - will put up last years numbers with T.O.
    • Favre - always solid.  Walker will be there for the start of the season.
    • Green - Healthy Holmes will help him

    Running Backs

    • Tomlinson - #1 overall pick of all drafts
    • Alexander - will settle his contract disputes
    • Holmes - 32 years old, but still a difference maker.
    • McGahee - Will improve on last year
    • James - Has something to prove for a big contract next year

    Wide Receivers

    • R. Moss - Can perform on most teams.
    • Harrison - Is no longer the only target for Manning.
    • Owens - He'll play, but will it be for Philly?
    • Wayne - Manning looks for him often.
    • Holt - Always Bulger's first choice.

    Tight Ends

    • Gates - Can't reproduce last years numbers, but still a great TE.
    • Gonzales - Still the best in the business, but can't get the TDs Gates will get.
    • Crumpler - Vick will continue to look for him.
    • Witten - Will duplicate last years numbers.
    • Clark - Another favorite target of Manning.

    Kickers

    • Vinateri - Clincher.
    • Akers - Will get lots of attempts.
    • Vanderjagt - Solid year after year.
    • Elam - Solid pick
    • Stover - Another solid kicker year after year.

    Defense/Special Teams

    • Patriots
    • Ravens
    • Bills
    • Falcons
    • Kansas City
  • Yes, I've joined Project FAZR.

    So, I’m the first person to be onboard with Project FAZRBrady Gaster is the second.

    Both Ryan and I are located in the same city, so its going to be easy for us to get together on a frequent basis and talk about things.  Having Brady onboard is exciting, as I’ve been a long time reader of his blog and have high respect for him and knowledge he possesses.  Ryan and I have been briefly discussing Project FAZR and kind of sharing our ideas about it.  You can pretty much get all the information you need about it right here.

    Had the originator of the idea, Ryan, not been as easily accessible to me, in person, as he is, I don’t know that I would have asked him about it and got on board, cause I’m a very busy person.  Just the idea of being able to work with him in person on occasion on the project was a big plus for me.  I don’t anticipate any of the other people we pick to join us will be in the locality of Ryan and I, but will be helpful people, no doubt.

    So for now, we are working on gather interest from some developers and answering some questions.  Also thinking up and sharing project ideas.  Its always fun to talk about projects you’ve had in your head for a long time but can’t do on your own, and suddenly getting that opportunity to discuss and possible get a group of developers to commit time and get the project done.

    Project FAZR is certainly in its beginning stages, and will continue to be for a little while until we get more people on board, in addition to Ryan, Brady and I.  Check out the idea, and drop Ryan a note if you want more information or are interested.

  • Wincv - The Windows Forms Class Viewer

    Saw a funny post on this blog earlier, and thought maybe a lot of people don’t know about the tools in SDK.  One of them is wincv, and if you don’t know about wincv.exe, you’ve been missing out.  If you use reflector, then you haven't been missing out, and I like reflector better, personally.

    Wincv is the windows forms class viewer.  It lets you find information about a class simply by typing in a search string.  If I launch wincv (location in “C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin” so it helps to have this in your PATH) and type in “DateTime”, I get what you see below:

    The default assemblies it loads for searching are:  mscorlib.dll, System.dll, System.Data.dll, System.Design.dll, System.DirectoryServices.dll, System.Drawing.dll, System.Drawing.Design.dll, System.Messaging.dll, System.Runtime.Serialization.Formatters.Soap.dll, System.ServiceProcess.dll, System.Web.dll, System.Web.Services.dll, System.Windows.Forms.dll, System.XML.dll

    For more information, see the MSDN documentation for Wincv.exe

  • Crop circle speculation

    If you know much about the research and studies done on crop circles, check out this article.  Could an orbiting satellite of the same nature be the source for crop circles?  Seems likely when looking at research.  Research says that stalks of wheat, corn, maize or whatever the crop may be, seem to have symptoms of being “microwaved”.  It has been my theory for quite a while that there is a mechanism up in space used to produce crop circles and their intricate patterns, and this new military device used to disperse riots seems to fit the bill, in my opinion, if of a higher power and attached to a satellite floating in orbit around the planet.  Also a decent explaination for cattle/animal mutilations, better theory than the chupacabra anyways.
  • Using Devenv at the command prompt to build projects

    We all know about NAnt, MsBuild and some other build tools.  People are very aware of these, but seem to be unaware that you can create your own build batch file just by using visual studio and the command prompt.

    Let’s say you have 2 solutions, a solution with business objects and business rules assemblies, and another solution just for an Asp.Net GUI project.  We can easily build a batch file to compile these three projects:

    Batch file build

    REM Builds projects in debug mode

    REM Build data project

    Devenv /build debug /project DataAccess "C:\Projects\WebApplication\BusinessProjects.sln"

    REM Build business rules project

    Devenv /build debug /project BusinessRules "C:\Projects\WebApplication\BusinessProjects.sln"

    REM Build web application

    Devenv /build debug /project WebApplication "C:\Inetpub\wwwroot\WebApplication\AspWebApplication.sln"

    Voila!  Run the batch file to build everything in debug build.

    • “Devenv” is the IDE executable.
    • /build is the switch to build the project.  It takes either “debug” or “release” as arguments.  Change “debug” to “release” to build everything in release mode.
    • /project and its argument specifiy the name of the project to build within a solution.
    • The final argument for “devenv” is the location of the solution file that contains the project you want to build.

    Note:  This works for .Net IDE 2002 and 2003.  I have not tried this with 2005 yet.  If anyone has, let me know of the changes in the comments below.

    You can do “devenv /?” at the command prompt to list all available switches for Devenv, with descriptions of their uses.

    From MSDN Documentation:

     The following syntax rules apply to all switches and arguments:

    • The command line syntax must start with devenv. For example, to use the /fn switch you would type the following:
      devenv /fn arial
    • Switches are not case sensitive.
    • The first argument is typically a solution file name.
    • When you supply a project file name instead of a solution file name, Devenv does the following:
      • Searches the parent directory of the project file for a solution file of the same name. For example, if you specify myproject1.vbproj, Devenv looks for myproject1.sln.
      • Searches for a single solution file with a reference to the project file in the parent directory of the project file. If more than one solution references the project file or no solutions reference the project file, a temporary solution with the same name as the project file is created.
    • File paths and file names that include spaces must be enclosed in double quotation mark ("").
    • Include the drive letter when specifying file paths.
    • Separate multiple switches and arguments with one white space character.
    • Devenv does not accept wildcards or other pattern matching syntax.

    Use the following command line switches to display the integrated development environment and perform the described task.

    Command line switch Description
    /lcid or /l Sets the default language for the IDE.
    /fn Changes the system font for the IDE.
    /fs Changes the system font size for the IDE.
    /run or /r Compiles and runs the specified solution.
    /runexit Compiles and runs the specified solution, minimizing the IDE when the solution is run, and closing the IDE after the solution has completed running.
    /mdi Opens the IDE in multiple-document interface (MDI) mode. In addition, the MDI environment option in the Options dialog box is selected. For more information, see General, Environment, Options Dialog Box.
    /mditabs Opens the IDE in MDI mode with the tabs on documents enabled.
    /command Starts the IDE and executes the specified command.
    /migratesettings Opens the IDE and copies certain Options dialog box settings from a pervious version to the more recent version.
    /debugexe Loads a Visual C++ executable under the control of the debugger. This switch is not available for Visual Basic or Visual C# executables. For more information, see Launching the Debugger Automatically.
    /useenv Causes the integrated development environment (IDE) to use PATH, INCLUDE, and LIB environment variables for Visual C++ compilation rather than the settings specified in the VC++ Directories section of Projects options in the Options dialog box. For more information, see Setting the Path and Environment Variables for Command-Line Builds

    Use the following command line switches to perform the described task. These command line switches do not display the integrated development environment.

    Command line switch Description
    /build Builds the specified solution or project according to the specified solution configuration.
    /rebuild Cleans and then builds the specified solution or project according to the specified solution configuration.
    /project The project to build, clean, or deploy. You can use this switch only if you have supplied the /build, /rebuild, /clean, or /deploy switch.
    /projectconfig Specifies the project configuration to build or deploy. You can use this switch only if you have supplied the /project switch.
    /clean Cleans the specified solution or project according to the specified solution configuration.
    /deploy Causes deployment after a build (or a rebuild) according to the specified solution configuration.
    /out Allows you to specify a file to receive errors when you build.
    /nologo Prevents copyright information from displaying.
    /? Displays help inside the Command Prompt window for Devenv switches.

    The following switches are available only to those companies who participate in the Visual Studio .NET Integration Program (VSIP).

    Command line switch Description
    /noVSIP Disables the VSIP developer's license key on a developer workstation.
    /safemode Launches Visual Studio in safe mode, loading only the default environment and services.
    /resetskippkgs Clears all SkipLoading tags added to VSPackages by users wishing to avoid loading problem VSPackages.
  • Extreme Programming Workshop Right Around the Corner!

    Don't forget, the Extreme Programming Workshop and Seminar is in Oklahoma City this Thursday (July 21st) and next Tuesday (July 26th)! Seats are filling up, but plenty of room available, so be sure and register for one of those days!

    Click here for more details.

  • Introduction to Refactoring

    Evolution.  It is inevitable.  Software succumbs to evolution, like everything else.  Almost all software goes through a process of revisions and changes between the time it was born a wee little prototype, to its inevitable death.  Object oriented programming is by far, IMO, the easiest code design to deal with when having to make changes during the life of a software product.  However, just because you might be using OOP, doesn’t mean you have optimal design.  Last week I talked about analyzing code metrics, which play a big part in determining how good, usable and maintainable your design is.

    This is where refactoring comes in.  Refactoring can be defined as a process where developers examine existing code and improve the design of that code by means of modifications.  While there is no specific model for the process of refactoring, there are certainly some common areas where you see most problems in design, which is where refactoring takes place.

    Refactoring is a very in-depth subject, and I’m only going to skim the top of it for you beginners out there.  I’m not going to get into test driven development or patterns of software design, but simply explain 4 common tasks which are encapsulated in refactoring.

    Identify methods that can be moved.

    This means to look for methods that are encapsulated in the wrong class.  Methods should perform a task relevant to the class in which they belong.  If a method is making frequent calls to another class, consider moving that method to the other class.  Look at the following example:

    Namespace Refactoring

     

        Public Class Person

     

            Private _dateOfBirth As Date

            Public Property DateOfBirth() As Date

                Get

                    Return _dateOfBirth

                End Get

                Set(ByVal Value As Date)

                    _dateOfBirth = Value

                End Set

            End Property

     

        End Class

     

        Public Class VoterRegistration

     

            ' Used to determine if the person is old enough to vote

            Public Function CalculateAge(ByVal voter As Person) As Int32

                Dim years As Int32 = DateTime.Now.Year - voter.DateOfBirth.Year

     

                If DateTime.Now.Month < voter.DateOfBirth.Month OrElse (DateTime.Now.Month = voter.DateOfBirth.Month AndAlso _

                    DateTime.Now.Day < voter.DateOfBirth.Day) Then

                    years = years - 1

                End If

     

                Return years

     

            End Function

     

        End Class

     

    End Namespace

    Hopefully it is clear that “CalculateAge” is in the wrong class.  It is taken a single argument of type “Person” and acting entirely upon that argument.  This is a clear case where a method should be moved, in this case from the “VoterRegistration” class to the “Person” class so you have code like below for the “Person” class:

        Public Class Person

     

            Private _dateOfBirth As Date

            Public Property DateOfBirth() As Date

                Get

                    Return _dateOfBirth

                End Get

                Set(ByVal Value As Date)

                    _dateOfBirth = Value

                End Set

            End Property

     

            Public Function Age() As Int32

                Dim years As Int32 = DateTime.Now.Year - _dateOfBirth.Year

     

                If DateTime.Now.Month < _dateOfBirth.Month OrElse (DateTime.Now.Month = _dateOfBirth.Month AndAlso _

                    DateTime.Now.Day < _dateOfBirth.Day) Then

                    years = years - 1

                End If

     

                Return years

     

            End Function

     

        End Class

     

    Identify new methods.

    Common mistakes amongst developers is to create methods that are too complex and accomplish too much themselves.  This leads to methods that are hard to build upon, maintain and debug.  Cyclomatic complexity is a common code metric to use to determine if a method is too complex.  Dividing methods into smaller, more easily managed pieces improves upon simple design and improved clarity.  Repetative code is another clear indicator of where to create new methods.

    Take a look at the following code:

    A method that is reusing code within itself

     

    Namespace Refactoring

     

        Public Class Foo

     

            Public Function GetData() As DataTable

     

                Dim dt As New DataTable

     

                Dim dcFirstName As New DataColumn

                dcFirstName.DataType = Type.GetType("System.String")

                dcFirstName.AllowDBNull = False

                dcFirstName.Caption = "FirstName"

                dcFirstName.ColumnName = "FirstName"

                dcFirstName.DefaultValue = Nothing

                dt.Columns.Add(dcFirstName)

     

                Dim dcLastName As New DataColumn

                dcLastName.DataType = Type.GetType("System.String")

                dcLastName.AllowDBNull = False

                dcLastName.Caption = "LastName"

                dcLastName.ColumnName = "LastName"

                dcLastName.DefaultValue = Nothing

                dt.Columns.Add(dcLastName)

     

                Dim dcDateOfBirth As New DataColumn

                dcDateOfBirth.DataType = Type.GetType("System.DateTime")

                dcDateOfBirth.AllowDBNull = False

                dcDateOfBirth.Caption = "DateOfBirth"

                dcDateOfBirth.ColumnName = "DateOfBirth"

                dcDateOfBirth.DefaultValue = Nothing

                dt.Columns.Add(dcDateOfBirth)

     

                Return dt

     

            End Function

     

        End Class

     

    End Namespace 

    Obviously, its staring you right in the face that there is reusable code here. This is where you create a new method.

    Refactored to create a new method

    Namespace Refactoring

     

        Public Class Foo

     

            Public Function GetData() As DataTable

     

                Dim dt As New DataTable

     

                dt.Columns.Add(BuildColumn("FirstName", Type.GetType("System.String")))

                dt.Columns.Add(BuildColumn("LastName", Type.GetType("System.String")))

                dt.Columns.Add(BuildColumn("DateOfBirth", Type.GetType("System.DateTime")))

     

                Return dt

     

            End Function

     

            Private Function BuildColumn(ByVal columnName As String, ByVal columnType As Type) As DataColumn

                Dim dc As DataColumn = New DataColumn

                dc.DataType = columnType

                dc.AllowDBNull = False

                dc.Caption = columnName

                dc.ColumnName = columnName

                dc.DefaultValue = Nothing

                Return dc

            End Function

     

        End Class

     

    End Namespace

     

    Identify inheritance.

    Many times when you see “Select Case” or “Switch” statements, this is a strong indicator that the code should be refactored into an inheritance design.  Look at the following code:

    Part of a carnival ride program.

     

    Namespace Refactoring

     

        Public Class Foo

     

            Private baseTokenAmount As Int32 = 1

     

            Public Function GetNumberOfRequiredTokens(ByVal typeOfPerson As PersonType) As Int32

                Select Case typeOfPerson

                    Case PersonType.Infant

                        Throw New Exception("Too young to ride")

                    Case PersonType.Child

                        Return baseTokenAmount

                    Case PersonType.Adolescent

                        Return baseTokenAmount * 2

                    Case PersonType.Adult

                        Return baseTokenAmount * 3

                    Case PersonType.Senior

                        Throw New Exception("Too old to ride")

                End Select

     

            End Function

     

            Public Enum PersonType

                Infant

                Child

                Adolescent

                Adult

                Senior

            End Enum

     

        End Class

     

    End Namespace

    The code is pretty clean and simple, but it makes it hard to build on and add other persontypes into the system.  If you have code like this everywhere, you’d have to go into a lot of different places in the program and change code to adjust for an added personType.  This is an example of code that should be refactored into inheritance.  The result would be the following code:

    Conditional refactored to inheritance and polymorphism.

    Public Class Foo

     

        Public Shared Function GetNumberOfRequiredTokens(ByVal person As IPerson) As Int32

            Return person.GetNumberOfRequiredTokens()

        End Function

     

    End Class

     

    Public Interface IPerson

        Function GetNumberOfRequiredTokens() As Int32

    End Interface

     

    Public MustInherit Class Person : Implements IPerson

        Private baseTokenAmount As Int32 = 1

        Protected ReadOnly Property Tokens() As Int32

            Get

                Return baseTokenAmount

            End Get

        End Property

     

        Public MustOverride Function GetNumberOfRequiredTokens() As Int32 Implements IPerson.GetNumberOfRequiredTokens

    End Class

     

    Public Class Child : Inherits Person

        Public Overrides Function GetNumberOfRequiredTokens() As Int32

            Return MyBase.Tokens()

        End Function

    End Class

     

    Public Class Adult : Inherits Person

        Public Overrides Function GetNumberOfRequiredTokens() As Int32

            Return MyBase.Tokens * 3

        End Function

    End Class

     

    Public Class Infant : Inherits Person

        Public Overrides Function GetNumberOfRequiredTokens() As Int32

            Throw New TooYoungException

        End Function

    End Class

     

    Public Class TooYoungException : Inherits Exception

     

    End Class

    Now, to add a new person type, we just add a new class for that person type that inherits from the class “Person” and we won’t have to change any existing code, we only added new code.

     

    Fix your variable names.

    What do you think td stands for?  You can probably come up with dozens of different things it could possible be.  What if I told you it stands for todaysDate?  This is a big problem in code.  Meaningless variable names.  In Visual Studio, sure Intellisense tells me its a date, but other than that, what the heck is it for?  Give your variables meaningful names, and not names where you leave out all the vowels either.  tdysDt is not very helpful either.  You are going to save somebody a lot of time and headache in the future if you use meaningful names.  I’ve even seen people go back to their own code before and have to decifer what the heck td stood for by search back through code.

     

    I have explained 4 common design issues to look for when beginning your code refactoring.  Once you do it a little while, it becomes easier and you’ll be able to code to avoid these pitfalls, rather than having to fix them afterwards by refactoring.

  • Coupling, Abstractness, Stability - Measuring and Applying Code Metrics

    In a comment to this post, Darrell suggested I describe where high factors of coupling are appropriate.  I’ll take it one step further and show you how to use those factors to determine the stability of an assembly and application, measure abstractness, and how to look at both to determine how useful your assembly actually is.

    Stability is measured by determining how easily you can change an assembly without that change having impact on other assemblies within the application.

    An assembly with high afferent coupling (other assemblies depend on it), which is a highly responsible assembly, is an assembly that has lots of reuse throughout your application.  These assemblies are also, by design, typically the most stable assemblies in the application because assemblies with a high level of responsibility to other assemblies are difficult to change without impacting its dependents.  An example of a highly responsible assembly (high afferent coupled assembly) would be an assembly that contains business objects, because business objects get used throughout the application, and if you change a business object, this has major impact on the rest of the application.

    An assembly with high efferent coupling (depends on other assemblies), is an assembly that is highly dependent on other assemblies in your application.  These assemblies are OK with being instable, because changing them doesn’t involved a great deal of impact on other assemblies within the application.  Highly efferent coupled assemblies have little responsibility to the rest of the application, but are highly dependent on the other assemblies.  GUI layer assemblies (code-behind assemblies in Asp.Net) are a prime example of high efferent coupled, low afferent coupled assembly.

    So now that we understand where afferent and efferent coupling takes place, how do you use that to figure out the instability of your assemblies?  Well, there is a formula for that:

    I = Ce / (Ce + Ca)

    Where:

    • I = degree of instability of an assembly ranging from zero to one
      • Zero indicates stability.  One indicates instability.
    • Ce = efferent coupling (outgoing dependencies)
    • Ca = afferent coupling (incoming dependencies)

    The closer I is to zero, the more stable and responsible the assembly is.  This is an indication of more incoming dependencies (Ca) than outgoing dependencies (Ce).  Again, stable packages are difficult to change without impacting the rest of the application.  As I approaches one, this indicates a more instable, less responsible, more dependent, easier to change assembly.

    So now, how do you make use of this?  You’re going to have assemblies that are both stable and instable in your application.  That’s the way things work.  You’re goal, as a developer, is to make an assembly as close to stable (I = 0) or instable (I = 1) as possible, given the particular assembly’s role in your application.  You’ll goal isn’t actually to reach a value of zero or one, but to get close to it.

    In .Net, as in all OOP languages, we can use abstract classes to increase the stability of an assembly.  Abstract classes pull away what a class is supposed to do from how its actually done, which is handled in an inheriting class.  Abstract classes are completely stable classes themselves, and an assembly full of abstract types would qualify as a completely stable assembly.  Concrete classes do work and do not necessarily define what work.  Concrete classes typically get the “what am I supposed to do” by inheriting from an abstract class.  The concrete class then implements the “this is how to do that work”.  Concrete classes are more instable, because they encapsulate actual work and have less dependents/more dependencies.

    So here’s the formula for determining the abstractness of an assembly:

    A = Na / Nc

    Where:

    • A = abstractness of an assembly
      • Zero is a completely concrete assembly. One is a completely abstract assembly.
    • Na = number of abstract classes in the assembly
    • Nc = number of concrete classes in the assembly

     By taking the design metrics we have talked about, you can determine just how useful your assembly is.  If you have an abstract assembly, but it is highly instable, you’ve really messed up somewhere, because you have an assembly that doesn’t do any work, but is highly dependent on other assemblies.  That is a very useless assembly.  In constract, if you have a highly concrete assembly that is also highly stable, you’re going to have a nightmare trying to make changes to that assembly, because it is doing a lot of work, and also is highly responsible to other assemblies in the application.

    Last month I posted a few tools that analyze your assemblies and provide this information to you.  Definately check these out and look at some of your code metrics to determine what kind of path you’re on and headed down.

  • A terminology lesson regarding coupling

    Here are two terms that must not be used much, even though most of you know the concept.  I mentioned them on this post of Jeffrey’s, and am responding to a comment left asking for explaination of these two terms.

    Afferent coupling

    • The number of types that depend on a particular type within the same assembly.

    Or/Also

    • The number of types outside an assembly that depend on types within the assembly.

    High afferent coupling is an indication of a highly responsible type or assembly.

     

    Efferent coupling

    • The number of types that a particular type depends on within the same assembly.

    Or/Also

    • The number of types inside an assembly that depend on types in another assembly.

    High efferent coupling is an indication of a highly dependant type or assembly.

  • Logging exceptions in your event log