Friday, March 29, 2013

Resharper as a coding instructor

I've been using Resharper a lot more lately. It's evolved nicely; while still a little annoying and intrusive the productivity increase is dramatic. Many of the features are things Microsoft should have added into Visual Studio years ago (they've been in Eclipse for what, 10 years?).

One of the neat things is that it is constantly suggesting better ways of coding or of structuring your code. I find myself learning about attributes of C# that I'd either forgotten, or hadn't know about.

I have a list of transactions that I want to add to the budget month container. Traditionally we might have done something like the following.

foreach (var transactionItem in items)
{
 month.AddTransaction(transactionItem);
}

This simply iterates over the collection of items, and for each one it calls the .AddTransaction method on the month.

My more modern method might be more like this:

items.ForEach(i => month.AddTransaction(i));

Resharper, though had a suggestion. Why not simplify that line even further? I'm game - so I clicked the suggestion. After all, there is always undo. This is the line;

items.ForEach(month.AddTransaction);

Simple, concise, and clear. I will confess that I had to run the unit test it in the debugger and inspect month's transactions just to make sure that the items had actually made it in there. Yup. Sweet.

Wednesday, March 27, 2013

RavenDB with MVC 4

I've decided to use RavenDB for a project that I'm working on. I've been researching a number of database options for a site which could eventually have pretty rigorous traffic load. Though I really like MS SQL as a traditional relational DB I've seen it, when coupled with naive EF use, become a horrible drag on performance.

So far I'm pretty impressed. It is very nice not to have to setup and maintain a dedicated ORM just to translate from the real world of objects into a flattened and normalized set of tables. I've created a set of "POCO" database classes in my BI/Services project (though for a larger project I'd probably simply have a dedicated database project). For the classes that will be the document that is stored I've added a string property to receive the document ID. For those that I'll explicitly define the key I simply added a method to the DB class "GetKey()" - in the example below the key is "UserProfile/curtis.forrester".

public DBModels.UserProfile GetUserProfile(string username)
{
    using (IDocumentSession raven = Store.OpenSession())
    {
        UserProfile user = raven.Load<UserProfile>(UserProfile.GetKey(username));
        return user;
    }
}

public void StoreUserProfile(UserProfile profile)
{
    using (IDocumentSession raven = Store.OpenSession())
    {
        raven.Store(profile, profile.GetKey());
        raven.SaveChanges();
    }
}
This is all that is necessary to store and load a UserProfile document. Since the data is stored as JSON I also modified the class and had no issues at all. I added some properties, loaded the UserProfile, set the new properties and stored the document and the updated "record" now reflected the new version.

The flexibility that Raven provides to generate keys for new documents is fantastic. From fully letting the server handle it to providing a method for you to register a custom handler is great.

Like all databases some knowledge and experience will be required to make sure that performance is up to par. I did some initial testing where I stored a bunch of documents that had collections and then loaded them. I found that loading each individual document was much slower than using their bulk loading approach. I found that the sweet spot was to load between 25 and 50 documents. When I increased the number to 500 or 1000 it was as slow as loading each one-by-one.

Wednesday, March 20, 2013

SOLID vs GRASP

I have, like I'm sure you have, encountered the "experts" who ask the normal buzzword questions:

  • So, do you follow the "Gang of Four" patterns?
  • How about SOLID - do you use that in your job?
  • Have you used dependency injection techniques?
This reminds me a lot of how our culture was in the late '90s with people dressing in the robes of either Booch or Rumbaugh. Your school of thought and the modeling approach you used was like a religion. Fortunately UML fixed all of that (ya, remember UML?).

The SOLID question has gotten me thinking. We all know (or should know) what SOLID is all about. That doesn't mean that we agree. When this acronym was starting to become generally used about the same time most of our ".com" companies were collapsing I remember debating its merits with others I worked with. In general I was in agreement with the principles, and certainly with the spirit and goals of the rules.

Single responsibility principle - that a class should have one role or function. Absolutely. This keeps the overall design clean and it is generally easy to understand what stuff does and how they are relating to those they interact with.

Open/Closed principle - that a class is open for extension, but closed for modification. No way. More on this later.

Liskov substitution principle - that objects should be replaceable with their subtypes. On this I generally agree. But this is especially good when you use a factory, and follow the "I" of SOLID and have defined discrete, functional interfaces. In that case especially a consumer of your class doesn't care if it's the original parent instance or some later substituted child.

Interface segregation principle. Just give your customer what they want. If all they need is a small subset of what the class provides let them see your class through the eyes of a simple interface. The less any one part of a software system knows about any other the easier it is when refactoring must be performed. It is also easier to do TDD and write concise unit tests.

Dependency inversion principle. This generally good principle has led, in my opinion, to some of the most unreadable and hardest to debug code. However, when done correctly and cleanly this makes for very "agile" software design.Microsoft recommends using a service locator - and while at design time it's not always obvious which service you'll be using, that's just the point. It doesn't and shouldn't matter. Only that you'll be interacting with some service at run time that will provide, well, the services you'll need. Unit test are greatly simplified using frameworks like Moq. Back in my Java days we used Spring for injecting configuration.

So, what is my issue with "SOLID" and why have I mentioned GRASP in the title? Well there are two reasons. First I do not at all agree with the fundamental principle of the "Open" part. One of the original features of "OO" was that there was an exposed interface that provided a contract to the user. How the implementation did this was of no concern to the outside consumer. This meant that the class could be completely rewritten with no disturbance. That I might need to have the code reviewed again (a silly concept) just because the implementation has changed ignores TDD - if there are a series of complete unit tests that automatically verify that the class is abiding by its contract any and all changes should be permitted.

The interface, and the contract, of a class should never change - it can be extended if need be, though I personally feel that even this isn't a good idea. If a particular class needs to provide more and new functionality this is to me an indication of a need for a new subclass. Yet "SOLID" purists seem to feel that Bob Martin is a deity and these principles sacred. Sacred cows make the best hamburgers!

My second objection is that these principles, while great, only reveal a part of the overall field of good practice.

GRASP

Enter yet another acronym, but an important one. "General Responsibility Assignment Software Patterns". That one had to have been born in a pub over a few beers. These "spoke" to me when I started hearing them packaged together along with the concept of Domain Driven Design. These are patterns firmly planted in the real world. 

In my current role as an ASP.Net MVC developer the "Controller" is critical to handling all user interface interaction. Factory patterns have served me well for allowing a system entity to ask for a service or module that will provide the named function and allowing the factory to determine what to create and return.

Services, delegates, and loose coupling - these are standard motifs that we use every day that that provide robust models of software architecture.

It is not so much that I prefer "GRASP" over "SOLID" any more than I prefer Hibernate over Entity Framework. They both have their place and both their advantages. But purists that want to ask interview questions like "do you use SOLID in your current job" need to understand that there is a wider field of study that any one acronym simply does not encapsulate. 

Finally, a semantic point: we don't use SOLID in our job - we become it as developers. We don't use the patterns of GRASP - they become a part of us. When they are the fabric from which we are woven we become the types of developers that create well-designed and agile software.


Friday, March 01, 2013

TSA Doesn't have to Suck

My work took me to Columbus, OH this week for a two day trip. Actually, it took me about a world away from Columbus to a little town called McArtur where there is the only official light in the county. There is also one of the oldest companies still in existence in Ohio having been established in the late 1800's. Then manufactured dynamite for mining; they now manufacture much more powerful explosives. I had a unique opportunity to see their operations up close since I was installing some software that I had written to enable them to track product through manufacturing, packaging and onto a truck destined for European customers. In short, the gig was "a blast"!

When I left Atlanta Tuesday morning I had the usual unpleasant experience of walking through Atlanta's TSA gang. While the lady who was checking passports and boarding tickets was very pleasant it all ended there. As one approaches the scanners they're greeted with somber-faced agents who tend to command and yell rather than instruct. I get it - they deal with clueless travelers all day. They don't get it - we're clueless cause the rules change and not everyone travels that often.

Traditionally we've had to walk through metal detectors. They now have these body scanners that require you to walk in, face a certain way, and raise your hands above your head as if you were a criminal. Humiliating and demeaning that it is, what is worse is when (literally) three agents yell at you to raise your hands. You're powerless to even look at them for fear they'll ID you as a terrorist and pounce on you. I escaped security with my usual frustration and resentment.

When I left the plant I changed to street shoes, changed my pants, changed my shirt and washed my hands. I had been warned that I might set off the detectors at the airport. I did. The body scanner detected something and so the gentleman told me he needed to do a pat down. I have a good sense of humor and they all seemed friendly. When he patted my rear-end side I went "woo!" in fake enjoyment. They all laughed. He says, "Oh, great - right in front of my supervisor." It was fun. Then he swabbed my hands and headed to the machine. Says I, "Oh boy - if you knew where I'd been the last two days." Jokes he back, "Not sure I want to know."

And the machine started screaming - "Explosives! High Explosives! Grab the guy." And I reply, "Yup - I was afraid that would happen."

The next 15 minutes or so were one of the best experiences of both professional and simple human interaction. They, naturally, did their job and followed procedure. But they were very friendly and polite about it. They knew where I had been, having seen other employees and their family come through and set off the detectors. They did a full pat down, and searched all my stuff. They explained what they were doing every step of the way, and even the beefy security guys that showed up (appearing to be ex-military) were friendly. They were focused and professional - had I been a bad guy there is no way I'd have made it through. But they were also quite willing to laugh, smile, and answer my questions.

What is the difference between the TSA in Columbus, OH and Atlanta? There are some, for sure. One set seem to have a chip on their shoulder and thrive on the power they have while the others are simply Americans doing a very important job. One group could care less to leave you with some dignity while the other respects you as a fellow American deserving of respect.

TSA doesn't have to suck. TSA agents don't have to be nasty, grumpy and bossy. They can instruct you as to what they need you to do in a manner and tone that allows you to endure the delay with dignity and respect. In return, I believe that travelers will show them respect and will go through the security-experience with patience.