Welcome to HDRI Community Site Sign in | Join | Help

Jay Kimble recently put up a great post about 'Git R Done' coding (great title) to call elitist shenanigans on the TDD/Agile/ALT.NET crowd (with whom I'd have to side with on most arguments) for a lot of recent preaching and Mort-bashing.

I must say, Jay's post strikes a chord with me -- in my seemingly-vain attempts to maintain some semblance of TDD/Agile/ALT.NET in my multi-project, many-meetinged day, I frequently find myself asking "is this all worth it? Wouldn't it be easier to sling some VBA in Excel for this?"

I posted two comments to his post, but I think they deserve their own post here (below)

In summary: In my mind, we software developers have to make a choice -- do we want to just keep Gitting R Done all the time like we essentially are today, or do we want to grow up and ENGINEER software for long-term stability and maintainability instead of just DEVELOP software to solve the immediate problem and damn the future? 


If you ask any Professional (yes, upper case 'P') to do something they know is wrong or will lead to disaster, they will tell you "NO!" -- Ask an Architect to place the walls such that they don't load the weight properly, or an electrician to wire the outlets in one big circuit, etc.

But it seems that everyone, including us developers constantly seem to delude ourselves that 'software is easy' when it's really not and needs to be treated with a measure of respect. Perhaps not so much like bridge building, but certainly like any other non-life-endangering engineering activity.

The problem with doing just what the customer asks you is that they're not aware of all the problems they're creating for themselves when they ask you to do X, Y, and Z and it's up to us to explain to them the risks and trade-offs and explain that you can't 'just' (just is a dirty word, I've come to find out) whip up this or that app based on Access because it won't be long before they'll have a data contention disaster and it'll be all your/my/whomever's fault for not pushing back and saying "NO!".

Git R Done is good, but not if the 'Done' involves endangering the customer's software's long-term stability.

No one takes software seriously, they treat it like an easy-built, easy throw away as-needed business tool and don't invest in long term, reliable, maintainable solutions.

And the only ones to blame for that is Us, the software developers, for not standing up and saying "NO!" when the customer asks for a gun to shoot themselves in the foot.

I think why many people slam on the designers and drag-n-drop and such is that it's an effort (no matter how successful this or that one may be) to move down the 'software is easy'.

I think we all need to stop deluding ourselves into believing that one day there will be drag-and-drop development and we'll never have to write a line of code.

MSFT has been promising that year after year, VB after VB, now XML-based BDUF framework after XML-based BDUF framework and we're really no closer. In fact, I seem to be writing more code, but it's much BETTER and REUSABLE code and I've found that BETTER and REUSABLE are infinitely more valuable than less-code-but-miles-of-tangled-executable-XML-and-designer-puke.

I think it bothers me, among others, that MSFT wastes heading down the never-ending, never-producing 'software is easy' road when they can finally give up and starting producing tools for the 'software is hard, handle with care' road which is the road many of us have started embarking upon with great success.

That we slam MSFT is a compliment to them, really. It means we have hope. We see glimmers of intelligent thought and huge promise -- squandered on tools which ultimately drag down the state of the art and do nothing to advance software engineering as less art than science.

EDIT: I forgot to link the 'just is a dirty word' part to Gary Sherman's blog. Sorry Gary, I really did mean to do that!

I recently installed Vista RC1 on my tablet and couldn't get the Web Application Project MSI to install properly.

It turns out it needs to run as admin and the Vista 'allow privliged action' dialog apparently didn't fully take care of the problem.

I found this link helpful, I hope you do too!

http://richmercer.com/archive/2006/09/01/Installing-Web-Application-Project-in-Vista.aspx
I was just working on a project that had run-away Hungarian Notation

And I thought to myself, what if the rest of the world used Hungarian Notation?

"wfHoney, could you vrbPass me the tmtTomatoes so I can vrbPut them in this sldSalad I'm vrbMaking? thxThanks!"

I was working with some colleagues the other day and we stumbled across some old code that exhibited the switch statement code smell. It was a particularly concerning one since it existed inside a service-type class (i.e. NotificationService, SomeExternalSystemWeDontCareAboutService, etc). For a really simple example, let's say it was a currency conversion service. There was one piece of information the service needed from the focus object being passed in and then it was supposed to be able to deliver on its service requirements (converting the currency).

The primary method in this service took an implementation of an interface which allowed it to get the amount it was supposed to convert. Now, it should be noted that you probably wouldn't do this -- you'd just take the amount directly rather than an indirection interface. But please ignore that for this example. I want to focus specifically on the offending switch statement.

This class was not supposed to know about the specific implementations of the focus interface implementation being supplied. Over time, however, it evolved to have specific cases in a switch statement to actually get the money amount it was supposed to convert from the focus interface. This was good example, if slightly different in form, of a Leaky Abstraction as described by Jeremy Miller in his recent blog post on the subject.

The code went a little something like this (incriminating names of interfaces and methods changed to make the sample easier to understand):

public decimal ConvertCurrencyFromItem( IFocusItem item)
{
    //... uninteresting code

    decimal amount = 0.0M;

   
switch(  item.GetType().Name )
    {
        case "SomeStateThatHasWeirdConversionLawsImplementation":
            //... These guys have to have some pre-processing before we can convert

            amount = ... // some specialized code

            //... uninteresting code
            break;
        case "SomeGovernmentAgencyWithNoTaxImplementation":
            //... These guys get some weird tax rules applied

            amount = ... // some specialized code

            //... uninteresting code
            break;
        case "SomeCompanyThatGetsASpecialRate":
            //... We have a special deal with these guys, they get below-market rates

            amount = ...
// some specialized code

            //... uninteresting code
            break;
        default:

            amount = item.Amount;

            //... uninteresting code
            break;
    }


    //... uninteresting code that does the conversion using the 'amount' variable

}

This code would certainly be used on a new project they were planning and I recommended it as a good candidate for high priority refactoring going forward. I suggested using the Strategy Design Pattern to remove the specific knowledge of each implementation out of the service, while still letting the service do what it was supposed to do (convert currency).

Now, keep in mind this is a contrived example, so you might have a completely different (and better solution), but I'm just trying to illustrate how/when you might use the strategy pattern.

Let's start with our basic strategy interface

public interface IGetAmountStrategy
{
      decimal GetAmount( IFocusItem item );
}

Next, we get rid of our switch and move the specific logic into separate strategy implementations.

public class SomeStateWithWeirdConversionLawsStrategy : IGetAmountStrategy
public class SomeGovernmentAgencyWithNoTaxStrategy : IGetAmountStrategy
etc, etc, etc

And then you'd probably have the default strategy:

public class DefaultAmountStrategy : IGetAmountStrategy
{
      public decimal GetAmount( IFocusItem item )
      {
            return item.Amount;
      }
}

Our ConvertCurrencyFromItem method now looks like:

public decimal ConvertCurrencyFromItem( IFocusItem item, IGetAmountStrategy amountStrat )
{
    //... uninteresting code

    decimal amount = amountStrat.GetAmount( item );
    
    //... uninteresting code

}

An important benefit to using this refactoring is that ConvertCurrentFromItem is now quite easy to test. We can mock both the IFocusItem and IGetAmountStrategy dependencies and test only what we want to test: The currency conversion. Before, with the switch statement, we had to test all the special amount-getting cases in addition to the actual currency conversion.

So I was writing a 1.1 ASP.NET app, and I kept getting this pop-up/alert (from client-side JS) in the browser:
"Unable to find script library '/aspnet_client/system_web/1_1_4322/WebUIValidation.js'. Try placing this file manually, or reinstall by running 'aspnet_regiis -c'."
I googled this message and found all sorts of cures and I tried them all, to no avail.

Add this as one more possible solution. I checked my HTML source and I found this near the top:

<script language='javascript' src='scripts/WorkScheduleControl.js'/>    
<script language="javascript" type="text/javascript" src="/aspnet_client/system_web/1_1_4322/WebUIValidation.js"></script>

Note the "/>" on the end of my script tag? Yeah, that's the culprit. IE didn't load the second script tag, and thus didn't ever load WebUIValidation.js.

Even though I had the DTD set to xhtml1-strict, IE still doesn't support self-closing tags for the <script> tag apparently.

Changing my <script> declaration to <script lan....></script> fixed the problem!

Hope this helps someone and saves them a few hours of grief.
One of the frustrating things about dealing with SQL Reporting Services is the fact that they're hard to use from your own app. There is the ReportViewer control which is handy, but still cumbersome if your users just want to get a quick PDF dump of some list they see on the screen. It turns out, there's an easier way!

I found out that all the ReportViewer does is create a simple IFRAME and most of the work is in constructing the URL.

So on my ASPX page, I put a simple hyperlink control:

<asp:HyperLink id="reportLink" runat="server">Export to PDF</asp:HyperLink>

Then, in my code-behind, I set the NavigateUrl property to the report URL. For example:

string serverRootUrl = "http://localhost/ReportServer";
string reportFolder = "/MyReportFolder/";
string reportName = "SomeSummaryReport";

string rsUrl = String.Format(
"{0}?{1}{2}&YourParamNameHere={3}&rs%3aClearSession=true&"
+ "rs%3aFormat=PDF&rs%3aCommand=Render&rc%3aToolbar=False",
serverRootUrl,
Server.UrlEncode(reportFolder),
Server.UrlEncode(reportName),
Server.UrlEncode(paramValue) );

reportLink.NavigateUrl = rsUrl;

You can add as many parameters as your report takes (by using the "&ParamName=ParamValue" syntax), or you can leave them off entirely if you report requires no parameters.

When the user clicks the link, the PDF will be presented to them (either in-browser, or they will be prompted to download or save the PDF depending on how their Acrobat settings are configured).