The trouble of making a project public

by Tobias Hertkorn on March 7th, 2012

I just wrote a little helper program that lets you track your currently set power scheme. And reset it, if any external sources (like Windows group policies) change said power options. I wrote this, because I have sometimes long running tasks that collide head-on with our IT departments wise decision to force a power scheme that puts my laptop to sleep after an hour. A laptop. What’s the power consumption of that thing? And most of the time it’s not even plugged in on site, spending company money.

Writing the tool was pretty easy, done in about 45 minutes of coding to get a basic sweet little exe that does nothing but parse a command-line argument, and force-set a power scheme. Which was more than fine by me, since I used the task scheduler to run this program every 5 minutes, knew how to correctly pass a guid to the program, was not surprised that it did not give any feedback, …

I started showing the tool to a couple of friends, who – not surprisingly – had the same problems. How come all IT departments of all major companies have the same stupid ideas? ;-) This is when the suggestions and the feedback started rolling in. So, at first I wrote “documentation” on how to use it. Then I added more elaborate command line parsing, because it seems people do not read manuals. Strange.
Then I set up a git repository on github, so I could start saying “is there a pull request for what you are suggesting” and be all hip and stuff. This did not work out so great, because I ended up adding a daemon mode. Some poor individuals apparently do not even have admin rights on their laptop – and could not set up a task in task scheduler.
And finally I added the possibility to copy and paste the power scheme guids from within the program because some people can’t be bothered to use powercfg.exe.

And I feel like it is still not done. What are the todos? Write a blog post about the tool and set up a dedicated website for it.

So, going public meant going from a 45 min solution that worked brilliantly, to working more than 10 hours for it. And suddently feel like I am not done.

Is it always that hard to give back to the community? What is your experience?

March 7th, 2012 2:27 pm | Comments (1)

Source Structure (Part 3): Be aware of long project names, or …

by Tobias Hertkorn on February 14th, 2008

... why 260 chars really is not that much.

Have you ever seen this error message, while starting a new project?

SvnPlanning - Exceeds maximum path length allowed

"The length of the full path for the solution, project or item you are creating exceeds the maximum path length allowed by the system. You must reduce the length of the name or the location."

I remember sitting in front of my first Win95 installation, wondering how they did that damn thing with the long filenames. And what a waste. 8.3 was enough. So I started naming all my new word documents something totally silly. Like "The Abstract Reflection Regarding Catcher In The Rye After Careful Consideration Disregarded.doc", or something similar in German. And I thought, wow, that's just 97 chars. 260 chars will last me forever! Little did I know...

A source of constant tweaking

How could it possibly be that 260 chars are not enough? Surprisingly 260 chars get used up surprisingly quickly when creating solutions in Visual Studio. Let's look at the default structure Visual Studio creates for me when I create a new solution:

<solution name>
                 <solution name>.sln
                 <solution name>
                                  <solution name>.csproj
                                                <solution name>.dll
                                                <solution name>.pdb

(I hearts me ascii drawing)

That means a solution to create the dll "Com.Hertkorn.Framework.SampleFramework.dll" will result in a total path named:

That's a whopping 139 chars!

Hmm. Actually it seems as if the above error gets displayed at a total path name length of about 199 chars. Oh, well. Who cares what the actual number is. I guess the programmers of Visual Studio played it save and allowed for some leeway. Anyway, so we see, using the default strategy, Visual Studio creates a lot of file path bloat - which results in an obstacle, because it does limit the way we name dlls, which is directly connected with the default namespace, etc. and the way we structure the global structure of our subversion.
So the desire to have nice dll names and namespaces plus still being able to create deep directory structures creates, at least for me, a source of constant tweaking. Because either I create a solution with a short name and modify the namespace and dll name to represent the long name, or I start with the long name and shorten the subdirectories. Either way, it's an additional step that I would like to eliminate. And don't get me started on adding new projects to a solution.

What I currently do by hand are the following steps:

  • I create a solution using the full name of the target dll name in a test folder.
  • Close the solution.
  • Rename subdirectories to use a short name, usually removing redundant information.
  • Move the directory tree into my svn tree.
  • Reopen the solution.
  • Fix the paths to the projects.
  • Reload the projects.
  • If necessary tweak the namespaces.

That certainly is a number of steps that I can automate.

What we need to automate these steps

A tool automating these steps needs

  • The name of the target dll (full project description name).
  • The name of the target namespace.
  • The short name for the directory.
  • The filepath of the directory, where the solution structure will get created.
  • The information if both a solution and a project should get created, or if the newly created project should get attached to an existing solution.

Now we can create a structure like this:

<short name>
              <full project description name>.sln
              <short name>
                            <full project description name>.csproj
                                          <full project description name>.dll
                                          <full project description name>.pdb

This results in a file path:
Com.Hertkorn.Framework.SampleFramework.dll and even with a deep folder structure it results in 126 chars. That is even less than with the default behaviour and flat folder sturcture.

Namespace (sometimes) != dll name

Plus this method allows for the additional freedom of easily choosing the namespace independant of the dll name. That is sometimes desirable, for example in a situation where types, typically interfaces should be shared between different dlls usually unifying components.

So component A which lives in the dll and namespace Com.Hertkorn.Infrastructure.ComponentA and component B which lives in the dll and namespace Com.Hertkorn.Infrastructure.ComponentB should share types. Ideally their shared types live in a component Com.Hertkorn.Infrastructure.SharedTypes.dll but the root namespace should differ. I would argue the root namespace should be Com.Hertkorn.Infrastructure. That way a subdirectory ComponentA or ComponentB would result in a namespace complementing the namespace they want to unify. It is kind of an exotic situation that needs a lot of discussion if the team wants to live with the consequences. But it could happen. ;)

What needs tweaking in the .sln or .csproj

Within the .sln we need to tweak the file path of the resulting .csproj, which should be quite straight forward.

The changes within the .csproj are located in these two lines:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="">
  3.   <PropertyGroup>
  4.     [...]
  5.     <RootNamespace>SvnPlanning.WpfSampleApplication</RootNamespace>
  6.     <AssemblyName>SvnPlanning.WpfSampleApplication</AssemblyName>
  7.     [...]
  8.   </PropertyGroup>
  9.   [...]
  10. </Project>

February 14th, 2008 12:41 am | Comments (3)

Startups: Who should you fire?

by Tobias Hertkorn on February 12th, 2008

I just came across a pretty funny, or sad (?) post by Mike. Startups: Fire Your Dev Teams. Yeah, that's what I thought.

To tell you the truth - he has some very valid points, indeed:

Seriously. The minute you’re successful, plan to rewrite your software from scratch.

That is a very good point. Even though, as the whole post does, even this quote does overshoot the target. There are EXTREMLY good points against rewriting from scratch. Nonono. Don't. It should read: "Seriously. The minute you’re successful, plan to rewrite your software. FULL STOP". Not from scratch, use refactoring techniques.

But the next sentence was the killer:

Plan to hire enterprise quality developers.

Now THAT's a WTF. Hahaha. I laugh, because it is so tragic. "enterprise"-anything is a marketing term. enterprise != quality. I am seriously getting allergic to that word and the misconception it carries along. Buzzword bingo galore! Well, what did I expect on a blog called "agile thinking". What is particularly funny is that he states "I’ve worked for two startups and consulted at several more.". All while he is seriously bashing startup developer AND suggesting that he does indeed know better. Now that is tragically funny. :) Just my kind of humor.

The sad part is that most symptoms he describes are actually management related. Not developer related. No developer enjoys the death march before a presentation. Those death marches are usually managment induced. Lack of requirements, incomplete feature lists, last minute changes, lack of sticking to decisions, ...

The requirements for developer don't change that dramatically going from a startup to a enterprise. What does change dramatically are the requirements for management. Going from 10 developer to 20 is a huge step. Going to 100 is different world. All the while it is true, not all developer that "have been with us all the time" should get promoted. But even that is a management decision. It's not the developer's fault. Move them to those team that should open up new business areas. That's where they belong and where they will most likely be most satisfied. And make a team of (newly hired!) quality asssurance professionals bundled with some (newly hired!) senior architects work on the legacy code base.

Good points:

  • There is a difference in business goals between startups and enterprises.
  • When you know you found your market, harden your business by hardening your codebase.
  • Not all developers are bound to become lead-anything.

Ugly stuff:

  • The title.
  • Overuse of the buzz word "enterprise".
  • Blaming the developer for most of these flaws.
  • Doing a complete rewrite without the old developers, that's the evil himself.
  • The three tests if you are "enterprise" or not are quite a lot of fun for all the wrong reasons.
February 12th, 2008 1:52 am | Comments Off

Source Structure (Part 2): The reference problem, or …

by Tobias Hertkorn on February 10th, 2008

... trying to make up for yesterday's post.

Sorry, for yesterday's first part. I guess it does actually represent pretty well how torn I am. Even the damn post is non-linear. ;)

So, I guess I really do have to write down all the options, all the pitfalls and all the optimizations I see. Maybe that will clear up my vision. Oh, and I would love to hear from you, how you solve this mesh of interdependency not just between projects, but also between tools - and all that under the strict goal to maximize productivity and obstruct the flexibility as little as possible. And flexibility in my sense of the word means as well that it should enable me, if needed, to improve on dependant frameworks as closely as possible (direct project reference in my solution) and if not needed allows me to save build time by reference a specific version of said framework by assembly reference.

Since this reference problem is as good a starting point as any other of the problems I see when thinking about source structures and source management, I'll start my discussion right here, work my way through this problem set and come up with followup problems.

The reference problem

I guess it is time for some images to accompany my requirements. What did I mean by direct project reference versus assembly reference. Pretty simple:

Direct project reference:

SvnPlanning - Direct project referencing

Assembly reference:

SvnPlanning - assembly referencing

So, direct project referencing allows me to make any changes to the framework directly, without switching to a different Visual Studio. This situation is ideal for starting the development of the framework or for hunting down bugs. It will greatly improve my productivity in those two scenarios, because here I can closely look at the relationship between my application code and the framework code. And altering the framework code and observing the effect on the application is as easy as can be.

But since it is a framework it should be a slowly changing part of your overall application and assembly landscape. That's why I need the second mode as well, where I just want to reference a precompiled assembly. That has two reasons: One it saves on compile time, because the IDE does not have to check if anything changed, etc. Thus improving my productivity while developing my application. And two it prevents me from accidentely modifying a framework or compiling against an old version or the trunk version, just because I did not pay close attention to what I checked out of source control. Don't underestimate the second argument! Anybody who has spent time hunting down a weird bug - until discovering that he didn't check out the correct version of a framework, will tell you about sever self-inflicted bruises from banging heads on desks, etc. So I believe the second argument is actually the stronger one of the two, because it saves me from wasting time and energy on checking and rechecking if I use the right framework. Plus it is there simply because I am worried about my (and your) health.

Can we automate that transition? Digging into the .sln and .csproj files.

Please don't pay any attention to the file paths here. I will discuss it later, why these filepaths displayed here are actually very, very evil.

Direct project reference:

This results in following SvnPlanning.WpfSampleApplication.sln:

  1. Microsoft Visual Studio Solution File, Format Version 10.00
  2. # Visual Studio 2008
  3. Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SvnPlanning.WpfSampleApplication", "SvnPlanning.WpfSampleApplication\SvnPlanning.WpfSampleApplication.csproj", "{A9CDAFB6-9224-4064-9A04-01C68C957633}"
  4. EndProject
  5. Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Framework", "_Framework", "{25121969-C024-446A-9CED-92ABD1200DE5}"
  6. EndProject
  7. Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Com.Hertkorn.Framework.SampleFramework", "..\Com.Hertkorn.Framework\Com.Hertkorn.Framework.SampleFramework\Com.Hertkorn.Framework.SampleFramework\Com.Hertkorn.Framework.SampleFramework.csproj", "{8EEAC483-B09F-4771-8A29-EFCC01B029FA}"
  8. EndProject
  9. Global
  10.     GlobalSection(SolutionConfigurationPlatforms) = preSolution
  11.         Debug|Any CPU = Debug|Any CPU
  12.         Release|Any CPU = Release|Any CPU
  13.     EndGlobalSection
  14.     GlobalSection(ProjectConfigurationPlatforms) = postSolution
  15.         {A9CDAFB6-9224-4064-9A04-01C68C957633}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  16.         {A9CDAFB6-9224-4064-9A04-01C68C957633}.Debug|Any CPU.Build.0 = Debug|Any CPU
  17.         {A9CDAFB6-9224-4064-9A04-01C68C957633}.Release|Any CPU.ActiveCfg = Release|Any CPU
  18.         {A9CDAFB6-9224-4064-9A04-01C68C957633}.Release|Any CPU.Build.0 = Release|Any CPU
  19.         {8EEAC483-B09F-4771-8A29-EFCC01B029FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  20.         {8EEAC483-B09F-4771-8A29-EFCC01B029FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
  21.         {8EEAC483-B09F-4771-8A29-EFCC01B029FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
  22.         {8EEAC483-B09F-4771-8A29-EFCC01B029FA}.Release|Any CPU.Build.0 = Release|Any CPU
  23.     EndGlobalSection
  24.     GlobalSection(SolutionProperties) = preSolution
  25.         HideSolutionNode = FALSE
  26.     EndGlobalSection
  27.     GlobalSection(NestedProjects) = preSolution
  28.         {8EEAC483-B09F-4771-8A29-EFCC01B029FA} = {25121969-C024-446A-9CED-92ABD1200DE5}
  29.     EndGlobalSection
  30. EndGlobal

And following SvnPlanning.WpfSampleApplication.csproj:
(I skipped unnecessary parts. They are marked by [...])

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="">
  3.   [...]
  4.   <ItemGroup>
  5.     <Reference Include="System" />
  6.     <Reference Include="System.Core">
  7.       <RequiredTargetFramework>3.5</RequiredTargetFramework>
  8.     </Reference>
  9.     <Reference Include="System.Xml.Linq">
  10.       <RequiredTargetFramework>3.5</RequiredTargetFramework>
  11.     </Reference>
  12.     [...]
  13.   </ItemGroup>
  14.   <ItemGroup>
  15.     <ProjectReference Include="..\..\..\Com.Hertkorn.Framework\Com.Hertkorn.Framework.SampleFramework\Com.Hertkorn.Framework.SampleFramework\Com.Hertkorn.Framework.SampleFramework.csproj">
  16.       <Project>{8EEAC483-B09F-4771-8A29-EFCC01B029FA}</Project>
  17.       <Name>Com.Hertkorn.Framework.SampleFramework</Name>
  18.     </ProjectReference>
  19.   </ItemGroup>
  20.   [...]
  21. </Project>

Assembly reference:

This results in following SvnPlanning.WpfSampleApplication.sln:

  1. Microsoft Visual Studio Solution File, Format Version 10.00
  2. # Visual Studio 2008
  3. Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SvnPlanning.WpfSampleApplication", "SvnPlanning.WpfSampleApplication\SvnPlanning.WpfSampleApplication.csproj", "{A9CDAFB6-9224-4064-9A04-01C68C957633}"
  4. EndProject
  5. Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Framework", "_Framework", "{25121969-C024-446A-9CED-92ABD1200DE5}"
  6. EndProject
  7. Global
  8.     GlobalSection(SolutionConfigurationPlatforms) = preSolution
  9.         Debug|Any CPU = Debug|Any CPU
  10.         Release|Any CPU = Release|Any CPU
  11.     EndGlobalSection
  12.     GlobalSection(ProjectConfigurationPlatforms) = postSolution
  13.         {A9CDAFB6-9224-4064-9A04-01C68C957633}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
  14.         {A9CDAFB6-9224-4064-9A04-01C68C957633}.Debug|Any CPU.Build.0 = Debug|Any CPU
  15.         {A9CDAFB6-9224-4064-9A04-01C68C957633}.Release|Any CPU.ActiveCfg = Release|Any CPU
  16.         {A9CDAFB6-9224-4064-9A04-01C68C957633}.Release|Any CPU.Build.0 = Release|Any CPU
  17.     EndGlobalSection
  18.     GlobalSection(SolutionProperties) = preSolution
  19.         HideSolutionNode = FALSE
  20.     EndGlobalSection
  21. EndGlobal

And following SvnPlanning.WpfSampleApplication.csproj:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="">
  3.   [...]
  4.   <ItemGroup>
  5.     <Reference Include="Com.Hertkorn.Framework.SampleFramework, Version=, Culture=neutral, processorArchitecture=MSIL">
  6.       <SpecificVersion>False</SpecificVersion>
  7.       <HintPath>..\..\Com.Hertkorn.Framework\Com.Hertkorn.Framework.SampleFramework\Com.Hertkorn.Framework.SampleFramework\bin\Debug\Com.Hertkorn.Framework.SampleFramework.dll</HintPath>
  8.     </Reference>
  9.     <Reference Include="System" />
  10.     <Reference Include="System.Core">
  11.       <RequiredTargetFramework>3.5</RequiredTargetFramework>
  12.     </Reference>
  13.     <Reference Include="System.Xml.Linq">
  14.       <RequiredTargetFramework>3.5</RequiredTargetFramework>
  15.     </Reference>
  16.     [...]
  17.   </ItemGroup>
  18.   [...]
  19. </Project>

As you can see, it is quite straight forward to switch between the two modes. When switching from direct referencing to assembly referencing the tool has to remove stuff from the .sln and remove a ProjectReference and add a Reference in the .csproj. The switch from assembly referencing to direct referencing is equally straight forward. Btw: Right now I don't care about Visual Studio integration of the tool, I am fine with unloading the solution, running the tool to switch mode and re-opening the solution.

From looking at the stuff that needs to change between the two mode we can derive what the tool needs to know:

  • The location of the .sln
  • The location of the two .csproj
  • The GUIDs of the two .csproj
  • The mapping that SvnPlanning.WpfSampleApplication.sln contains "{A9CDAFB6-9224-4064-9A04-01C68C957633}" (SvnPlanning.WpfSampleApplication.csproj)
  • The mapping that version a.b.c.d of "{A9CDAFB6-9224-4064-9A04-01C68C957633}" depends on version e.f.g.h of "{8EEAC483-B09F-4771-8A29-EFCC01B029FA}" (Com.Hertkorn.Framework.SampleFramework.csproj")

With that information alone it could tailor the .sln and the .csproj to either reflect mode A or mode B.

Decisions necessary to support this tool (= TODO list)

  • Do we check in the ever changing .sln and .csproj files into subversion?
  • Do we only check in the meta data that is needed to create the .sln and .csproj files?
  • Do we only check in .sln and .csproj in a certain mode, e.g. only in assembly reference mode?

Related decisions

  • Where should the precompiled assemblies of the framework lie, directly inside the application path, e.g. in a lib directory or in a special assemblies folder structure?
  • Do we use the GAC as a very special assembly folder structure?
  • Who is responsible for making sure that those assemblies exist, are up to date and contain the latest bugfixes?
  • How does this play out on the continuous integration server?
  • Can we get debugging information even for precompiled assemblies?
February 10th, 2008 7:09 pm | Comments (2)

Where is a reasonably elegant .Net Source Structure setup tool, or …

by Tobias Hertkorn on February 9th, 2008

... why putting everything together is damn hard.

The current situation...

At work we are currently working on a nice and big project. But sometimes we have to implementing smallish products on the side. They tend to look quite similar, they all share some common self-coded frameworks and they usually have some external libraries they depend on (Castle, NHibernate, EntLib, ...). Then they have to be checked into SVN, they should be built and tested on our continuous integration, so an appropriate project should get created there, ... Then we need a handful of Domain Objects to do some persisting, usually fairly simple stuff, some services that exposes the "server-side" and finally a GUI.

As you can see even if only setting up a simple solution that is under source control and using continuous integration, even that already takes three totally different tools too setup. Creating the solution in VS, doing a initial checkin via tortoiseSVN and going to your build server via remote desktop and tweaking the configuration files. During all this I tend to make errors, because I am still thinking about an interesting function in the nice and big project. And I am hurrying along, since I want to get back to it. So ... I make small errors. Every projects looks the same, but is slightly different. And me being a physicist, I know that a small disturbance repeatedly applied can sometimes lead to severe consequences. ;)

So, now I created my basic simple solution, but it still lacks the Domain. So, I start adding a project for the domain, choose the right name in order to have a consistent , put all domain objects in the folder DomainObjects. Create the hmb.xml (first remember the syntax again), write the class, write the filtering, write the service, set up basic unit tests, ...

I hear you scream: Tobi, all you need here is code generation. Ha, but that's what I was waiting for, because that means ... I need a FOURTH tool.

And we are not done here. Because now we get into the area of external dependencies and common frameworks. Do I put all external libraries in a lib folder under my solution? What about my frameworks? Do I include precompiled assemblies? How will bugfixes in those frameworks propagate into my solution? Will I have two Visual Studios open while improving the framework for the current solution, one for the framework and one for the solution? Or will I put a direct project reference into my solution? How will that decision affect continuous integration? So now I go for msbuild or NAnt. A fifth tool.

Hmm, now I ranted for a couple of pages - and the conclusion is: Even setting up a simple project and starting performing very basic coding tasks is a quite lengthy and errorprone process. BUT it is quite a lot of boilerplate code/configuration that varies very little between different solutions.

What do I want...
... which most likely not what I need! We all know that problem.

<insertion topic="YAY for tooling">

Give me six hours to chop down a tree and I will spend the first four sharpening the axe.
Abraham Lincoln

I am inherently lazy, well actually not lazy, lazy, but I strive to maximize my efficiency. If I know I will have to do a task more than three times and implementing a solution will cut the time in half that I will spend on doing said task, I am going to invest in that solution. Did you notice that I didn't say how much time I invest in implementing that solution? ;) Well sometimes, ... No. Actually it never, EVER takes more time than brute forcing my way through the boring repetitive task. Ever! And it's more fun and I learn a lot! Ha! So there you have it, three great points in favour of implementing tooling:

  1. ... never takes more time than the boring repetitive task!
  2. ... is fun!
  3. ... teaches a lot! (sometimes how not to do it...)


Anyway, back on topic: I want to supply a product name, if applicable dependencies, one or more service names and associated domain objects.

Taking that information a tool automatically sets up a source tree, consistently adds those dependencies, creates the service, domain and tests for the service. It generates the build script necessary for an automated build and test, performes the initial checkin and adds the new project to the continuous integration server.

Right now I don't see any way around improving on the tools we started writing ourselfs. Because I have not come across a tool that would do these tasks in an efficient way. Maybe I am mistaken?

I have looked at a long list of available tools, but it seems none of them have the capabilities to span across multiple problem domains. Plus most of the available tools have hidious addin APIs. Is it just me, or does anybody else share the feeling that XML is in no way suited for process-based, procedural scripting, such as build scripts. They tend to get very ugly, hard to read and maintain.

Well, do you have any suggestions?

Read on:
Assembly referencing versus direct referencing
And there is more: Be aware of long project names, or ...

February 9th, 2008 2:49 am | Comments Off

What is “Code Smell”

by Tobias Hertkorn on May 20th, 2006

I bought Fowler's Refactoring a couple of month back. And I just love going back to it and reading chapters again and again. One of the most interesting phrases used in the book is "Coding Smell". And it is way easier to migrate legacy code, when your code is refactored and smells as little as possible. ;)

Today I stumbled across an excellent post concerning Coding Smells at Coding Horror.

To give you a short overview of what Coding Smells are - here is a quote from wikipedia:

In the community of computer programming, code smell is a jargon term used among programmers to refer to a symptom that indicates something may be wrong. It generally indicates that the code should be refactored or the overall design should be reexamined. The term appears to have be coined by Kent Beck on WardsWiki. Usage of the term increased after it was featured in Refactoring. Improving the Design of Existing Code

Determining what is and is not a code smell is often a subject judgment, and will often vary by language, developer and development methodology.

Common Code Smells:

  • Large method - a method, function, or procedure that has grown too large.
  • Large class - a class that has grown too large.
  • Feature envy - a class that uses methods of another class excessively.
  • Inappropriate intimacy - a class that has dependencies on implementation details of another class.
  • Refused bequeath - a class that overrides a method of a base class' such that the contract of the base class is not honored by derived class. See Liskov substitution principle.
  • Lazy class - a class that does too little.

Some links to articles about "Code Smell":

May 20th, 2006 12:23 pm | Comments (1)

Migrationpaths from legacy Visual Basic 6.0 to .NET

by Tobias Hertkorn on May 18th, 2006

There are a lot of problems converting a VB 6.0 app to .NET. So in a real life-time situation it is mostly not cost-effective to try and migrate everything in one step. Plus the programmers working on the project have to be trained in the new .NET language, C# or whatever. That calles for a slower approach. I call it Cross-Language Refactoring. The idea is to slowly replace performance critical or unmaintainable parts, while already implementing new features using the new language. Usually those new features interact with legacy code as well. So while the team is implementing a new feature, there is a chance to migrate those parts in the legacy code as well. This way the legacy code gets replaced bit by bit into the new object oriented world, while giving the team the time to get better at the new language.

I have a bit over 1 year experience in moving slowly from ASP to ASP.NET. There are a lot of problems there as well - but that would be a different article. Please feel free to contact me, if you need some pointers for that scenario. But this post will concentrate on moving a client app to .NET. Or at least start to do so.

There are two possible "slow" migration paths:

  1. Building a .NET GUI and integrating the legacy VB 6.0 through dlls
  2. Using the legacy interface and start replacing legacy modules by .NET modules

There are pros and cons to both approaches. The problem with the first migration path is, that it will use a lot of time to create a new GUI. On the other hand the second path will allow the user to still enjoy the old GUI and the old look-and-feel. But it is not an option when your GUI it too messed up, or is the reason why there is the need to migrate in the first place.

The MSDN-Magazin in May 2006 features an interesting article on how to make the second path possible:

Call Into The .NET Framework From Existing Visual Basic 6.0 Apps

Make sure to check it out before you are considering to migrate an application from VB 6.0 to .NET. Maybe a slow Cross-Language Refactoring approach is right for you as well.

On a different note: I would advise you to NOT move from VB 6.0 to VB.NET, but instead from VB 6.0 to C#. It turns out the programmers learning the new concept of object oriented programming, are way better at producing good code, when having a visual difference between the languages. When using VB.NET it is too tempting to use the old VB 6.0 "style" of programming and therefor neglecting patterns and oo design principles.

May 18th, 2006 3:15 pm | Comments (2)

The Bazaar and the Cathedral

by Tobias Hertkorn on May 7th, 2006

Well, I just watched Revolution OS. It is a documentation about Linux done in 2001. To quote form their website:

REVOLUTION OS tells the inside story of the hackers who rebelled against the proprietary software model and Microsoft to create GNU/Linux and the Open Source movement.

I really liked the presentation, being a Linux user, hacker and fan since about 1996. Yep, I just got up, walked over to my bookshelf and there it still was. "LinuX Anwenderhandbuch und Leitfaden für die Systemverwaltung" loosly translatable to "Linux Userhandbook and Guide for System Administration". So it is a beginners book to Linux. And it was clearly written by hackers for hackers. Ah, the good-old-times. ;) Well, anyway, to get back to my topic:
The Bazaar and the Cathedral, an essay by Eric S. Raymond is mentioned in that documentation and I just thought, well that might just sound like the beginning of the agile and/or extreme programming movement, whose philosophy I started using at the webdevelopment team of experten-netzwerk about 2 years ago. And it got me quite excited, because I think it is always fun to have an unfiltered look at the unwatered inspiration that leads up to "movements".

Well, it basically is a compilation of very simple principles, but that's the beauty. I needed it written down. I did use some of the points talked about by instinct.

  • Given enough eyeballs, all bugs are shallow.
  • Constant feedback is good. Instant gratification.
  • Bugs don't drive users away.
  • Be chatty with your mailing lists. Don't just send release notes to the mailing list. Let the mailing list come up with solutions or help you choose between possible solutions. Aquire beta testers. Recognize good ideas from other people.
  • Release early, release often, listen to your customers.

As I said very basic ideas, but even going through this simple list, I do stumble over a couple of points that need or needed improvement in my current or former projects. So that got me really interested and fortunatelly I continued reading. And I would encourrage you to do so as well. It is quite a remarkable read. For those who are not willing to do that, even though I just told you to do so (I do promise you some egoboo! Ha, read on!), here is a short summary

Linus and therefore Linux uses a very different communication pattern than traditional software projects use. The major problem of large projects is scalability, known as the n-squared complexity cost. Linux has a starshapped communication pattern, with basically a lot of programmer talking to one guy. This means that there are a lot of people basically working for one guy (Linus). But how can people get motivated to put a lot of effort, work and spare time into a project?

What motivates hackers?
Basically projects don't start in bazaar mode. The code must have a plausable promise. It must promise that given a certain amount of work, it will become brilliant. Based on this promise the interest in the project must be nurtured the produce a "critical mass" of people that are working for the project, by code, testing or giving feedback. The trick is: People are playing for reputation. You don't take up the title hacker yourself. That's a title other people assign to you.
Raymond goes on and uses some definitions from anthropology: The internet culture is comparable, if not exactly the same as a gift culture: People gain status by giving things away and everybody plays for reputation. Usually that translated into gifts or food. But when it comes to the internet culture it translates to: Give away free time, energy and skill in order to look good in front of other hackers. People play this game for reputation. Knowing this, it is easy to optimize the management strategies of open source project. Make sure you motivate your users, testers and programmers by promising them knowlegde, skills and standing in front of other hackers. Raymond uses the term Egoboo used mainly in the SciFi community. The goal in a free software project is to create and nurture a gift culture. This is the ideal way to operate without force in an anarchy kind situation.

Just a tip: Listen in on the talk by Raymond. Link is on his website.

Well, is the paper a bit optimistic? Maybe. ;) Did it start the Extreme Programming or Agile Programming movement? Maybe not. I did start reading the article to get some new ideas for my managing. Did I get those? Hell yeah! Read between the lines and learn a lot about motivation. Industry projects do lean too much on pressure as far as I am concerned and should look at the OSS to find out about reputation, reward and ... fun. ;)

May 7th, 2006 6:36 pm | Comments Off
Tobi + C# = T# - Blogged blogoscoop