RSS
 

Archive for November, 2009

Fun with Generics

30 Nov

Generics were a great addition to .NET but sometimes their behavior can be unexpected.  Check out these somewhat unintuitive bits.

Static Constructors

Consider the following class with a static constructor:

        
public class GenericDemo<T> { static GenericDemo() { Console.WriteLine("static (shared) constructor"); } public void SayHello() { Console.WriteLine("Hello!"); } }
 

Given the following usage of the type, how many times is the shared constructor called?

 

            1:  public static void Main()
            2:   {
            3: 
        
            4:   GenericDemo<string> instance1 = new GenericDemo<string>();
            5: 
        
            6:   GenericDemo<string> instance2 = new GenericDemo<string>();
            7: 
        
            8:   GenericDemo<int> instance3 = new GenericDemo<int>();
            9: 
        
           10:   GenericDemo<float> instance5;
           11: 
        
           12:   GenericDemo<double>.SayHello();
           13: 
        
           14:   }

 

The answer is 3 which makes sense if you think about it.

This gets at the heart of what generics really are.  Static constructors are only called once (single threaded assumed) per type when first instantiated or when invoking a static method.  So lines 4, 8, and 12 exclusively manipulate new types for the first time and trigger the call.

Overloading

Consider the following declaration.

        

public class GenericDemo2<T> { public void SayHello(T myinput) { Console.WriteLine("generic overload invoked"); } public void SayHello(string myinput) { Console.WriteLine("string overload invoked"); } }

Will it compile? It surprised me that this is indeed valid and does not throw a runtime error if T is a string.  If called when T is a string, it calls the non generic method every time.  Interestingly VB does not allow this to compile because its implementation varies slightly.

How about this which uses generic methods:

        
public class Example3 { public void SayHello(string toSay) { Console.WriteLine(toSay); } public void SayHello<T>(string toSay) { Console.WriteLine(toSay); } }

 

It looks like there would be a conflict and the compiler would reject the overload.  But it does compile!  The T is a true parameter and gives it a different signature!

 
No Comments

Posted in C#

 

Socrates on SOLID: The Open/Closed Principle

25 Nov

This is the third in a series of (hopefully) amusing posts into Robert Martin’s SOLID principles.  It’s written as a dialog between Socrates and a student named Loej in the spirit of the dialectic method popularized by Plato.  In this post, the principle explored is the “Open / Closed Principle”.  I hope you find this enjoyable.

Socrates, who is the narrator of the dialogue.
Loej, who is but a bit of sand in the maelstrom of software development.

Socrates:  Welcome again Loej.  Last time we discussed the Single Responsibility principle.

Loej:  Yes.  We agreed that, in general, each class should have one responsibility; each class should have only one reason to change.

Socrates: Excellent. My question today is this.  Have you ever experienced technological 20/20 hindsight?

Loej:  You mean regret a technical decision?  Of course.  I think all software developers have.

Socrates:   I’m talking more about clarity, not regret.  Have you ever had a better understanding of the domain or a customer’s needs as you progress through development.

Loej:  That usually happens as we go along during our iterations.

Socrates:  What about after deployment?

Loej:  That happens to.  Often times once a product is in the wild we gain a lot of insight and get a lot of feedback from customers. If we can, we try and refactor the code to incorporate feedback.

Socrates:  Let’s clarify something.  You can’t refactor code to incorporate change. Refactoring is a transformation of code that improves software design but does not change software behavior.

Loej:  Oh.

Socrates: Anyway, So what you are saying is to use your newfound clarity, you rewrite the code to change its behavior.  That’s fine during a fluid design of new code, but what about existing code that has stabilized, like after you have deployed?

Loej:  Well, it’s usually no biggie. You just need to look over the whole project and make sure you don’t break anything when you rewrite.

Socrates: How are you sure you didn’t break anything?

Loej: You have to check all of the dependent classes.

Socrates: Check?  You mean test?

Loej: Right. Check, test, just make sure it still works right.  And you may have to do some rewrite some tests too.

Socrates: But doesn’t this risk breaking your existing functionality?

Loej: Well, you can’t change existing behavior in a class without rewriting its code.

Socrates: That is true, but you reisk breaking something.

Loej: Then what are you supposed to do?  You said we are changing the behavior of the program.

Socrates: Well, if you can’t change existing code in an existing class?

Loej:  I get it.  You want me to say create a new class.  But then you’ve got all these dependencies pointing to the old class. You will have to recode those dependencies to point to the new class.  You are still rewriting lots of existing code.

Socrates:  What a conundrum.  I propose instead of scurrying to cover new functionality here and there you incorporate the Open/Closed principle into your design.

Loej: Ok I’ll bite. Just what is the Open/Closed principle?

Socrates: The Open/Closed principle states that Software Entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.  A modern interpretation would say that a class’s public facing interface should never change.

Loej: That sounds like Poppycock.  Every time you want to make a small change you would have to create a new class.  That’s a whole lot of work.

Socrates:  Ah, but we lucky .NET programmers have the luxury of interfaces.

Loej: How does that help?

Socrates: By using interfaces the parts that shouldn’t change don’t need to  We solidify the public facing parts in interfaces and agree to only use those interfaces.

Loej:  Ok, let me think about this.  You’re saying if I need to change behavior I create a new class and implement the existing interface?

Socrates: Yes.

Loej:  And if I need to add functionality to an interface?

Socrates: You don’t change the interface.  You create a new interface, possibly deriving from the old one.

Loej: I’m not convinced. You still have to change that code somewhere – the bit that bind classes to interfaces.  I mean somewhere you have to wire everything together and new up the instances.

Socrates: You’re right.  There is a problem of tying everything together, and that opens up a whole new discussion about abstract factories and dependency injection.

Loej:  Ok, I can put that aside for a second. But you still haven’t convinced me.  I see a maintenance nightmare.  I see ICustomer1, ICustomer2, ICustomer3…

Socrates: Which brings us back to the single responsibility principle we discussed yesterday.  If each class truly has a single responsibility, a single reason to change, that won’t happen.

Loej:  Hmm.  I’ll have to ponder it.

Socrates:  I see this as a technical debt mitigation technique. During initial development interfaces are rightfully in flux and should be more fluid.  As things stabilize though, this principle becomes important.   Still, it doesn’t take much additional effort to correctly apply this principle.

Loej: Well, interesting as always.

Socrates: Indeed.  Until next time.

 
 

Socrates On SOLID: The Single Responsibility Principle

24 Nov

This is the second in a series of (hopefully) amusing posts into Robert Martin’s SOLID principles.  It’s written as a dialog between Socrates and a student named Loej in the spirit of the dialectic method popularized by Plato.  In this post, the principle explored is the “Single Responsibility Principle”.  I hope you find this enjoyable.

Socrates:  Welcome again Loej.  Last time we agreed that software development is, as Steve McConnell puts it, a wicked problem.

Loej:  Right.  We have to solve software problems again and again to get them right.  This means change is an inherent part of the software development process.

Socrates:  And we agree that when we write code, we must anticipate change in order to manage complexity.

Loej:  Right and managing complexity is the fundamental concern of software engineering.

Socrates:  Very good.  When we talked before you said that in your experience, even a simple change can be difficult to make and may cascade into unrelated changes.

Loej:  Right. I remember when our company went international we had to add a shipping country for just about everything.  Products, customers, you name it.  I mean dragging the new fields to our forms was easy enough.  Master are you OK?

Socrates:  (Shivers) Continue…

Loej: But then we had to change the database code in the Customer form, the Product form, and the Supplier form. And we had to change our validation controls on all the forms.

Socrates: And?

Loej:  We introduced a defect. But at first we thought it was a bug with our printing object.

Socrates:  Your printing object?  How’s that?

Loej: We had an object which printed everything out.  It did things like PrintW2, PrintCustomerInvoice, PrintAddressLabel, stuff like that.  All of a sudden invoices and address labels stopped printing!

Socrates:  Did you track it down?

Loej: Yes after a few long days.  It turned out that we were writing a null to the customer table and when we retrieved the customer from the database in the Printer object, we got back a null as well.  This null was being appended to the address string and this caused the printer to not print!

Socrates:  Ouch.

Loej: Yeah bad memory.

Socrates:  No pun intended?

Loej:  Hmm?  Oh, no.

Socrates: I see.  Let’s start at the beginning.

Loej:  Sounds good.

Socrates:  You had one user directed change, to internationalize shipping, but this change required you to change some really big classes.

Loej:  Right.

Socrates: And in doing so you introduced a defect.

Loej:  Right again.

Socrates:  And the defect was originally thought to be in the Printer object, which was also a large class which did all things printer related.

Loej:  Yes.

Socrates:  If the printer class had been simpler, would it have been easier to debug?  Easier to test?

Loej: Well, that code would just need to be somewhere else.

Socrates: Right, but would you have had to look so hard to find the defect?

Loej:  You mean if we had a class whose job was to just print customer invoices? And a class just to print address labels?

Socrates:  Exactly.

Loej:  But wouldn’t this violate the don’t repeat yourself principle, you know, DRY?  I mean wouldn’t we need a bunch of code repeated in each of those little classes?  And doesn’t a bunch of little classes add complexity which we were trying to mitigate in the first place?

Socrates: Good questions. Let me address your first concern, DRY.  Why do you think it would be violated?

Loej: Well, we had methods in the printer object that formatted strings and checked that columns were correct and all that stuff.  All of these things relied on shared methods in the printer object.  We’d have to duplicate that in every new object.

Socrates:  Would you really?

Loej:  Oh, you’re suggesting we could keep those things in the printer class?

Socrates:  Or a couple new classes.

Loej:  Ok I get it.

Socrates:  Right.  So let’s not worry about DRY.  Now about your second concern, bunches of little classes.

Loej:  Right, we would have like 20 classes instead of one.

Socrates: And this adds complexity?

Loej:  Totally. I mean who can keep track of 20 things in their head.

Socrates:  Would you rather keep track of 20 classes or 20 methods of one class?  Isn’t this really the same thing?

Loej:  Well, there are a lot more files around.

Socrates: Could you use folders to simplify that?  And don’t multiple small files work better with your revision control system anyway?  And don’t modern IDEs take care of this?

Loej:  Points taken.  But automatic completion would become a mess…

Socrates:  What about using namespaces to handle that?

Loej: Ok.  So there’s not much difference in terms of complexity between twenty methods and twenty classes in modern software development with modern IDEs.

Socrates:  And actually using namespaces and folders you can simplify things more with separate classes than you can a single monolithic object.  Let’s move on then.  We agreed earlier it’s easier to find defects if they are more focused.

Loej:  Right.

Socrates: Would it be easier to not inadvertently introduce defects if objects were smaller and more focused?

Loej:  I suppose so.

Socrates: So would it make sense to divide up your validation logic, display logic, data logic, and business logic into separate classes?

Loej:  Well it would have made it possible to do some testing.

Socrates: Taking this idea further, what if each class had a single responsibility.  If each class just did one thing?

Loej:  That would make it easier to test.  But how do I know when I’m done dividing things up?  How do I know when I’ve got the right level of granularity? I mean, our printer object only handled printing.  And our forms only did one thing.  Like the supplier form handled suppliers. I mean at some level of abstraction, everything only does one thing.

Socrates: Well what do you mean when you say the printer object only handled printing?

Loej:  In the case of the printer object it meant that it only handled printing.  It printed invoices and it…

Socrates: Hold up!

Loej: What?

Socrates:  You said the word "and".  I think that’s a good sign you are breaking this rule when describing a class.

Loej: You mean that if I use the word "and", I have more than one responsibility?

Socrates:  Exactly.

Loej:  Ok I’ll buy that.  But how do I know if I have the right responsibility?

Socrates:  That’s going to depend on your domain model and a second rule of thumb.

Loej: What’s that rule?

Socrates: According to Robert Martin who formulated these SOLID principles, each class should have one and only one reason to change.

Loej: That sounds arbitrary and academic.

Socrates: Well, but what would it mean if we had two reasons to change?

Loej: I suppose it meant that the class did more than one thing.  It had two responsibilities.

Socrates: Right.  So either we planned for the class to have two responsibilities which we have decided is not a good idea, or we didn’t understand the class well enough in the first place because we didn’t see that there were two responsibilities – two reasons to change.

Loej:  I guess it makes sense.  Still, I can think of some cases this wouldn’t be good practice or good design.

Socrates: Sure. SOLID should help us think about good software design but they are principles of good design and not laws. Your domain model requirements should sometimes take precedence.

Loej:  So what you are saying is to keep this idea in mind as I code.  This will lend my design to looser coupling, easier testing, and smaller more focused objects.

Socrates:  Very good. Now go and meditate deeply on the letter S until we speak again.

Loej:  Yes master!

 
 

Socrates on SOLID: Motivation

17 Nov

This is the first in a series of (hopefully) amusing posts into Robert Martin’s SOLID principles.  It’s written as a dialog between Socrates and a student named Loej in the spirit of the dialectic method popularized by Plato.  I hope you find this enjoyable. 

The other posts in this series can be found below.

Socrates, who is the narrator of the dialogue.
Loej, who is but novice at the master’s feet.

Socrates: Welcome Loej. Today let us discuss the fundamental concern of software engineering. What is the chief concern of software engineering?

Loej: I know this one. It’s complexity.

Socrates: Indeed! And what is the chief cause of complexity in software development?

Loej: All those squiggles and curly things?

Socrates: Let me ask this another way. What is the one thing that customers always do?

Loej: Oh. They change their minds.

Socrates: Right! And when they change their minds, what do you do?

Loej: Try to talk them out of it.

Socrates: (Chuckles).

Loej: Right. Never works.

Socrates: So customers always change their minds. And what happens when they change their minds?

Loej: Usually we have to go back and make a lot of changes in the code.

Socrates: And what happens when you must change your code?

Loej: It depends on the size of the change, but usually it requires a lot of work just to try and not break anything. We have to tack a lot of stuff on. We have to break other stuff open.  One changes usually ripples through a lot of the code. It gets pretty messy.

Socrates: What do you mean by pretty messy?

Loej: More complex.

Socrates: And when you say tack stuff on and things ripple?

Loej: Well, sometimes we have something that depends on something else, and that something depends on something else, and so on. One change might need two more which might cause four more, and so on.

Socrates: So change can lead to a geometric increase in complexity.  We agree software engineering’s chief task is managing complexity. And we agree that a major contributor to complexity is change. So then our task must be to manage change in order to manage complexity.

Loej: But is change really the fault of developers? Isn’t this about poorly written specifications, lack of detailed requirements, customer’s needs shifting during the project, etc?

Socrates: Yes all of these things contribute to change, but they in turn are a results of a more fundamental aspect of software engineering. As Steve McConnell puts it software design is a wicked problem.

Loej: What’s a wicked problem?

Socrates: A wicked problem is one that is not fully understood until a solution has been formulated.

Loej: Then it’s impossible to solve!

Socrates: No. It is partially understood leading to partial solutions. Through the process of solving the problem, we gain better understanding of the problem.

Loej: Which then gives us the right solution!

Socrates: Sadly, no. There are no right solutions to wicked problems, only better solutions.

Loej: That’s lame.

Socrates: Indeed. So how do we get really good solutions if we must solve a problem to better understand it?

Loej: I guess we have to solve it many times, possibly over and over until we are done.

Socrates: In other words we must iterate. And what happens in each iteration?

Loej: We have to change the solution.

Socrates: Now we are getting somewhere. So change isn’t ancillary to software engineering is it?

Loej: No, it is a fundamental part of the process.

Socrates: Correct.

Loej: Well what can we do? How do we deal with change when it can be so disruptive?

Socrates: Ah! Now you are asking the right questions. Ponder what we have discussed and we shall talk again soon about some insight into this question called SOLID.

 
 

Thinking about Delegates

14 Nov

Delegates can be hard to get your head around.  I think the reason is that there are so many moving parts involved (declaring the delegate, declaring the delegate instance, declaring matching signatures, assigning the instance, etc, etc).

I thought maybe a different approach would be useful (Inspired by Rome Total War).

Enter Delegus Maximus

Imagine you are the great Roman general Delagus Maximus. In a few moments, you will be launching an all out offensive against a loosely allied confederation of barbarian tribes.

In a desperate attempt at defense the barbarians forge shaky relations between warring tribes, yet distrust runs rampant from years of conflict.   While huge in number, they are unable to coordinate effectively.

But not you. Your army is a well oiled machine of destruction!

To coordinate your specialized units, you use different colors of flags to give to indicate shared maneuvers. This way a single flag can result in a whole series of complex maneuvers between legions, cavalry, archers, and artillery. For example, a red flag might mean rank and file attack head on while cavalry flank and archers shoot at the enemy’s rear.  A yellow flag might mean skirmishers should pick at enemy archers while cavalry charges and your pikes brace for an enemy charges. You get the idea.

If coding this, we would need a way to represent the various flags and have the attack order vary with different flags. We also need multiple actions to be taken when the order is issued.  One way would be to use a delegate type to represent the order and a parameter to represent the flag:

//Declare a delegate
public delegate void AttackOrder(Color flagColor);
 

So what is this delegate thing?  In fact it’s a type declaration:  It’s a type whose payload is a method signature. What makes it confusing is that it looks so much like a method.  If I had been the author of C# the delegate declaration might have looked more like this:

//Not real code!  public delegate Attackorder  = void (Color flagColor);

 

But that’s just my opinion.

Each troop’s squad needs a method that matches the delegate’s method signature so they can respond to attack orders. To simplify this example, I created an interface that has a method matching the delegate signature. Notice that the signature of RespondToOrder matches the delegate.

interface ITroopSquad
{ 
       void RespondToOrder(Color flagColor);
}
 

Each unit implements this interface. I’m going to create an Archer and Cavalry classes:

class Archers : ITroopSquad 
    { 
        public void RespondToOrder(Color flagColor) 
        { 
            //This matches the delegate signature. Do orders here. 
        } 
    }
 
class Cavalary : ITroopSquad
    {
        public void RespondToOrder(Color flagColor)
        {
            //This matches the delegate signature.  Do orders here.
        }
    }
 

I then place some units in a list:

    List<ITroopSquad> romanArmy;    
    romanArmy = new List<ITroopSquad>();
    romanArmy.Add(new ArcherSquad());
    romanArmy.Add(new CavalarySquad());

 

What we need next is to declare a variable of the delegate type.

public AttackOrder destroyBarbarians;

 

This just a declaration, nothing more interesting than int x. We have just declared (but not created!) a variable of the delegate type we are going to assign to.

We’re just about ready to crush the resistance, but we still need to tell our troops to listen for the order.  We need to have each troop’s RespondToOrder method invoked when the destroyBarbarians delegate instance is invoked.

I can assign each troop’s RespondToOrder event using the following:

  foreach (ITroopSquad troop in romanArmy)
  {
      destroyBarbarians += new AttackOrder(troop.RespondToOrder);
  }
 

What’s happening here? 

Each time we loop through the foreach, a new delegate instance of AttackOrder is constructed with an instance of the troop.RespondToOrder method.  It is then combined (chained) using += with any existing delegates already assigned to destroyBarbarians.

In C# 2.0 and beyond, a simplified syntax is available as follows:

  foreach (ITroopSquad troop in romanArmy)
  {
      destroyBarbarians += troop.RespondToOrder;
  }
 

Under the covers the compiler is creating the appropriate delegate type for us and assigning it.

The stage is then set. The army awaits the order. All we need do is give the order!

if (destroyBarbarians != null)
{       
  destroyBarbarians(Color.Red);
}
 

Well you do see we had to do one more thing – we also needed to make sure the order isn’t null when we invoke it. For example, if all of our troops are dead (nobody is listening when we invoke destroyBarbarians) than we can expect an exception because the delegate has no assigned value.

With a single wave of our red flag, our squads sweep into action and route the barbarian horde! Victory!

 
No Comments

Posted in C#

 

Comic 11/14/2009

14 Nov

     Comic strip #4

 
No Comments

Posted in Comics