October 2004 - Posts

Build and Deploy with NAnt in Rockville on Thurs 4th November
Tuesday, October 26, 2004 10:56 PM

I will be presenting on NAnt and how to use it to build and deploy your software - the session will touch on the commonly used tasks and how to use them in your integration process.  It promises to be a great jumpstart for the NAnt newbie and may even show the seasoned NAnt'er a thing or two - such as C# scripting in NAnt and building your own custom tasks.

NAnt is a wonderful extensible framework for doing all sorts of things - so come along ...

The event will be held at the WinProTeam Rockville (Maryland) User Group on 11/4 at 6:30pm.

[Updated link - thanks Dylan]

When Refactoring is YAGNI ...
Tuesday, October 19, 2004 12:28 AM

I attended a Washington DC XP UG (WDCXP) meeting tonight for the first time.  It was a small turnout with Bryant Smith presenting on DIP (Dependency Inversion Principle) with a slant to persuading new developers to adopt agile techniques through design patterns.  The discussions were interesting and varied wildy across different aspects of design patterns and XP.

One question that has been bugging me with the project at one of my clients is the case for Refactoring.  As TDD developers, we all know that Refactoring is essential to atone for the sins of DoingTheSimplestThing.  But how do you reconcile the time spent refactoring with the features that the customer would have to give up for that time?  I am not talking about the little ExtractMethod or IntroduceExplainingVariable here - those are quick and easy ... I mean realizing a design pattern is now needed and implemented it.  The refactoring tools are very limited in the .NET world at the moment - meaning that this refactoring will have to be done by hand and then tested (with your existing suite of tests, of course!).  It is easier to just TODO the item and move on, especially when under a time crunch.  This accumulates a burden of TechnicalDebt as the project runs its course.  I wrote a little custom NAnt task a few months back to traverse our source code and put together a list of the all the TODO items - there are around 300!

Adam (a member of WDCXP) suggested two possible solutions:

  1. Force refactorings to be done before checking the code in
  2. Add needed refactorings when next a feature is added to that subsystem

Forcing the refactorings doesn't solve the lost time for other features problem.  I like the adding the refactorings as code is changed but I still feel a lot of those TODOs will be left undone.  Maybe that is OK?

Please note that this system and associated project is highly successful and is loved by developers and users alike (despite the many remaining TODOs).

How do you reconcile your time refactoring against lost value to the customer?

UPDATE:  More food for thought ... RefactoringTrumpsYagni ?

Bill Gates mentions Automated Testing Tools in his view of the future
Monday, October 18, 2004 1:44 PM

Scoble points to this article ("The Enduring Magic of Software") by Bill Gates in which Bill states:

"... we're already seeing the benefits of automated testing tools that can verify code and help eliminate common security vulnerabilities ... "

Admittedly it was only part of a sentence in a 2 page document, but still!!! :-)

 

Passed Certification 70-315 - Web Apps with C#
Saturday, October 16, 2004 1:06 PM

Just passed 70-315 this morning!!

The problem with certifications is they often ask about stuff you never use (for one reason or the other) so you have to know everything.  I used Amit Kalani's training guide to prepare for the exam which is a very thorough analysis of the material with lots of step-by-step exercises and good sidebar hints for exam questions.  My only complaint about the book is the size - it is 1200 pages and weighs over 4 pounds!  I wish they would have split it into a 5 book pack.  Reading the book on the bus and metro this last week was really uncomfortable and who has time to sit down at a table to read a book these days?

The NDA prohibits discussing the exam questions (for good reason).  Let's just say that it was reasonably challenging especially in the variety of topics asked.

Next:  SQL Server or WindowsForms.   Hmmmm...

by thycotic | 3 comment(s)
Filed under:
TDD Interview with Capital Area .NET
Friday, October 15, 2004 10:48 PM

A series of interview questions and answers have been posted by the Capital Area .NET User Group as a followup to the presentation I gave at their user group in July.  The questions are quite probing and make a good introduction to TDD for both the newbie and the skeptic.  Feel free to comment on their site with thoughts from your own experiences!

Kudos to Hal Hayes and the team at the Capital Area .NET User Group for such a great idea and wonderful followup!

Pair Programming - The Ultimate Setup and the other options we tried.
Wednesday, October 13, 2004 11:41 PM

We have tried various equipment and configurations at my current client to determine the optimal pairing environment.  Such as:

  • Sharing one workstation
    • Pros: ? :)  (maybe cost and office space)
    • Cons: Only one keyboard/mouse for input, difficult to see screen, no privacy, cramped
  • LCD Projector
    • Pros: Highly visible
    • Cons: Limited lifetime, setup and lamp cool down time, unavailability of projector, no privacy
  • VNC'ed notebooks
    • Pros:  Two keyboards/mice for input, own screen for viewing
    • Cons: No privacy for the desktop sharer, powerful notebooks are very expensive, interfering non-development applications (IM, Email, etc)

So, what did we finally settle on?

Ultimate Pairing Setup!
  • VNC'ed notebooks to one powerful desktop pairing station and two large LCD monitors!
    • Pros:
      • Cheap powerful workstation (under table) for compiling and running tests
      • Highly visible - big 17" LCD screen for watching pairing desktop
      • Privacy - own notebook screen for email, IM, etc.
      • Pairing workstation has only the development essentials plus a "pairing" IM account
    • Cons:
      • Cost of the powerful workstation (although much cheaper than keeping notebooks upgraded)
      • Takes up more office space

Performance Tip:  Our LCD monitors have dual inputs so we put the one from the workstation and one from our notebooks.  This allows us to use VNC while actually looking at the real signal from the workstation which helps if VNC gets laggy. (Bob figured this one out!)

Thanks to my colleagues, Bob and Mark for their input in our experiments and to Ed for funding everything!

What are your experiences with Pair Programming configurations?

UPDATE (10/14/2004)
Jeff
- we set VNC to take inputs from both keyboards and mice, this eliminates the otherwise annoying "no, no ... over there!" (while pointing frantically at your own screen which your partner can't see!).  This allows either person to "chime" in at any point and probably increases productivity even further.  We also like the sitting across from each other as this facilitates better communication - you can just look up and talk directly to your pair. Another interesting challenge of the dual VNC for input is that you all share a global clipboard which can get interesting if someone has to fire off a quick email or something ... :-)
Will - Both of those are Acer Ergonomic keyboards (both are exactly the same model).  It is my favorite ergonomic keyboard so I picked up 3 from Ebay and hoarded them since they don't make them anymore. :-(

C# - NAMED LOOPS ... I miss them.
Tuesday, October 12, 2004 9:56 AM

Named loops give the ability to extend flow control with markers.  Cynics would argue they are glorified gotos but in that case, they probably don't like continue anyway!

Here is a simple contrived example:

1namespace NamedLoopExample 
2{
3 public class NamedLoops
4 {
5 public void Example()
6 {
7 Product[] products = new Product[] { new Product() };
8 Sku[] skus = new Sku[] { new Sku(), new Sku() };
9 // in Java: ProductLoop: for (int n = 0; n < products.Length; n++)
10 for (int n = 0; n < products.Length; n++)
11 {
12 for (int i = 0; i < skus.Length; i++)
13 {
14 // find the right sku
15 // continue with the next product not sku
16 // in Java: continue ProductLoop;
17 }
18 // some other logic to do something else
19 // since the sku wasn't found
20 }
21 }
22 }
23 public class Product { }
24 public class Sku { }
25}


Named loops are not something you need very often, but occassionally they are useful. The alternative
of tracking a bool to know when to break is really ugly.  Often you can refactor the logic possibly into separate methods (with Extract Method) to make the flow easier to manage.

Does anyone else miss named loops?

UPDATE (10/13/2004):  There is a great discussion of GOTO that also references named loops on the C2 wiki.

by thycotic | 3 comment(s)
Filed under: ,
TDD Teaser #2 - Think you know NUnit?
Monday, October 11, 2004 8:12 PM

I recently concluded a TDD with ASP.NET presentation in Cleveland with several TDD Teaser problems for the audience.  The idea proved to be a lot of fun so I decided to repost the problems on my blog.

The Rules:

  1. Prize (a Thycotic keyring light) to be mailed to the first comment with the correct answer on this blog post with valid contact information.
  2. My definition of the problem is the correct one. :)  Other answers might be right but won't win the prize.
  3. I will post the answer within a few days.

What is wrong with running the following Test?

1using NUnit.Framework;
2
3namespace UnitTests.BadCode
4{
5  [TestFixture]
6  public abstract class Problem2
7  {
8    [Test]
9    public virtual void TestSomething()
10    {
11       RedHerring @int = new RedHerring();
12       Assert.AreEqual(1, @int.BogusNumber);
13    }
14  }
15  public class RedHerring
16  {
17      public int BogusNumber;
18  }
19}

UPDATE:  I am looking specifically for an error rather than a test failure.

Winner: Kirk Marple

Answer & Discussion (click and drag your mouse to see the answer)
Duncan - you are right. The value of BogusNumber would initialize to zero as it is an instance variable. I was looking for an error though not a test failure.

Answer:
NUnit creates an instance of the TestFixture labeled classes when it runs and calls their Test labeled methods. It cannot create an instance of an abstract class so it will ignore it in the NUnit GUI (Problem2 won't even appear). However using the NUnitAddIn and selecting to run the individual Test will cause the error that the instance can't be instantiated. Abstract classes are very useful when refactoring your test suites. We get bitten by this little quirk all the time on our projects when an inherited test fail in the unit test report and the first thing we do is try to run the individual test on our workstations.

Well done to Kirk for the first correct answer.

Well done also to Ron Buckton and Vishal Narayan Saxena for elaborating on the answer!
C# - Why Overloads Instead of Optional Parameters? And AOP.
Friday, October 8, 2004 12:48 AM

I just came across an old post on Dan Fernandez's blog that links to the "Whiteboard with Anders" session from TechEd 2004.  I was lucky enough to watch this event live.  One of the memorable questions answered - one that I often hear from ex-VBers - is why C# uses overloads instead of optional parameters ...

Watch the video because it has lots more, but here is the answer from the transcript:

Hejlsberg:

"Okay. The question is, Why don’t we have default parameters? I think there are a couple of reasons. First of all, they’re somewhat duplicative of overloading. I mean you can do the same with overloading, and which is indeed what people do today, but yes, you’re right. It’s more typing for sure. I think the other one is subtler, and in retrospect maybe not as important as I thought. Originally in the language design are- our issue with default parameters is that they burned the default into the call site as opposed to leave it up to the implementation. If you do overloads, let’s say you have void f, and then, let’s say, you have void f of index, for example, and void f of index is where the work happens, right? Then in this guy here, you simply say echo 5, because your default is 5. When the user calls f, it is up to you to change- you can change what your default is later in v2 of your API. When you have a call f somewhere, this by the compiler is translated into f of 5 in the call site, because it just copies that value. Now you can never change the default. This gives you more flexibility, but- and I thought that that was important. Perhaps it’s not all that important, but ... "

There was also an interesting informal discussion after the session where Michael Palermo (my co-volunteer in the development cabana that day) was discussing the AOP questions with Anders.  Anders was not aware of some AOP experimentation that had been done with C# using some Remoting mechanics (System.ContextBoundObject) - Michael couldn't remember the source at the time.  I remembered it being from an old MSDN article that a colleague had once shown me.  It is worth looking at the sample to see how it works - plus it was a good feeling to be one up on Anders! :-)

by thycotic | 1 comment(s)
Filed under: ,
Inheritance in types returned by a WebService - good or bad idea?
Thursday, October 7, 2004 6:48 PM

Simon Guest posted a list of his Top Ten Tips for WebService Interoperability which is a wonderful resource if you are building a webservice that will be widely used. 

Unfortunately the list doesn't advise about inheritance in the types that are returned from a webservice.  This sounds like a no-no ... why would you make something any more complicated than it needs to be, right?  However, it can often make a lot of sense in your business data.  For example, say you have a large object graph for input to one of WebMethods - another WebMethod returns the same data plus more output information.  Wouldn't it make sense to have a specialized subclass that inherited from the base object and provided the extra output information?  We tried this but got burned alive trying to define the schema validation for the output data.

Contrived Example:

[WebMethod]
public int PlaceOrder(OrderRequest order)
{   // return order number
}

[WebMethod]
public Order RetrieveOrder(int orderNumber)
{   // return order with additional info
}

public class OrderRequest
{
   public int Quantity;
}

public class Order : OrderRequest
{
   public string CurrentStatus;
}

<xs:complexType name="OrderRequest">
  <xs:sequence>
    <xs:element name="Quantity" type="xs:int" />
  </xs:sequence>
</xs:complexType>

<xs:complexType name="Order">
  <xs:complexContent>
    <xs:extension based="OrderRequest">
      <xs:sequence>
         <xs:element name="CurrentStatus" type="xs:string" />
      </xs:sequence>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

I am having a difficult time getting it to work correctly within a .NET environment.  Are other people doing things like this?  Does it work on other platforms?

by thycotic | 4 comment(s)
Filed under:
More Posts Next page »

This Blog

Syndication