Friday, November 22, 2013

Creation Patterns

Creation patterns are a group of patterns that solve one problem: build a concrete object of what you want when you want it how you need it.

What are some of the creation patterns?
  • Factories - These patterns take in a set of parameters and returns a concrete class typically as a base type or an interface.  When is this pattern helpful?  Do you integrate with several API's that do the same thing with different methods?  Do you have several types that all inherit from a single base type?  In every case, you want to build a specific concrete class, but you only care about the base class or interface functionality.
  • Builders - These patterns build a concrete class.  One point behind this pattern is to get all that boilerplate initialization in one nice little place so that it's not sprinkled all over your application and so that it may not have to change at every sprinkle should the need to change arise.  How could it change?  A new parameter of course.  May want to check in on that Open/Closed principle before you go down that path.  The other point of this pattern is to prevent a long list of constructors in the class definitions.
  • Object Pools - This pattern provides a cache of resources already acquired for the purpose of fast initialization.  You see these often with network based connections like database connections.

Monday, November 18, 2013

The Repository Pattern

The repository pattern is an approach to solving the problems of data preservation, organization, and access.  Using the repository pattern abstracts away the storage medium allowing you to not care if your storage is in memory, in XML, in a NoSQL system, or in a SQL system in all its glory.  This is helpful for several reasons.  First, you can unit test without a fully featured database system running requiring significant build-up, coordination, and tear-down before and after each run.  You can rest easier at night knowing that when your boss says that some new database technology is really awesome and you should use it, he won't be upset when you tell him it will take less time than he thought to recode everything.  And another more subtle reason for the repository is to build queries from business rules that are acting upon the repository instead of sprinkling your queries everywhere in your application/business layers.

TLDR: Repositories are your gateway to getting at your application's data.

Martin Fowler's got an excellent write-up on the repository pattern here.

Tuesday, November 12, 2013

Patterns and Software Development

My father always said that it's always critically important to have the right tools for the job.  He's right, though that shouldn't be very surprising.  Applying that nugget of wisdom to software development has so many different meanings that it will make your head spin.

For example, there's your development environment: Visual Studio, Eclipse, Vim, Emacs, and Notepad (a few of only millions of development tools).  Many of these environments have plug-ins allowing you to build more tools for your tools.  I've even seen a video of someone that has bootstrapped a speech controlled development environment so that he can dictate his code.

Another example would be libraries you can use.  This is a collection of software ready to be used by your software.  Libraries can limit the amount of code required to complete your task.

Then there are patterns...  Patterns are code snippets that help you create strategies to effectively complete a task or solve a problem.  The more code you create, the more you will notice a class or even a function call that works well in several situations.  Not that it's used often, but when it is used, there's a feeling of relief that you're doing something that just feels right.  Get enough good patterns in your head, then you're really excited to create new code.  But why?
  1. Patterns are recognizable.  They are repeatable.... which lends to their recognizability.
  2. Similar patterns can be used to solve similar problems.
  3. Patterns help us learn from the sweat of our coding predecessors
  4. Good patterns are easy to maintain.
  5. Patterns allow us to think less about some of the details and more about the bigger task at hand.
  6. Patterns are often fast to implement requiring less refactoring.
There are too many patterns to name.  There are books about patterns.  Many patterns are organized into one of several groups.  Patterns are extensively studied because they can be extensively used with great success.  In some future updates, I will cover a few of the more basic, but interesting ones as well as discuss the different groups that most patterns fall into.

Please don't think that patterns solve all the world's problems.  They don't.  As with all things, KISS (Keep It Simple Stupid) is paramount.

Thursday, November 7, 2013

Coupling and Cohesion (a revisit to my college days) Part 2

This is the second part of a 2 part post covering coupling and cohesion.  Want to see my thoughts on Coupling?  Get it here.  It's free, gosh darn it!

I'm going to discuss Cohesion in this post.  Cohesion always gave me problems because it's abstract and I mentally mixed the word "cohesion" with "adhesion".  When your brain does that do you, you're in trouble.

Code Cohesion is a description of your code.  Your code's completeness and degree that it is whole is cohesion.  When my mind thinks of the word "cohesion", I think of "cohesive".  After thinking about this a bit, it seems to make more sense to think of the word "coherent".  You may ask yourself, "is your class or set of functions coherent?  Does it make sense?  Does it have only one responsibility?  Is it complete?"  A class with a low amount of cohesion means that this class performs tasks that are not related to each other.  A great example of this would be a milkman class that delivers milk, the newspaper, and fathers your wife's next child.  You really want a high level of cohesion.  You really do.

So, you want high cohesion.  Why?  High cohesion means your code is coherent, it makes sense, it's concise, it tells the whole story, it is....  complete with a nice little bow.  Low cohesion means your code makes little sense and nothing is where it belongs.  Low cohesion is a sock drawer with kitchen knives.  High cohesion is a well organized sock drawer with no loose socks (and no knives).

Wednesday, November 6, 2013

Coupling and Cohesion (a revisit to my college days)

This is the first of a 2 part series of blog posts discussing coupling and cohesion:

One curious set of words that bugged me when I was in school was Coupling and Cohesion.  Coupling and Cohesion were tough for me to get my head around.  It didn't help that they both started with a 'C' and I could visualize both words coming to a visual end of 'togetherness'.  For example, I could use a pipe coupling to fit 2 pieces into a single cohesive pipe.

For this post, I will limit my discussion to Coupling.

Code Coupling has to do with how one 'thing' fits with another 'thing' and how they depend on each other.  Let's say I have a 1" pipe. I need a 1" coupler if I'm going to connect it with anything else.  Likewise, if I have a function call that depends on something, that something is required if I'm going to use it anywhere.  A pipe connected to nothing is as useless as a function never called, so I'm forced to have a 1" coupler for the pipe and I'm forced to have that instance of an argument for the function call.  This is where the pipe metaphor gets good for developers:  I can change my function's dependency on a widget by defining an interface that the function can depend on instead.  An interface is simply a definition of a set of functions.  Where this gets interesting is thinking about the interface as something that is more related to the function and less related to the widget.  Since this interface is something the function depends on, why not think of it as having a stronger relationship to the function and less of a relationship to the widget?

So, you want low coupling.  Why?  With coupling, you want a low amount of dependencies on other things.  More dependencies on things outside of your domain means more changes more often.  More changes means you have a higher chance of making a mistake.  It's a numbers game, really.  More changes = more time = more mistakes = more time = less learning something new and cool.  Low coupling allows for easy interchangeability.  High coupling forces uncomfortable code.  Low coupling is being able to eat all the desserts.  High coupling is being able to only eat sugar.

Friday, October 18, 2013

Invoke-RestMethod and Invoke-WebRequest Header and Other Problems

I'm working on a script that copies the contents of a Rackspace Cloud Files container to another container.  I'm leveraging Rackspace's PowerShell library from GitHub and adding what features it currently does not possess.  One such feature is a function to copy a Cloud Files Object.  The API documentation for this specifies 2 ways to do it.  So here's my story:

  1. I first went the path of using the "COPY" method.  This effort was quickly thwarted when it became obvious that Invoke-WebRequest's -Method does not support Copy for a value.  On to #2.
  2. I began working on the "PUT" method.  This approach requires you to specify the size of the file being copied in the header as the "Content-Length".  So I added "Content-Length" to the headers and it gives me this error:
    This header must be modified using the appropriate property or method.
    Parameter name: name

    So, there's no way to add content-length to the Invoke-WebRequest or Invoke-RestMethod functions...  What now?
  3. I rolled the dice on Google for a while until I came across this Microsoft Connect bug.  Taking a quick look at the workarounds, Ch15Murray suggests tapping into some .NET features.  Here's what it looks like:

    $webRequest = [System.Net.WebRequest]::Create( $url )
    $webRequest.PreAuthenticate = $true
    $webRequest.Method = "POST"
    $webRequest.Headers.Add('Authorization', "Basic $token")
    $webRequest.Accept = 'application/*+xml;version=5.1'
    $webRequest.GetResponse()
    
I noticed that I can change the method property here without any validation, so I could use "Copy".  This takes me back to my first attempt which seems much easier.  Now I have a nice little approach to taking on the copy of a Rackspace Cloud Files object.  Here's my final code:
    $webRequest = [System.Net.WebRequest]::Create($rackspaceSourceUrl)
    $webRequest.PreAuthenticate = $true
    $webRequest.Method = "COPY"
    $webRequest.Headers.Add("Destination", $destinationPath)
    $webRequest.Headers.Add("X-Auth-Token", $token)
    $webRequest.GetResponse()

Monday, October 14, 2013

PowerShell Script with multiple Invoke-Sqlcmd calls

People need reports, but I don't like spending too much time putting them together.  That's why I'm looking into using PowerShell to build my reports for me.  I currently use 4 or 5 different SQL queries that hit different servers to acquire numbers for my report.  I'm starting small and hope that by the time I'm done with this script that it will fill in all of the nice bits in an Excel spreadsheet.  So, let's talk about my first snag:

When I began working on this, I found that the best way to get what I needed was to change what SQL scripts I had into scripts that return a single data set.  This means creating temporary tables and filling them with key/value pairs.  Then for the output, I would simply select * from the temporary table.

My next snag was when I needed to add a reference to a second SQL script to my PowerShell script.  I'm calling Invoke-Sqlcmd because the -inputfile parameter allows me to specify a file instead of a single query.  When I ran this, I found that only my first Invoke-Sqlcmd was writing to the screen.  To work around this, I set the result of the Invoke-Sqlcmd to a local variable and then called Format-Table with the new local variable.  Now I have one screen that gives me all of the data I need to throw into my Excel spreadsheet instead of having to go to 2 different SQL scripts.


Add-PSSnapin sqlservercmdletsnapin100
Add-PSSnapin sqlserverprovidersnapin100

$result1 = Invoke-Sqlcmd -inputfile "UsageCount.sql" -Server "server1"
$result2 = Invoke-Sqlcmd -inputfile "Incidents.sql" -Server "server2"

Write-Host "-----------------"
Write-Host
Format-Table -inputobject $result1
Format-Table -inputobject $result2

Thursday, October 3, 2013

PowerShell Curl Awesomeness

I needed to translate a curl command into a PowerShell command the other day for some reporting that I need to get done with Rackspace's Cloud Files solution.

Before I could get started, I grabbed some of the Rackspace PowerShell bits at http://developer.rackspace.com/blog/powerclient-rackspace-cloud-api-powershell-client.html.  It turns out that, as of my time of need for this module from Rackspace, the module had no Cloud Files features in it.  So I rolled my own.  I was given a quick curl command from the fanatical support tech at Rackspace to grab the data I needed for my reports.  I'm working on learning PowerShell, so I decided to find a nice PowerShell way to get my curl goodies.  Most folks will say that you should use Invoke-RestMethod, but the problem with this approach is that it does not return any headers.  Rackspace returns the information I need in the header.  Instead, I need to use Invoke-WebRequest.  The return value has a Headers property that gives you access to the response headers.  So my cool little script looks like this:



function WriteOutFileStats($count, $byteCount){
Write-Host ([string]::Format("Files = {0:N0}", $count))
$gbCount = $byteCount / 1024 / 1024 / 1024
Write-Host ([string]::Format("Size(GB) = {0:N2}", $gbCount))
}

Write-Host "Rackspace------------------------------------------------------------------------------"
Import-Module PowerClient
Get-AuthToken
$rackspaceUrl = ""
foreach ($service in $token.access.serviceCatalog.service)
{
    if ($service.name -eq "cloudFiles")
    {
        foreach ($endpoint in $service.endpoint)
        {
            if ($endpoint.region -eq "ORD")
            {
                $rackspaceUrl = $endpoint.publicURL
            }
        }
    }
}
$resp = Invoke-WebRequest -Uri $rackspaceUrl -Headers $HeaderDictionary -Method Head
WriteOutFileStats $resp.Headers["X-Account-Object-Count"] $resp.Headers["X-Account-Bytes-Used"]
Write-Host (Get-Date)