Friday, March 12, 2010

Single Responsibility Principle

Had an experience yesterday with something at work that reminded me of the Single Responsibility Principle, except at a larger scale...

The Single Responsibility Principle basically states that a class should have one (and only one) reason to change. Another way of saying the class should only do ONE THING. The benefits of designing classes this way includes:
  • Easier to change - if you're changing the logic of the class (which only does one thing), then you don't have to worry about whether you're going to break the other "things" it does.
  • Easier to understand - you can focus on the "one thing" the class is doing.
  • Easier to unit test - your unit tests only need to worry about the one thing the class does.
We were in the middle of a problem at work where we needed a certain set of classes (Decisions) to translate to another set of classes (Instances). The reason for this was the "originating" (Decisions) class wasn't XmlSerializable, and we needed to send it across the wire (the reason for THAT was due to looped relationships within the object graph, eg "child pointing back to parent"). The "translation mechanism" we were using (Instances) happened to be a set of classes (that WERE serializable) we were using to interface with an external billing system.

By using this "translation mechanism" for our purposes, we were essentially violating the SRP at the architectural level. The class was responsible for:
  • Interfacing our Decisions class with the external Billing system.
  • Transmitting our Decisions class across a web service
Thing got tricky because the translation wasn't exactly direct - there was information lost in the translation, and we had to infer several properties, relationships, etc on the Decisions class from OTHER properties that were intended for use by the Billing system. And if these "Billing" properties didn't behave exactly like we wanted, we were faced with the prospect of changing them, and potentially impacting the Billing system translation. To make things much worse, we had no unit testing in place for what the Billing system required.

We've reached the point where the changes required (while seemingly minor) were getting more frequent, and our comfort level (fear) around the Billing System was enough to make us take stock of the entire situation. We've decided to rollback any of these "accomodating" changes we've made, and attempt to get the original (Decisions) class to serialize, rather than using the Instances class to perform the translation. And if THAT doesn't work, then we'll probably create a separate mechanism for getting it sent across, rather than trying to use the Instances class.

The Instances class already has a responsibility, and burdening it with this second one just got too scary.

Wednesday, February 24, 2010

Virtual Tables during SQL Compilation

One of my goals this year is to build proficiency in SQL Server - I know my way around it pretty well, but there's a ton of technical detail, tools, etc that I DON'T know about. I've got a big fat book I'm slowly reading, and will try to share some of what I learn here.

SIDE NOTE - alot of these posts are going to ultimately sum up to "This doesn't really add value", or "I didn't find anything hugely interesting here". In order to save you, the faithful reader, some time, I'll try and tell you up front whether you're going to walk away a better person after reading a particular post.

In this post, I'm laying the groundwork for the next post, providing some background information. Probably useful.

A big piece of SQL performance involves how a query is processed logically. In a nutshell, the SQL Server compiler will parse a query into multiple pieces, and construct a series of "Virtual Tables" at each stage of the processing. It's useful knowing how this works - a few reasons being:

1) There are certain SQL rules that are pretty confounding, but make sense in light of how SQL Server is processing the query. For example, "why can't I use the 'MAX' aggregate function in my WHERE clause?"
2) Performance - if you can move certain processing to a logical step that will cut down the processing required by subsequent steps, you can improve performance
3) Weird Results - sometimes, things are included in a result set, when they don't seem like they should be. For example, sometimes the "GROUP BY" clause will toss in a result that seems like it should have been excluded by a WHERE clause.

There's more to this topic than I want to cover here - I didn't see anything on the web, but here's the book if you're interested:


So one of the big surprises for me was that, for each table you JOIN in a query, SQL Server does a Cartesian Join. Basically, for 2 tables, this means that the number of rows will be:

[# of rows in Table1] x [# of rows in Table2]

If you've got big tables, and queries that need to join alot of them at once, this seems like it would get pretty ridiculous within SQL Server? How does it manage to work with datasets this big? I've looked around on the web a bit for some sort of explanation, but haven't found anything.

My next post is going to contain a test I ran to try and illustrate the performance implications of this Cartesian join. I think I'll also post something to http://stackoverflow.com/ and see if someone there has an answer. Stay tuned...

Tuesday, February 16, 2010

Builder Pattern

This post is the first of (hopefully) many outlining my exploration of Design Patterns, and how they can be used within my employer's production code. I'll abstract away any details (can't give away secrets), but will try to provide enough to give the general idea. These posts won't go into detail on the actual patterns themselves, but will provide references to sites that do explain things in detail.

...and to start things off.....The Builder Pattern!

The Builder pattern essentially delegates the construction of complicated entities to specialized classes that know how to construct them. Here are some sites outlining the Builder pattern:

http://www.dofactory.com/topic/search.aspx?q=builder

http://en.wikipedia.org/wiki/Builder_pattern

Some of my thoughts on the Builder pattern:
  • Useful when the construction of an object (ie, the "Product") requires a series of steps. eg, something like "Build Tree, Populate Nodes, Sum Totals". If the "Product" is simple, and doesn't require these steps, the Builder pattern doesn't seem to apply.
  • Useful when there are several "varieties" of "Product" that can be build. For example, if we have an abstract "Vehicle" class, with concrete "Car", "Motorcycle", "RV", etc.
For application of this pattern, I'm currently struggling to find a good application. I mainly work on an Ordering system, and I'm not sure there's an obvious use. I considered the fact that we have different types of Orders (eg, New, Change, Supplement, etc), but they all seem to use the same core "contract" to carry the Ordering information. If we had an overarching "Orchestrator" of sorts, we could potentially use Builder for constructing the Orchestrator. It might look something like this:

ConnectOrderOrchestrator.Build

Which would do something like:
  1. Retrieve Existing Information
  2. Construct Order Form
  3. Apply Defaulting
Then each Order Type could have their own Builder that walks through this same series of steps? I don't know, though - kind of seems like fitting a square peg into a round hole.

For now, I'm going to put this one in the back of my mind. As I work on code, hopefully something will jump out at me...

Wednesday, April 8, 2009

Apologies (iPhone Draining Time!)

I've been away for a while, and have been about as diligent with posting to this blog as I was afraid I would be :( I've been plunging headlong into iPhone development, and have really been enjoying myself! Been programming a game (what else!?), and have been learning a ton, both about iPhone development, as well as game architecture.

Not much to report in this post, but I'll try to be more regular with my updates. One of the things I've been doing as part of my development is "research" into existing iPhone games to discover positives and negatives. Just played around with "FlightControl", and enjoyed it quite a bit. This one has the potential to be addictive! Check it out (and spend a buck! support iPhone development!)

http://www.firemint.com/flightcontrol/

Monday, February 23, 2009

Distractions

As I had feared, I got about 3 posts into my new blog, and have become distracted. I started writing an "exercise helper" in .Net to demonstrate new ideas (mainly around WPF), but have grown a little bored with it. Also, I've decided I want to try out some iPhone development. Tired of reading these stories about guys like me who spent 6 weeks worth of evenings writing a game, and are now retired. So my brother Will and I are starting to explore game ideas, and game development on the iPhone. I ordered Leopard for my macbook (which is necessary for the iPhone SDK), and have been reading documentation on the SDK. Soon as that mofo gets here, I'll have it up and running, and will see just how hard it is to get into Open GL ES. Hopefully future posts will involve that topic :)

Thursday, February 12, 2009

Workout Helper, Step 3 - Getting it Right from the Beginning

Now that we've overthrown the weightlifter, let's get to some actual meat and potatoes.

When I was a young buck, full of vinegar and carpal-tunnel-free, this is when I'd start tearing into the code. Wiring events, spitting out business logic, I'd code first and ask questions later. I'd give some thought to overall maintainability/readability/testability, but would be more concerned with making things work. This served me well from a time-line perspective, but created a whole slew of issues later on.

Now that I'm older and wiser, I've learned a few coding practices that have improved my coding by leaps and bounds. This hasn't been an easy transition - I spent many years scoffing at the importance of some of these patterns and practices. However, after using them, and seeing their benefits, I'm hooked and want to learn more.

Side Note - as a developer, I think I'm probably a little arrogant, resistant to change, and threatened by the idea that I might look stupid. With age and wisdom, I'm better at recognizing it in myself, but I still have my moments. For the most part, I'd rather be a humble learner than a cocky know-it-all. This mind shift has helped me start learning things I should have been learning long ago...

This post will introduce the "View/Presenter" pattern to our application (this is actually a subset of what's called "MVP", or "Model View Presenter"). MVP is a well-established pattern that separates your code into 3 concerns:

Model - the repository of data. This could be a .Net DataSet, a class/entity, an XML file, etc. There should be no "business logic" in the model - it's just a dumb container.
View - this is what displays the data contained in the Model, and allows the user to interact with it. In .Net, this is typically Window, Control, ASP page, etc.
Presenter - this is where the business logic resides. The Presenter could be considered the "go between" for the Model and View. The Presenter is sometimes called the "Controller".

There are some major benefits to using this pattern, including:
  1. Seperation of concerns - using MVP, we don't get business logic tangled into our Data or GUI. This relates to the "Single Responsibility Principle", which states that "A class should have one, and only one, reason to change." In other words, a class should do one thing, and one thing only. With MVP, we don't have a GUI trying to handle display AND biz logic. The SRP is part of a bigger set of patterns called the "SOLID Design Principles", which are an important cornerstone of software design. SOLID goes beyond the scope of this posting, but is worth learning about - you can read about it here.
  2. Better Unit Testing - Unit Testing is an extensive topic that we'll revisit often in this forum, but for now, just know that MVP leads to better unit tests. You can Unit Test your biz logic without having to "fake" windows/GUI. Once you start writing Unit Tests against this pattern, it almost becomes fun seeing where your design is faulty, and how it can be improved. Using the pattern and Unit Tests, it's almost like you're carving the code out of a block, and the pattern is guiding your hand.

Here some links describing the MVP pattern further:

Wikipedia
MSFT

For now, we're just going to worry about the View/Presenter (Model will come later). The V/P relationship will be formalized with two classes and an interface:

MainWindow - our View, this is the Window class that will implement the GUI
IMainWindow - an interface that is implemented by MainWindow. This is what the Presenter will be interacting with.
MainWindowPresenter - a C# class that will handle the business logic.

Here's how it looks:



We'll be flushing this idea out in subsequent steps, but for now, we've got the basic structure in place. Our View and Presenter are "aware" of each other, and will "hand off" different responsibilities appropriately. Note that the View has a reference to the Presenter itself, whereas the Presenter has a reference to an interface. This will assist with Unit Testing in a subsequent post - more on that later.

Note - notice how I introduced some regions here? I'm not sure I could come up with a conclusive argument on WHY regions are good, but I love them, and feel dirty when code isn't using them. I always "regionize".

Alright, enough for today. Our application isn't doing anything new, but it's been refactored to use the MVP pattern, and is ready to start accepting actual functionality. Next post, we'll start doing some data binding.

Wednesday, February 11, 2009

Workout Helper, Step 2 - Image to Icon

Alrighty, now that we've got the basic framework in place, let's do something about the homongoloid dominating the application. His bulging muscles mock us, and we refuse to be pushed around any longer. He may be massive, but we're the ones controlling the code, and his physical strength is no match for our XAML skills.

In the old days of Windows Forms programming, taking the image and making it the Window icon was fairly easy, but still a bit of a pain. It could be done with a few lines of C# - basically turn the jpg into a stream, do some massaging, abracadabra, there's your icon.

With WPF, it's dirt simple - just add the following XAML to the Window element:



Note - I wasn't actually sure how to use a jpg as an Icon off the top of my head - tried a few different uses of "Image*" tags, but nothing seemed to work (I think I've been jaded by my Windows Forms Jpg-Icon conversion experiences). I posted a question on www.stackoverflow.com, and got an answer back almost immediately. That site is great for this type of thing, and I will presumably be referencing it quite a bit along the way!

http://stackoverflow.com/questions/537125/jpg-as-a-window-icon-using-xaml

Here's the app now:



In addition to the ease of use, I've had experiences in the past where our application suffered from memory/handle leakage. This subject is horrifically complicated, but long story short, just because C#/.Net is managed code, doesn't mean the memory management magically works all the time. There are instances where things can leak, and if they leak badly enough, your application bursts like a water balloon. One area this seems to happen is with Resources (eg, Icons and Images). I'm assuming that the XAML I've written above disposes of everything correctly, giving us some nice "magic" that handles all the complicated stuff under the covers.

One less thing to worry about!