Friday, July 20, 2012

Don't Repeat Yourself

Want to be a better developer?  By far the easiest place to start is by implementing the DRY principle of software development.

Don't
Repeat
Yourself

Duplicated code is bad.  It's a code smell, it makes you look like an amateur, and worst of all, it makes the next developer who has to maintain your code want to drag you out into the parking lot and slap you around for a while.

Learning to recognize DRY violations is a core foundation to writing cleaner code, but I'll be the first to tell you that recognizing and squashing repetition violations is a discipline.    It requires you to slow down, really think over your code, look for patterns and refactor them.

Here's the thing though: making your entire code-base purely DRY is pretty difficult, and runs the risk of reducing the readability and the flow of the application from a maintenance perspective (excessive abstraction is a code smell as well, known as contrived complexity, and a fun fact is that it almost annoys me more than DRY violations because the people who create that code smell are more likely to be arrogant/inept where DRY violating people are more like children running with scissors).  So in my mind the goal of DRY is not to purge every possible ounce of duplication out of your system, but the closer you get to the business logic the more DRY your code should become.

To put this in perspective, let's consider an enterprise solution with the following layers (from outside in):

  • Presentation- Various UI clients, executables, etc.
  • Service- Feeds presentation layer
  • Business/Interactors/Rules- Actually does the work
  • Persistance- Stores and retrieves data
Presentation layer?  Sure, you might have some duplicate service calls on various forms.  This in the grand scheme of things is not all that big of a deal, because your presentation layer should not be performing business logic.  Thus, even if you duplicate some calls and structures, those calls shouldn't need to change for a behavior update.  It's nice to make this layer reasonably DRY, but there's a line to be crossed where it seems like developers start cramming unrelated methods together into the large class or "god object", which is another code smell.  You need to weigh the risk of change and readability and make an educated decision.  However, even our designer brethren understand DRY, what do you think CSS does?  Reduces duplication, provides a single source of truth!

A well designed service layer just takes requests and returns responses.  Again, due to minimal business logic, duplication here really should be avoided, but it probably won't kill you if some similarities pop in, particularly in cases where similar services are exposing to different clients.  I definitely take a harder look at this layer than the presentation layer.

Business layer is where we really lock things down.  For any business rule, logical sequence, calculation, etc there must be a single source of truth.  One of the main reasons the architecture forefathers created multiple layers was to purge duplication of these very important facts within software systems.  Until you experience the nightmare of having to update a calculation that is spread throughout multiple layers and duplicated everywhere you can't really appreciate this.  It's a game of coding whack-a-mole that you are almost guaranteed to lose by introducing bugs into production.  

Cool story bro, I once had to work on a system where an important fact was in a middle tier, in stored procedures, also hidden in expressions in reports, and additionally was even duplicated in JQuery on the presentation layer, what was literally a 2 line change took about a week by the time all the duplication spots were located and shaken out.  The hellish thing about duplication like that in distributed systems is that you can't do any cross platform searches easily to find all the buggers.  As to be expected with such shoddy code structure there weren't any tests to run either.

In the persistence layer, particularly in the realm of relational databases any database architect worth their salt will take care of DRY for you.  The whole concept primary keys and unique constraints is to make your data DRY.  Duplicated code is bad enough, but let me assure you that unintentionally duplicated data is a nightmare in its own right!

In the end, DRY is a key to making your code reusable and more maintainable.  Having mentored a lot of developers over my career, I've also found that the pursuit of the DRY principle actually is what leads many new developers to discover architecture patterns in more progressive and natural way than handing them a gang of four book and telling them to go away.

Sometime soon we'll talk about the Single Responsibility Principle (SRP).  Mixing SRP violations with DRY violations is a great way to punish future maintainers if you're a sadist, but that's a topic for another day!

Sunday, July 15, 2012

Parsing A Complex List With JQuery / JSON

So I've been playing around with learning JQuery lately, and while I found some "Hello World" types of examples, I was really looking to jump right in and bind to a WCF service that returned a complex list of objects, particularly a list within a list, since if you can handle that, you can handle just about anything.

The common data structure I'm going to use for this example is a list of movies that contains a list of cast members.  So the first thing we need is a wcf service with some classes in it to represent this structure:

   [DataContract]  
   public class Movie  
   {  
     [DataMember]  
     public string Title { get; set; }  
     [DataMember]  
     public string Director { get; set; }  
     [DataMember]  
     public List<Actor> Cast { get; set; }   
   }  


   [DataContract]  
   public class Actor  
   {  
     [DataMember]  
     public string FirstName { get; set; }  
     [DataMember]  
     public string LastName { get; set; }  
   }  


   [DataContract]  
   public class MovieList  
   {  
     [DataMember]  
     public IList<Movie> Movies { get; set; }  
   }  

Basically what we'll have here is a service that returns a MovieList object.  In real life, we'd add things like success/fail and error messages to the MovieList class, but I'm keeping the clutter down.  For our service itself we'll expose an interface contract and just in-line a couple movies for sample purposes:


   [ServiceContract]  
   public interface IMovieProvider  
   {  
     [OperationContract]  
     [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json)]  
     MovieList GetMovies();  
   }  


   [AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]   
   public class MovieProvider : IMovieProvider  
   {  
     public MovieList GetMovies()  
     {  
       MovieList list = new MovieList();  
       IList<Movie> movies = new List<Movie>();  
       var movie = new Movie  
                {  
                  Title = "Spaceballs",  
                  Director = "Mel Brooks",  
                  Cast = new List<Actor> {new Actor() {FirstName = "John", LastName = "Candy"},  
                  new Actor() {FirstName = "Mel", LastName = "Brooks"},  
                  new Actor() {FirstName = "Bill", LastName = "Pullman"},  
                  new Actor() {FirstName = "Rick", LastName = "Moranis"}}  
                };  
       movies.Add(movie);  
       movies.Add(new Movie  
                {  
                  Title = "CaddyShack",  
                  Director = "Harold Ramus",  
                  Cast = new List<Actor> {new Actor() {FirstName = "Bill", LastName = "Murray"},  
                  new Actor() {FirstName = "Chevy", LastName = "Chase"}}  
                });  
       list.Movies = movies;  
       return list;  
     }  
   }  

Pretty simple stuff so far, now we have a service, and it will expose a JSON representation of this data when we call it.  By using a tool like firebug, we can see that the JSON emitted is going to look like so:


 {"Movies":
[{"Cast":[{"FirstName":"John","LastName":"Candy"},
{"FirstName":"Mel","LastName":"Brooks"},
{"FirstName":"Bill","LastName":"Pullman"},
{"FirstName":"Rick","LastName":"Moranis"}],
"Director":"Mel Brooks","Title":"Spaceballs"},
{"Cast":[{"FirstName":"Bill","LastName":"Murray"},
{"FirstName":"Chevy","LastName":"Chase"}],
"Director":"Harold Ramus","Title":"CaddyShack"}]}  

So now this service is all ready to publish.  Now all we have to do is create a page that contains some JQuery to call it, and then parse the JSON object in a loop to build and emit some html.  The power of this approach really shines in being able to explicitly define your html including any classes, div structure, etc.  It gives us similar flexibility to using a repeater.  For the html page, we'll just drop a simple button on the form and define a div to hold the results of our query like so:


   <h1>My Movies</h1>  
   <div>  
     <input id="btnGetMovies" type="button" value="Get Movies" />  
   </div>  
   <div id="movieList">  
   </div>  

In order to call the service, we're going to use the $.ajax method in jquery.  It has several properties including the url to call, formatting, and I will specify a success and failure method.  We're going to assign the click of the button when the document is ready to make the ajax call.  The JQuery script ends up looking like so:


     $(document).ready(function () {  
       $("#btnGetMovies").click(function(event) {  
         $.ajax({  
           type: "GET",  
           contentType: "application/json; charset=utf-8",  
           url: "http://localhost:81/MovieService/MovieProvider.svc/GetMovies",  
           data: "{}",  
           processdata: true,  
           dataType: "json",  
           success: function(msg) {  
             AjaxSucceeded(msg);  
           },  
           error: AjaxFailed  
         });  
       });  
     });  

The msg variable will contain the json object, and we'll declare a javascript function called AjaxSucceeded to parse it.  Now if you're a good little web developer, we'll try to avoid using tables to grant some flexibility for our designers.  I am definitely not a designer, but I'm going to emit the json into a header tag that contains the director and movie title, then we'll put another heading tag for the cast, and put the cast into an ordered list.  By wrapping this information into a div, we can assign a class to the div and give any future designer some flexibility over styling these objects.  As a general template, we want it to look something like this:


 <div id="movieList">  
   <h2>Spaceballs (Mel Brooks)</h2>  
   <div class="castList">  
    <h3>Cast</h3>  
    <ol>  
      <li>John Candy</li>  
      <li>Mel Brooks</li>  
      <li>Bill Pullman</li>  
      <li>Rick Moranis</li>  
    </ol>  
   </div>  
   <h2>CaddyShack (Harold Ramus)</h2>  
   <div class="castList">  
    <h3>Cast</h3>  
    <ol>  
      <li>Bill Murray</li>  
      <li>Chevy Chase</li>  
    </ol>  
   </div>  
 </div>  

To do that, we're going to take the msg in our function and do two for-loops in java script and dynamically build the html output we want.  Then at the end we'll use the JQuery selector to locate the movieList div and assign its content to the output we created.  Here's the code to do that:


     function AjaxSucceeded(result) {  
       var list;  
       list = "";  
       $.each(result.Movies, function(i, movie) {  
         list += '<h2>' + movie.Title + ' (' + movie.Director + ')</h2>';  
         list += '<div class="castList"><h3>Cast</h3><ol>';  
         $.each(movie.Cast, function(j, actor) {  
           list += '<li>' + actor.FirstName + ' ' + actor.LastName + '</li>';  
         });  
         list += '</ol></div>';  
       });  
       $('#movieList').html(list);  
     }  

Last thing to do is to slap some CSS on it using these classes and child selectors, I'm going to just toss an underline bar on the header and put a dotted line border around the cast, professional designers can mock me, I have thick skin.


 #movieList h2 { font-family: Arial;font-size: 14pt;font-weight: bold;border-bottom: 1px solid #000;}  
 .castList h3 { font-family: Arial;font-size: 12pt;font-weight: bold;margin: 0;padding: 0;}  
 .castList ol { list-style-type: none;margin: 0;padding: 0;border: 1px dashed #000; }  

And you're all set!  You have a working service that emits a list of objects that contain lists as properties.  It executes quick, it's ajax enabled, and you have total control over the mark-up.

Feel free to grab the code source from my public github repository.  I've called the project JQueryPlayground, and future blog posts on JQuery and ASP.NET will expand this project.  Enjoy!

Saturday, July 7, 2012

Don't say no, say "yes, but"

These days as companies get a bit wiser about their projects and continue moving towards cross-functional teams it is highly likely that you as a developer will be tossed into a mix of people without technical skills or a real understanding of what you do.

One thing I have seen over and over throughout my career is the perception that the IT guys are the enemy.  They're arrogant, sarcastic, they act like they want to run your department, hell, there was even a Saturday Night Live skit about this.

So here is a pro-tip for you IT workers out there who take part in these teams.  First, realize that the business users around you, they are your customers, and just like you wouldn't expect any sarcastic flack from your service providers, they don't expect it from you.  Second, remind yourself that it is highly likely that none of them have the background, experience, or passion for technology that you do.  Third, learn to say "yes, but" instead of no.

You don't want to be seen as the ambassador of no, the preventer of information services even. People want to be listened to, they want to feel that their opinions are considered and that they have some input into their processes.  Thus, we must resist the urge to do the following things:
  1. Interrupt someone in the middle of their speaking- Yes, you can instantly see the road they are going down and know it is a bad one, but don't just jump in and interrupt them, it's rude.
  2. Use any dismissive gestures such as looking at your smartphone, gazing off into the distance, squirming in your seat.  Make an effort to keep a reasonable level of eye contact and attentiveness.  If eye contact makes you uncomfortable (yeah, IT has a lot of introverts), then glance at the speaker and take notes.
  3. Don't say no.
"But Eric, ", I hear you saying, "we must say no, their ideas are usually bad, they have no idea what it takes to do things".

I agree, but you can say yes, but and still say no.  Let me give you some examples:

User: "We need you to change the scope of this feature"
You: "Yes, we would be happy to do that, but that is going to have a schedule impact, would it be ok if we examined this and got back to you with an estimate?"

This is much more effective than:
"No, we can't do that right now, we're far to busy and we don't have time".


User: "I think we should do _insert really bad idea here_"
You: "Yes... we could go in that direction, but how are we going to handle x, y, and z?"

This is much more effective than:
"No, we absolutely should not do that, if we do that then x, y, and z are going to cause big problems"

In the first case, you said yes, and you're appearing to be cooperative and asking for collaboration on the issues you perceive.  In the second you're putting the user in the position of feeling rejected without any further discussion, which can lead someone to digging in and defending their position whether logical or not.

If you master this skill, you can not only be viewed as a great service provider, but you can often get users to talk themselves out of bad ideas.  Give it a try!

Thursday, July 5, 2012

Speaking at SQL Saturday August 18th

I will be speaking at SQL Saturday #164 in Cleveland, OH on August 18th.  My presentation is titled "Building A Better Development Shop" where I'll be exploring the things companies can do to attract (and repel) good talent.

It should be a good time filled with good advice and some ribbing at processes we all know and love.

Hello World

public interface IBlogger 
{
   void Post(string content);
}

Once upon a time there was a developer who was very passionate about the craft.  He even went so far as to be a rather prolific blogger on CodeBetter.com, which to this day is an excellent source for code-related material.

Then after many successes on the job, he decided to take a step into management and became a director of application development for a growing and successful start-up.  After many years, he grew restless and needed a change of pace, so he left his position, became a consultant, and dived back into the trenches.

This developer, he has a lot to say about not only coding practices, but also about management, working in teams, relating to the business, and other topics.

Stay tuned...