Showing posts with label Book Review. Show all posts
Showing posts with label Book Review. Show all posts

Friday, June 30, 2017

Book Review: Working Effectively with Unit Tests

I recently finished reading Working Effectively with Unit Tests by Jay Fields (Amazon link). I'm a bit mixed on whether I would recommend this book. There are some good unit testing tips, but it wasn't especially memorable, and there were a few things that I didn't care for too much.

The short version is that my main recommendation for unit testing techniques will remain The Art of Unit Testing by Roy Osherove (Jeremy's review).

Things I Liked
Keep What Works
There were a few general messages that I really liked. The first is try stuff and keep what works. I always prefer a non-dogmatic approach because not every technique works in every environment. I really appreciate that Fields talks about some of the things that he's done in the past, liked them, but then later stopped using them because they no longer fit his situation.

Descriptive Tests
Another message that I really liked is to keep tests DAMP (Descriptive And Maintainable Procedures) as opposed to DRY (Don't Repeat Yourself). Keeping common code centralized is a good practice for our production code, but testing code is a bit different. Tests are really meant to be independent, isolated, and not interact with each other, whereas our production code needs to be cohesive and collaborative.

This really follows my general advice to make sure that tests are readable. It's good to be a bit more verbose and explicit so that they are very easy to approach when we need to look at the actual test code.

Setup Methods
As far as specific recommendations, there are several that I found useful. First is generally avoiding setup methods. By keeping setup (the "Arrange" step) local to the test, it enhances readability and helps make sure we are only using the things that we need for a particular test.

For example, in a test class-level setup method, we may have multiple objects instantiated with various states that we can use in different tests. This means that we could have objects that are instantiated in a setup but are not actually used for a test. This means that we've got some wasted code, and it also makes it a bit harder for us to determine exactly what's important for a particular test.

I've explored something along these lines (Unit Testing: Setup Methods or Not?), although I tended to use factory methods that are explicitly called to get some of the non-critical bits out of the tests themselves. Fields' technique is definitely worth exploring some more.

Assertions
There are a couple pieces of good advice regarding assertions, including one assertion per test. This is particularly important because most testing frameworks use exceptions for tests. So when the first assertion fails, no code after it will run. If we have several assertions, we don't know if we have a single failure or multiple failures. If we keep one assertion per test, then we can tell where our problems are. This also goes along with the DAMP approach; we don't need to be afraid of duplicating behavior in unit tests.

Another piece of advice is to assert last. The thing that we are actually verifying should be at the very end of the test method. This makes it really easy to find what we're testing. And this also goes along with the "Arrange/Act/Assert" layout which I really like.

Fields also spends time talking about testing for exceptions and some of the weirdness that is caused by using a try/catch block. When using a try/catch block, the assertion is in the middle of code (usually in the catch block), and we also need to have a "fail" in the middle of the code if an exception is not thrown.

To get around this, Fields suggests making a custom assertion method, Assert.Throws(), that can be used to check for exceptions without a try/catch block, and can also be put at the end of the test. That way we can follow the "assert last" advice. This is similar to the "Assert.Throws()" that is provided with NUnit (and other frameworks that provide custom assertions). I wrote a bit about this in Testing for Exceptions with NUnit.

Things I Have Mixed Feelings About
Solitary and Sociable
There were a few things that I had mixed feelings about. One of them had to do with Solitary Unit Tests vs. Sociable Unit Tests.

A solitary unit test is a test where only 1 object is "new"ed up. Everything else is some sort of test double, like a stub or mock. A sociable unit test has multiple objected "new"ed and checks the interaction between them.

I don't really like the definition of sociable unit test because to me that steps outside of the world of unit testing and starts moving into integration testing. Fields does mention integration testing, but he looks at that as more of an end-to-end type thing. I've generally looked at integration testing as checking that the objects work together at different levels -- from localized to end-to-end.

This isn't really important in the grand scheme of things. I just seem to put all of my "unit tests" into the "solitary unit test" bucket.

Fields does make the recommendation of separating the solitary unit tests and sociable unit tests. The solitary ones are generally very fast and we want to run those very often, and the sociable ones may take a bit longer (for example, if there are I/O operations) and we probably run those less frequently. This is very good advice.

Sample Scenario
Another thing that I was mixed about is the sample scenario. I do like that the same application code was used throughout the entire book. But the scenario was a video rental store. Since the book is from 2014, this example was a bit out of date when it was published. As someone who is well over 40, I have no problems remembering what it was like to rent movies from a physical store. But I'm sure there are lots of developers today who have not had that experience.

Again, not a big deal. The samples could easily be updated to use a video kiosk rather than store.

Things I Didn't Like
The First Test
While I like that the same scenario is used throughout the book and that there was a focus on continuously improving the tests, I really did not like the first example.

The reason is that Fields states, "Let's get straight to code" and then shows a rather-difficult-to-read example and says "you don't need to understand this." From my perspective, that defeats the purpose of going straight to code.

Motivators
Another thing that left a bit of a bad taste had to do with test motivators. Fields spends some time telling us that it is important to understand our motivation for writing tests in order to write effective tests that match the motivation. He also spends quite a bit of time listing different motivators. The problem is that these motivators are not used in the rest of the book (unless I missed it). So it looks like we're being told that it's important to understand the motivation, but doesn't tell us how that impacts things in a practical way.

Naming
Another thing I don't agree with is Fields' opinion on naming tests. He likens test names to comments. Since the test methods are never called directly, the test names are unnecessary and at worst can add confusion. I agree that test names are comments, but I have seen usefulness in that. When a test has a good name, when it fails I can tell what happened simply by looking at the test explorer; I don't need to dig into details to see what went wrong (at least, I don't need to dig into the test details nearly as often).

I would liken test names more to variable names than comments. When we have useful variable names, it enhances the readability of our code. This is why I'll often include an intermediate variable. Then I can include some "comments" about what it is doing by giving it a good name, even if the code itself is not that hard to understand.

The Last Test
While I like most of the techniques presented, I wasn't a big fan of the final test state. His use of Test Data Builders throughout the book were interesting, and they gave me some ideas that I would like to work through. But the conclusion was a bit of a logical extreme:


Here's the text

public class CustomerTest {
  @Test
  public void chargeForTwoRentals() {
    assertMoney(
      5.7,
      a.customer.build().addRentals(
        create(
          stub(Rental class)
            returning(a.money.w(2.2).build())
            .from().getCharge()),
        create(
          stub(Rental class)
            returning(a.money.w(3.5).build())
            .from().getCharge()))
      .getTotalCharge());
  }
}

For someone walking up to this test for the first time, it is a bit confusing. I think it's because the Arrange, Act, and Assert all get mixed together. Fields promotes this as a good choice because it does follow "assert last" (although it's basically crammed the entire test into the assertion).

To pick this apart a bit, the behavior that we're testing (the "Act") is at the very end: "getTotalCharge()". The "Arrange" is really everything after "a.customer.build()..." which creates an object with test data so that we can call "getTotalCharge()" on a populated object. The "Assert" is the last step, but also the first step (which is weird in my mind).

I think that the test data builders can be very useful, but I would really like to see a standard "Arrange/Act/Assert" layout with some intermediate variables for readability.

Wrap Up
While Working Effectively with Unit Tests by Jay Fields does have some good advice, I think the drawbacks keep me from making it a recommendation. For general testing advice, I'd still go with The Art of Unit Testing by Roy Osherove.

Happy Coding!

Monday, March 13, 2017

Understanding Introversion (and Other Personality Features)

So, I recently finished reading Quiet: The Power of Introverts in a World That Can't Stop Talking by Susan Cain (Amazon link). I found this book to be very interesting and relevant to me. And it actually gave some names to things that I've noticed in myself.

I really wish that I had read this book sooner. I bought a copy of it last June (the receipt was still inside the book), but I didn't start reading it until last month.

I'm not really here to review the book, just point out some things that I found interesting. And I found a lot of things interesting. Here's a picture of all the markers that I dropped:

There is a bit of "Yay, Introverts!", but it's understandable. One very interesting observation is how the U.S. culture changed as more and more people moved into the cities.

The Extrovert Ideal
When people lived in small towns and rural areas, we knew all of our neighbors and the people that we interacted with. This meant that our judgments of other people were based on experience and reputation (although that's not always a great thing).

As people moved into the cities, now we are interacting with strangers on a regular basis. Who do we choose to do business with? Who do we choose for friends? Rather than relying on experience, we now have to make snap judgments based on first impressions. Now having an outgoing personality and winning smile is considered essential.

Introverts and Extroverts
I won't talk about the differences in being an introvert or extrovert because I've talked about that before: Becoming a Social Developer: A Guide for Introverts. The short version is that introverts get their energy internally while extroverts get their energy externally.

Insight: I'm Pretty Introverted
Cain presents a list of 20 (admittedly unscientific) questions to try to figure out how introverted or extroverted you are. I found that I answered all 20 toward the introversion side. This is not anything new to me. I know that I'm a pretty solitary person who enjoys the company of a few friends. I don't get bored when I'm alone. I love to read, think, and solve problems. Large gatherings and loud activities tend to exhaust me.

High-Reactives and Low-Reactives
Another thing that I was able to identify with is the idea of being a high-reactive. This stems from how people react to unfamiliar stimuli. A high-reactive person will tend to get agitated or nervous; a low-reactive will tend to stay calm.

This is not directly related to introversion and extroversion. There are high-reactive introverts and high-reactive extroverts.

Insight: I'm a High-Reactive
But this describes me pretty spot-on. When I go into a new situation or I'm doing something unfamiliar, I get extremely nervous. And it sometimes has to do with pretty ordinary things, like going to the eye doctor. This is why I can never take a polygraph test; just being tested will cause me to fail.

In addition, there's a tendency to observe things from the edges rather than just jumping in. That describes me pretty perfectly as well -- and I've written about that: High Risk vs. Low Risk. When I'm put into a conversation with people I don't know, I tend to observe and listen. I'm trying to figure out the "rules" before I join in.

Last month, I had someone point out that I was awfully quiet when she introduced me to some people that she worked with. This was because I didn't know the "rules" for interacting with that group of people. That is typical for me.

Public Speaking
Fear of public speaking is common across all people. And you would think that a high-reactive introvert would avoid it at all costs. But there are some people who enjoy it (including me). That enjoyment comes within some parameters.

Insight: I'm Fine When I'm Prepared
First, I have to be prepared. If I have time to figure out what I'm going to say in advance, I do just fine. I've confirmed the opposite. When I've been on panel discussions, I don't do very well. I'm a slow thinker, and I have trouble responding to ideas that I haven't had time to digest.

Second, I treat it like a performance. I have a role to play (more on that in a bit). If I understand that role and I'm prepared for it, I can execute on it just fine -- without falling into a panic.

Third, I have lots of repetition. I give the same technical talks over and over again. Some topics I have presented over 25 times. This means that I've heard most of the questions that people come up with, so I can answer confidently. And when I get a new question, I'm not afraid to say "I don't know. I'll need to look into that further."

All of these things combined have made me a successful public speaker even though my makeup fights against that.

A False Persona?
One thing that I've been concerned about is my stage persona. When I speak about technical topics (and some non-technical topics), I appear very extroverted. When I do this, am I still being true to myself?

Cain mentions a former psychology lecturer, Brian Little, who is an effective public speaker, quite boisterous on stage, and very entertaining. At the same time, he is an introvert who must find a quiet place to recharge between his presentations and interactions. That sounds familiar.

Little proposed the Free Trait Theory. The idea is that even though we're endowed with the trait of introversion or extroversion, we can act out of character in the service of "core personal projects", things that we care deeply about.

Insight: I Can Be Extroverted Regarding Things I'm Passionate About
So what comes out of this? It means that even though I am an introvert, I can act out of character when I'm doing work that I care deeply about. One thing that I care deeply about is helping developers learn about technology.

This is exactly what I'm seeing in my world. I'm not putting on an act. I'm still true to myself. I'm just behaving a bit differently than usual to reach a goal.

Encouraging False Behavior?
This all loops back to my work in encouraging people to be Social Developers. I've seen huge benefits from breaking out of my normal behavior to talk to strangers at developer events. Because I've seen these benefits, I want to encourage other introverted developers to try it and hopefully see some of those same benefits themselves.

It's a fine balance. I want to encourage people to try something new and scary. But I also want to make things as comfortable as possible (which is why I don't force people to talk to their neighbors in my presentations). And most of all, I want people to remain true to themselves.

Insight: A Social Developer Can Still Be True to Himself / Herself
Based on the idea that I can be extroverted about things that I'm passionate about, I don't have a problem with encouraging other people to do the same thing. Talking to strangers is outside the standard introvert behavior. But we can change our behavior for a good reason. In this case, it's expanding our knowledge, our circle of influence, our resources, and our friends.

So I don't feel like I'm encouraging people to change who they are. Instead, I'm encouraging people to change their behavior for something they care deeply about. (And hopefully I can encourage them to care deeply about it by showing the benefits I've found in my world.)

Wrap Up
I really enjoyed reading Quiet by Susan Cain. I don't know that I found out anything "new" about myself. But this definitely brought ideas into focus for me. I'm able to understand myself a bit better. I realize that who I am is normal, and there are plenty of other people out there just like me.

And with this better understanding of myself, I can better understand the people around me. I can recognize how we are the same and how we are different. That will lead to better interactions overall.

Happy Coding!

Monday, July 25, 2016

Learnings from The Book of F# by Dave Fancher

As you've probably guessed, I've been doing a lot of work with F# recently. A big part of those learnings was from The Book of F# by Dave Fancher (Amazon link).

The Book of F# by Dave Fancher
I set aside this month to dive deeper into F# (since I've been threatening to do it for a while but never put it high enough on my priority list). I started the month with Tomas Petricek's Real World Functional Programming, and that gave me a lot of things to think about. But as I got further in, I recognized that I really needed to get to the basics of F#. I was going through some samples and trying to explore a bit, but I felt like I was fumbling a bit.

This problem came to the forefront when I started working on the Euler Problems. I found that I was having a hard time knowing where to go next; I just didn't know enough about the language itself.

So, I put Tomas' book on hold (after 8 chapters), and picked up Dave's book. And that turned out to be exactly what I needed to do.

Starting with the Basics
I've picked up quite a few of the basics of F# from looking at samples and listening to other developers. But it has been rather hit-and-miss.

The Book of F# started right where I needed it to: how to use the tools. The first 2 chapters are short, but they are extremely useful when you're not familiar with the F# tools in Visual Studio.

Project Layout
One thing was file layout in F# projects. Because of the way that F# parses things, file order is important. Dave shows the various ways to add files and move them up and down in a project (something that you never have to do in C#).

Another part of that was how to use modules and namespaces. This is something I could have used about a month ago when I was working with my Digit Recognizer project. In that project, I needed to take F# code that was in a script and move it into a dll that I could use from a C# project. I fumbled my way through that (and also asked some advice from Mathias Brandewinder when I saw him at NDC Oslo). But this book really helped to formalize that.

Using F# Interactive
The other thing I really appreciated were the instructions on how to use F# Interactive in Visual Studio (I've been using Visual Studio as opposed to the command-line tools. I may start using those in the future.)

Particularly, Dave shows the various commands: #help, #quit, #load, #r, #l, and my favorite #time. I've been using #time quite a bit when I've been looking at how to improve performance when solving the Euler Problems.

I'm also glad that Dave points out the "it" value that gets automatically assigned by F# Interactive. I've found myself using that a few times to get some more information about something that was just evaluated.

One Parameter, One Return
Another thing that I appreciate is the statement that every function has one parameter and one return value. This is a great starting way of stating this (which I clumsily tried to describe when talking about partial application).

By thinking about functions this way, it makes partial application and composition a bit more clear -- although I still have a long way to go with function composition.

Semi-Colons (or Not)
Another one of the basics that I really appreciated had to do with the use of semi-colons. Because white-space is significant in F#, there are times where semi-colons are optional.

For example, when declaring a record type, you don't need semi-colons between the labels if you declare them on separate lines. These two declarations are equivalent:


This is also true when creating records with assignment pairs. I ran into this issue when I was going through an example from somewhere else. I was putting things on a single line and just leaving spaces, and that didn't work. When I added semi-colons it did. But the example didn't have semi-colons (because things were on separate lines).

This cleared up quite a bit of confusion for me.

Lots, Lots, More
Obviously, the book covers a lot more information about F# than what I've listed here. These are just a few of the things that have been tripping me up lately, so they were especially appreciated.

After going through The Book of F#, I know I've got a much better grip on the language.

A Bit of Fun
Another thing that I appreciated about The Book of F# is that the samples use rather nerdy references. This included references from "The Day the Earth Stood Still" and "Doctor Who" (in addition to a list of Arnold Schwarzenegger movies).

What I liked about the references is that they were just there (they weren't pointed out). So, if you had no idea who Rory Williams was, it wouldn't detract from the example. But if you do, then it's a nice nod to a bit of fun.

Wrap Up
The Book of F# has been a great help in getting me a formalized version of the basics of F# that I needed to move forward. A big thanks to Dave Fancher for going to the work of putting this together. (And Dave's a really great guy if you ever get a chance to meet him in person).

The Book of F# also makes a good reference. The material is well organized, and I've found myself flipping to the chapter on Collections to remind myself of a particular function.

Overall, this is a great place to get a solid foundation.

Happy Coding!

Monday, September 14, 2015

Design Patterns for Speakers: Review of Dan Roam's Show and Tell

If I had to describe Dan Roam's book Show and Tell: How Everybody Can Make Extraordinary Presentations (Amazon link), it would be:
Design Patterns for Speakers
I have to thank David Neal (@reverentgeek) for turning me on to this book. This is the result of one of the hallway conversations from That Conference.

Design Patterns
Here's the reason I compare this book to software design patterns. Design patterns are one of those things that programmers are already using, even if they don't realize it. But once we understand what those patterns are, we can start to use them more intentionally.

That was my experience reading this. I recognized some of the patterns in my own presentations, but I also saw a lot of places for refinement.

Four Storylines
Roam explores four different types of presentations: The Report, The Explanation, The Pitch, and The Drama.


And once he dives a bit deeper into each of these, I start to see the patterns in my own presentations. Primarily, I've been working with The Explanation and The Pitch.

For example, most of my talks that describe a technical topic, like Interfaces or Lambda Expressions, fall into pattern of The Explanation. These are designed to start out with what we already know and build step-by-step from there.

Some of my other talks are examples of The Pitch, including Clean Code and Unit Testing Makes Me Faster. Rather than explaining a technology, these are designed to encourage us to change our behavior.

The Details
Entire sections are spent on each of these storylines, as well as the PUMA model (I won't go into details of PUMA -- you need some reason to read the book).

And this is where I started to find places for improvement. Even though I was following the basic storylines in my talks, there are ways that I can handle the details a little differently to make them more effective.

And this is where I go back to the similarity to design patterns: now that I understand the patterns, I can start to use them more intentionally.

I'll stick in this gem from the final thoughts on The Explanation:
There is no such thing as a boring topic. There is only boring teaching.
And there's tons of great advice on how to make things engaging.

Looking for Improvement
Based on what I've read, I'm going to start reviewing my presentations. For example, I recognized a lot of the PUMA elements in my Clean Code presentation. My next step is to really review the talk (by watching this video) and picking out the elements one at a time. With that information, I will take a look at how I can re-order and enhance certain parts. The ultimate goal (just like with writing code) is constant improvement.

Challenge to Try Something New
One of the things that I've been thinking about a lot lately is Becoming a Social Developer (in case you missed it). In fact, one of the big things that I'm working on is a conference talk on the subject.

Originally, I was thinking that this would fall into The Pitch storyline. But after more consideration, I think The Drama is much better. This would change the way that I tell the story -- rather than starting with my eye-opening experience (like I often do when talking to other folks about this (because it seems the most exciting to me)), I should really start out with my low point -- how I was the loner at the conference for many years.

From the people I've talked to, I know that I'm not alone in this experience. Starting off with this helps build the idea of "you are not alone". Then moving to the discovery, the success, and (hopefully) the inspiration to see the world a bit differently and try things out for yourself.

Interestingly enough, this is roughly the pattern used in my original article, but I haven't been using it when talking to developers about it. It was really eye-opening to start examining these storylines to see how I can be more effective in my presentations.

And this has also convinced me that "Becoming a Social Developer" would make a great opening keynote for any developer event. If you'd like to help me with this, drop me a note on the website: Becoming a Social Developer.

[Update June 2016: I presented "Becoming a Social Developer" at NDC Oslo (read more or watch the video).]

Show
A major part of the book is about how to tell your story with visually -- more specifically, with drawings. And this is what David Neal was talking about when he introduced me to Roam's approach.

I've been thinking about how to incorporate this into my presentations as well. I'll probably start off small and work my way up. But David talked about how he's been really successful with the drawings that he uses in his presentations. (And I've seen one of his presentations, and it is very engaging.) I'm looking forward to exploring this a bit more.

Wrap Up
I highly recommend Show and Tell: How Everybody Can Make Extraordinary Presentations by Dan Roam for anyone doing presentations. I'm approaching this from someone who regularly does technical presentations, but this is useful for any type of presentation.

I really like these patterns. Now that I know about them, I can start to use them more intentionally.

Happy Speaking!

Tuesday, September 8, 2015

Update: Machine Learning Projects for .NET Developers

I've been working my way through Machine Learning Project for .NET Developers by Mathias Brandewinder (Amazon link). Apparently, I'm going pretty slowly since I got the book back in July (and was very excited about what I found). I've made it through Chapter 3 now.

Yes, I've been going slowly. But a lot of the information is really sinking in -- both about machine learning and about the F# language.

Very Approachable
One thing I really like about this book is that it is *very* approachable. When I looked at the first project on recognizing hand-written digits, I was expecting to get lost pretty quickly. And that's why I didn't undertake the challenge earlier (I made up my own challenge instead).

But Mathias made this task seem almost trivial. When he talks about the first step of doing the simplest thing possible (comparing light/dark pixel values from the data with the known values of the training set), it seemed blindingly obvious. Why didn't I think of that?

By seeing such an easy first step, I knew that the task was doable -- even by me.

And this was a hurdle that I needed to get over.

It doesn't stop there, though. That technique gets us positive results, but far from perfect. He then goes on to describe other machine learning algorithms that are a bit more complex (and a little bit outside of my competence with mathematics). And he also talks about the importance of comparing our "tweaked" algorithm to our baseline. We need to make sure we make things better and not worse.

Interesting Problems
Another thing that has kept my attention is the set of problems to be solved. I've already talked about how digit recognition had caught my eye, but it didn't stop there.

In Chapter 3, Mathias goes on to show how to build a simple DSL to query StackOverflow data. Does this sound familiar? If not, just go back to see how Barry Stahl (blog, twitter) blew my mind in a presentation on building a DSL to get StackOverflow data 2 years ago.

Getting into the F# Flow
The examples have also helped me "get into the flow" of F#. This has to do with really embracing the "pipe forward" operator |> and setting up parameters for functions so that they can easily be chained together.

Back to the StackOverflow DSL, I'm surprised at how easy this was to build. F# type providers are really awesome.

Here's a quick run through of the DSL code (which is available on GitHub). The first few lines set up the type provider:


Then there are a few functions to build the DSL:


The way that we interact with StackOverflow is by building a URL with a query string. So each of these small functions (tagged, page, pageSize) are designed to add to the query string. But these make things much easier to work with.

The last function (extractQuestions) executes the query.

And with this in place, we can start using it:


The first couple lines create aliases between "C#" and "F#" and their URL-encoded counterparts.

Then we see the awesomeness of having these small methods that we can pipe together. So what "fsSample" ultimately gets us are the StackOverflow questions that are tagged with "F#" and then gets the first 100 results. (The StackOverflow API is paged, and it returns the first page if no value is specified.)

What I've really grown to like is the syntax that we see in "analyzeTags". This summarizes the results. And it does it in very small pieces. First by getting the tags from the questions, then the number of times each tag appears, then limiting the results to tags that appear more than once, then sorting them in reverse order based on the count, and then printing out the results.

Here's the output of "analyzeTags fsSample":


Working with data this way really makes me like F# more and more.

Hey Look What I Can Do!
The best thing about Machine Learning Projects for .NET Developers is that it lets me do things that I never thought I could do. I had made these tasks out to be much more complicated in my mind.

But here's something I did today (by following the example in the book):


This is a map showing the population density per square km in each country. The data comes from the World Bank, with F# type providers providing easy access to the data, then using Deedle to create data frames that are easily consumable by R and the "rworldmap" package.

It sounds complicated, but there are only about 40 lines in the script file to do this. Really cool stuff.

More To Come
I'm less than halfway through Machine Learning Projects for .NET Developers, so there is much more to come. I think this is the catalyst that I need to travel much deeper into the functional world and the F# language.

Happy Coding!

Tuesday, June 30, 2015

Book Review: The Art of Unit Testing with Examples in C#

I recently finished reading The Art of Unit Testing with Examples in C# by Roy Osherove (Amazon link). This is the 2nd edition that came out in 2013. I actually finished a couple weeks ago, but I've been taking time to digest the material. (I've mentioned it herehere, and here.)

The short version is that you should read this book if one of the following applies to you:
  • You want to get started with unit testing.
  • You want to improve your testing techniques.
  • You want tips for successfully incorporating unit testing in your work environment.
This is a short book (about 230 pages), and it is a fairly easy read.

Was It Useful to Me?
The easiest way to answer this question is to take a look at the bookmarks I put into the book while I was reading.

Interesting Topics Marked
It's pretty easy to see that I found lots of passages to be useful to me. I've been a believer in unit testing for a while now. And this helped validate some of the approaches that I've used and also see some shortcomings in some approaches that I've used. I can't say that I agree with everything Osherove says, but I agree with a high enough percentage of it that the differences are negligible.

Highlights
There are quite a few things that stuck out for me. First is a clearly defined list of qualities that good unit tests have. And then it goes beyond that to describe the problems that keep us from having good unit tests (such as not having sufficient isolation) and looking at practical techniques for correcting those problems.

I also like that although he recommends TDD as a well-established way of building testable code, he does not proscribe it when first starting out. He says that it's more important that developers understand unit testing first. Having good unit tests is more important than a process. Once you understand the testing techniques, you can start to explore those other processes.

There is also quite a bit of time spent on isolation -- which is a huge issue when we're creating tests on discrete units of code. I appreciate that Osherove takes the time to go through the testing frameworks and isolation frameworks that he has found useful in his own work. (And this is one reason why I've looked into NUnit a bit further.)

When dealing with the various frameworks, I also appreciate that he tells how his tool set has changed since the publication of the first edition of the book and the reasons for that.

He also spends a bit of time talking about stubs and mocks and the differences between them. I will admit that I have not been very precise in my language when dealing with the fake objects that are in my tests. I am aware of this now and am working on being more accurate.

Osherove also provides some signs that you may have an over-complicated test or a test that tries to test more than one thing. For example, if you have control statements (switch, if, else) or loops (foreach, for, while), then you probably have logic that should not be in a test.

Along with this are a set of "smells" that you may have a problem with your tests. This includes things like constrained test order. If your tests have to be run in a particular order, then you have a dependency or shared state between tests that needs to be corrected.

I really appreciate a practical view of code coverage. Code coverage is not a silver bullet. Here's a quote:
"You could easily have close to 100% code coverage with bad tests that don’t mean anything. Low coverage is a bad sign; high coverage is a possible sign that things are better."
I have worked with teams that only cared about having 100% coverage (because this was something they could measure) without concern about the quality of the tests. In this situation, some developers will simply game the numbers so that they look like they have good results -- especially if the managers only care about the numbers. (And unfortunately, I saw that happen.)

An entire chapter is set aside for successfully bringing unit testing into your work environment. This is probably one of the most important sections. Finding the right champions, getting people of influence on your side, and setting realistic expectations are all key to a successful implementation.

My History With the First Edition
I'm a bit embarrassed to tell about my experience with the first edition of Osherove's book (back in 2009). I actually fought against unit testing in our environment back then. But (and this is a really big but), I wasn't fighting against unit testing itself, I was fighting against unit testing as the silver bullet that would fix a broken team. I used passages from the first edition to back up that viewpoint.

And I still believe that. Unit testing itself will not fix a broken environment. In this case, the team leaders were looking for a magic process that would idiot-proof development. What they really needed (at least in my opinion) was to invest in their developers. I am all about making developers better. Unfortunately, I saw them go through a new process every 6 months trying to fix things. It made me really sad to watch that.

So, I really enjoyed reading the second edition of the book because I'm now coming at it from a more productive direction. I have been extremely successful with unit testing, and I agree that it's one of the marks of a true professional -- someone who cares about the quality of the product that they deliver. (But that's another story.)

Wrap Up
So the short version is that The Art of Unit Testing is filled with great guidance and advice. As mentioned, where Osherove describes a technique that is different that what I have been doing, I explore it further.

For example, I've been swayed over to the side of not using Setup methods in test suites. Historically, I've used Setup methods, but after looking at things a bit more, I have changed my mind. I now agree with Osherove that we can enhance readability and maintainability by switching from Setup methods to factory methods that are called directly in the tests.

To make things more interesting, I had a recent conversation with Barry Stahl (my buddy that makes me think), and he described a technique that takes the concept of the factory method one step further. I'll definitely be exploring this a bit more.

Any book that encourages me to rethink the way that I've been doing things is a good book. We should be constantly re-evaluating our processes to make sure that we don't stagnate and are always headed in a productive direction.

Happy Coding!

Thursday, February 6, 2014

Book Review: Parallel Programming with Microsoft .NET

I recently finished reading Parallel Programming with Microsoft .NET by Colin Campbell, Ralph Johnson, Ade Miller, and Stephen Toub (Amazon link or read for free online). This book has a rather intimidating subtitle: "Design Patterns for Decomposition and Coordination on Multicore Architectures", but the content is actually very approachable.

I picked up this book to get better familiarity with the Task Parallel Library (TPL), and it gave me the information I was looking for (plus, quite a bit of information that I didn't know I needed).

This is a fairly short book -- just 130 pages, plus the appendices; it is approachable; and it clearly describes the problems that can be solved with parallel programming.

What's Covered
Parallel Programming shows how to implement various scenarios using the Task Parallel Library (TPL) and PLINQ (Parallel Language INtegrated Query). This book is from 2010, so it is from the .NET 4.0 era (after the TPL was added, but before async/await).

What I really like about this book is that it focuses on problems and solutions. It shows several different patterns and ways to implement parallelism in our applications, but it has a primary concern of making sure that we select the solution that matches our problem and environment.

We can get an idea of that by looking at the chapter titles:
  1. Introduction
  2. Parallel Loops
  3. Parallel Tasks
  4. Parallel Aggregation
  5. Futures
  6. Dynamic Task Parallelism
  7. Pipelines
  8. Appendix A - Adapting Object-Oriented Patterns
  9. Appendix B - Debugging and Profiling Parallel Applications
  10. Appendix C - Technology Overview
The Introduction gives the basics of what parallelism gives us and also what limitations we can expect. Just because we run parallel code across 8 cores does not mean our application runs 8 times faster. But we can get a good idea of performance improvement by calculating the degree of parallelism along with a few other factors. This is an easy-to-follow introduction, so even if you've never worked with parallel code or understand how the hardware handles requests across multiple cores, you can still understand the concepts presented.

The introduction also gives a quick overview of what will be covered in the other chapters -- with a focus on making sure that we select the right parallel pattern for our problem.

Chapter 2 covers parallel loops. This includes Parallel.For, Parallel.ForEach and also AsParallel in PLINQ. It gives the basics of the syntax, but more importantly, it talks about situations were we *can* use these constructs.

We cannot simply change a "for" loop into "Parallel.For" without considering the work that is actually being done inside the loop. This could result in corrupted data (if multiple threads update the same values without proper synchronization) or deadlocks (if multiple threads try to update values with improper synchronization). And it's very likely that even if our code works, we may actually see slower performance than if the code ran sequentially (due to the added overhead of the additional threads).

So, I really appreciate that quite a bit of time is spent in determining whether our code is suitable for a parallel loop. If not, there may be some changes we can make to our code to facilitate it, or there may even be a better pattern for us to look at.

And we don't simply want to add locks to our code to handle synchronization. This can lead to slower performance and deadlocks. It's much better if we can architect our objects and methods so that they do not require synchronization. Instead of using a shared state that needs synchronization, we should look at ways to accomplish the same task without needing that shared state.

Other chapters cover the topics in a similar manner, and there are quite a few references from one chapter to another to explore different options. Just to give you an idea of what's covered in the chapters, here's a screenshot from the introduction (it's in the middle of this page: http://msdn.microsoft.com/en-us/library/ff963542.aspx)


Again, this is a great approach to understand the types of problems that can be addressed with parallel programming and how to make sure we use the right implementation for our problem.

Another thing that I really like: there are clear recommendations and examples on how to handle things like cancellation and exceptions. These things are quite a bit more complicated when we may have things running in parallel.

Parallel Programming vs. Async
Parallel programming and asynchronous programming are 2 different things. But they are related. We most often think of parallel programming as running the same function across multiple cores so that we can enhance performance. (And from the chart above, we see that there are several variations that let us take advantage of parallelism if we have some slightly different requirements.)

Asynchronous programming is generally more about "go do this, and let me know when you're done" without interrupting the flow of the rest of the program. So, we may kick off a long-running calculation on a separate thread so that our UI stays responsive.

But in both of these cases, the result is that we end up using multiple threads (most of the time). And so we see both parallel programming and asynchronous programming implemented with Tasks and the Task Parallel Library.

Last year, I reviewed Async in C# 5.0 (it looks like almost exactly a year ago, actually). And one of the caveats in my review is that you need a good understanding of Tasks before reading it. It turns out that Parallel Programming with Microsoft .NET give you (almost) all the information you need to understand how Tasks are used with async.

Is This Still Relevant?
This book is from 2010, and we've had several important updates and additions to the .NET framework. So, is this book still relevant?

The answer is "Yes". The Task Parallel Library has had a few additions (including the IProgress<T> interface), but the core functionality is still the same, including using a CancellationTokenSource, spinning up new Tasks, and dealing with AggregateExceptions.

I found the Appendix on Adapting Object-Oriented Patterns to be very interesting. I'm a big fan of design patterns (as long as they are used properly). The appendix takes several OO patterns and shows how we may need to modify them to make sure they are thread-safe. For example, the "standard" implementation of the Singleton pattern (which includes a class with a static instance field) can cause problems in a multi-threaded environment. The book provides several ways to make a thread-safe Singleton, including adding synchronization or by using Lazy<T> for the instance. Very cool stuff.

Wrap Up
I'm not actually expecting to dive into parallel programming too deeply. Historically, I haven't had too many business problems that really warranted it. But I do have a much better understanding of the Task Parallel Library and PLINQ. I have been using the TPL more and more in my code (primarily for the asynchronous bits), and this book has given me some good ideas on how I can start expanding into the parallel world.

Parallel Programming with Microsoft .NET is an approachable resource for anyone who is looking to better understand the problems of parallel development and also for developers who simply want a better understanding of the Task Parallel Library for use with async method calls. Personally, I expect to use this information as I dive deeper into functional programming in .NET.

Happy Coding!

Monday, January 27, 2014

Book Review: Learn You a Haskell for Great Good!

I recently finished reading Learn You a Haskell for Great Good! by Miran Lipovača (Amazon Link). And, yes, it did take me a long time to get through this book -- mainly due to other distractions. I started reading this way back in October, got a good start, and then let it sit around for a while.

I'll split this into 2 parts -- the basics and the more advanced stuff.

The Basics
Learn You a Haskell gives a fairly gentle introduction to functional programming and the Haskell language. Lipovača understands that functional programming is an unfamiliar concept to many programmers who are starting out with Haskell. As such, he combines functional programming concepts with the description of how the various elements of the language work.

Haskell is a purely functional language, meaning that functions are first-class citizens (actually, the only citizens). And it is built around the concepts of immutability, "no side effects", and repeatability. Some other functional languages have compromises that let them fit in with more imperative programming.

I found this very helpful as a first step into functional programming. I really had to start thinking about immutability and repeatability in my own Haskell code. There is no other way of doing it.

The book takes small steps in introducing new concepts. This is very additive in nature (which is nice). And to describe some of the basics, the examples build simple functions based on prior learnings. Often, these simple functions end up as standard functions that are supplied with the standard modules. But it's nice to see how these functions actually work.

For an example, take a look at the zipWith' function (which I mentioned earlier in a different context):


This is from Chapter 5 (Higher-Order Functions) and shows several different concepts that are covered earlier. The concepts include function declaration (the first line), lists (the angle brackets), filters (the last 3 lines that work like a "case" statement), working with head/tail on lists (the "x:xs" and "y:ys"), and recursion (the "zipWith'" call in the last line).

This particular example is to add on the "higher-order function" part. A higher-order function is a function that takes another function as a parameter. In this case, the zipWith' function takes a function and 2 lists as parameters. Then it applies the function to each element of the lists and returns a list.

For example:
zipWith' (+) [1,2,3] [4,5,6]
Takes the "+" function (yes, that's really a function in Haskell) and uses it with the first element of each list, then the second element of each list, and so on. So, it calls "1 + 4", "2 + 5", and "3 + 6".  The result is a list: [5, 7, 9].

And of course, this leads to the Foo Bar example that I actually like.

The Advanced Stuff
The skill level ramps up. Lots of concepts are covered including Functors, Applicative Functors, Monoids, and Monads.

Things were a little fuzzy to me in the middle of the book. Since Lipovača uses the "building on previous knowledge" approach. I figured that I would be totally lost for the rest of the book, but I kept pressing forward.

What I found was that I was able to pick things back up again. For example, I got a bit lost in the description of applicative functors. But then, moving on to monoids, Lipovača describes how monoids build on top of applicative functors. And for some reason, reviewing the old material in conjunction with the new material made the old concept "click" with me.

Where I Explored Further
To help me get acquainted with Haskell (and functional programming in general), I took a look at the Euler problems. These are math-related problems that really lend themselves to being solved functionally. I used these to get me to start thinking functionally. I wrote about my encounter with the first Euler problem a few months back.

And I spent quite a bit of time on the second Euler problem. This deals with the Fibonacci sequence. I have a bit of fondness for the Fibonacci sequence. I have used a non-recursive implementation in C# in some of my previous examples. Since the Fibonacci sequence is often solved with a recursive function, I started there.

What I found is that creating a Fibonacci sequence with a classic recursion method is extremely slow. So, I spent some more time trying different approaches. And I found some really interesting Haskell examples online with completely different approaches. I'll talk about these in a later article.

Wrap Up
I found Learn You a Haskell for Great Good! to be a really good resource for me. It gave me a good overview of functional programming concepts. Now, I have had some exposure to functional concepts; I've been exploring them casually for the last year or so. Someone who is brand new to functional programming may need to spend a bit more effort on the early chapters. But that effort will pay off.

So, I put Learn You a Haskell for Great Good! into the "recommended" category. Check it out if you want to get started with programming in a purely functional language.

Happy Coding!

Tuesday, October 8, 2013

Book Review: Designing with the Mind in Mind

User interaction design is one of those things that I'm fairly decent at, but I don't excel at it (yet). In that vein, I've read several design books over the last few years including Don't Make Me Think (Steve Krug), Universal Principles of Design (Lidwell, Holden, and Butler), and, one of my favorites, The Design of Everyday Things (Donald A. Norman). For more on these books, you can refer to the UX Design section of my Bookshelf.

To continue my exploration, I recently read Designing with the Mind in Mind: Simple Guide to Understanding User Interface Design Rules by Jeff Johnson (Amazon Link). Like most of the design books that I have, this one is fairly short (under 200 pages), but it is packed with lots of useful information.

This book is primarily about how humans perceive the world, and how we can use that to our advantage when building our user interfaces. It also uses studies about how memory, recognition, and process affect how we interact with the world.

Chapters
The chapter titles themselves are a list of how humans work:

  1. We Perceive What We Expect
  2. Our Vision is Optimized to See Structure
  3. We Seek and Use Visual Structure
  4. Reading is Unnatural
  5. Our Color Vision is Limited
  6. Our Peripheral Vision is Poor
  7. Our Attention is Limited; Our Memory is Imperfect
  8. Limits on Attention Shape Thought and Action
  9. Recognition is Easy; Recall is Hard
  10. Learning from Experience and Performing Learned Actions are Easy;
    Problem Solving and Calculation are Hard
  11. Many Factors Affect Learning
  12. We Have Time Requirements

In each chapter, Johnson gives specific examples of these traits and how our application design can play on the strengths and weaknesses of each.  Here are few that stuck out to me.

Gestalt Principles
Chapter 2 ("Our Vision is Optimized to See Structure") covers the Gestalt principles of human perception. Apparently, these are fairly widely-known (and I've recognized some of them in my own design work), but this is the first time I've seen them delineated.

For example, the Proximity principle states that relative distances between objects determines how we group them mentally. Look at the following picture.


We tend to see the blue stars as 3 rows, and we tend to see the orange stars as being in 3 columns. We can use this in our UI design to make sure that things that go together are actually perceived as belonging together.

The Continuity principles states that we often perceive things as continuous even if it's broken in the middle. As an example, we'll consider a slider bar (this one is from Windows Media Player).


The volume slider is made up of 3 parts: the blue line on the left, the circle in the middle, and the grey line on the right. But the tendency of our brain is to see a single line with the circle on top of it. Now, whoever designed this particular slider added something to enhance this perception. Notice that the circle has a dark line going through the middle of it. This gives the added perception that the circle is semi-transparent, and we are seeing the continuous line underneath it.

The other Gestalt principles (similarity, closure, symmetry, figure/ground, and common fate) all have similar examples.

These principles seem obvious once you see them stated. But unfortunately, this chapter also contains several examples of applications that do not follow these principles, which leads to difficulty in using them.

How Fast Does Our Brain Work?
Another chapter that I found especially interesting was Chapter 12 ("We Have Time Requirements"). This takes a look at how long it takes the brain to perceive things, how long it takes us to process information, how long our attention is really dedicated to a single task, and so forth.

The chapter contains an interesting list of perceptual and cognitive functions and the duration of each. This includes things like the shortest gap that we can detect in sound (1 millisecond), minimum noticeable lag in ink as someone draws with a stylus (10 milliseconds), the time required for a skilled reader's brain to comprehend a printed word (150 milliseconds), duration of unbroken attention to a single task / "unit task" (6-30 seconds), and time to choose a lifetime career (20 years).

The most interesting part has to do with the time of a "unit task". This is covered quite extensively. Unit tasks are small (such as filling in login information). We will dedicate 6-30 seconds to a task before our brain jumps away. Now, it may jump right back, or it may get distracted by something else. Our goal as application designers is to try to keep our tasks within this time window.

For example, rather than having someone fill out an entire tax form in one big scrolling screen, we should break this process down into smaller tasks in a wizard-type interface. This allows us to concentrate on one small task at a time. When we click "Next" our brain may wander (or take a quick breather), but we're right back to concentration on the next task.

Wrap Up
We looked at just 2 of the chapters here. But I found each chapter interesting. I learned quite a bit about how the human mind works. And more specifically, how I can apply that knowledge to how I design my applications.

I know that my personal web site is in pretty bad shape right now (especially the home page). But this book helped me pinpoint several specific problems. I've been planning on updating things for a while, but this will give me the push to do it in the (hopefully) not-too-distant future.

Designing with the Mind in Mind is a great book for anyone wanting to better understand their users (and how their brains work). Once we understand our users, we are better prepared to create excellent experiences for them in our software.

Happy Coding!

Tuesday, August 13, 2013

Book Review: Pro ASP.NET MVC 4

It's been a while since my last book review, and there are a couple of reasons for that. First, I've been really busy this summer (between speaking engagements and producing 2 Pluralsight courses). And second, because I picked a 700 page book as my next read: Pro ASP.NET MVC 4 by Adam Freeman (Amazon link). The good news is that this was a very good read.

Two Parts
I really like the layout of this book.  It's split into two primary parts.

Part 1 covers the first 300 pages: Introducing ASP.NET MVC 4.  After some introductory chapters (about the MVC pattern, the Razor view engine, and some other tools), Freeman leads us through the process of building an on-line store. During each of these steps, more and more features are explored through the code. This includes things like strongly-typed views, controllers and actions, routing, dependency injection, validation, and security.

These are all "just enough" explanation to get the application to do what we need it to do. This seems like a very relevant example, and I found it helpful to follow along (sometimes typing things in and sometimes just going through the code for the completed project -- although I'll admit to having a run-in with Entity Framework not behaving as I expected it to).

Part 2 is the rest of the book and dives into the details. This makes for an excellent reference and covers pretty much all of the topics: URL Routing, Controllers, Actions, Filters, Views, Helper Methods, Model Binding, Model Validation, and Bundles.

Each of these chapters starts out by looking at the standard "in-the-box" functionality and then goes on to show how you can either customize the behavior or completely replace it with your own objects. Another thing I like is relevant warnings. For example, there may be a section that shows how to put validation into the Controller, but then emphasizes that it probably doesn't belong there; it really belongs in the Model itself or through custom model binding (in order to preserve the separation of concerns recommended by the MVC pattern).

Some Complaints (not mine)
I want to address some complaints that have shown up in some reviews.  But first, we need a little history. I own Pro ASP.NET MVC 2 Framework by Steven Sanderson. This is the 2nd edition of this same book.

[Editor's Note: I actually did a review of this book in 2011: Book Review: Pro ASP.NET MVC 2 Framework]

Next comes, Pro ASP.NET MVC 3 Framework by Steven Sanderson and Adam Freeman. This is the 3rd edition (which I do not have). There were some complaints that the 2nd and 3rd editions had much of the same material and didn't really show the differences in the versions. Personally, I don't have a problem with that. I see this as a reference for whatever current version is referred to. There are other references to see "What's New in MVC 3" or whatever.

Pro ASP.NET MVC 4 by Adam Freeman (the book we're looking at here) is the 4th edition. This has a lot of duplicated information from previous editions (the Sports Store example is the same example as was used in the MVC 2 book, but with some obvious updates for the new features). As mentioned above, I don't see the duplication as a drawback -- this is a 700 page reference book.

A Few Quirks
With that said, there are a few quirks to the book that are minorly distracting. This is to be expected in any technical book of this size; however, since this is the 4th edition, I would have hoped that more of these would be worked out.

One strange thing is that it looks like there was a search-and-replace done for several words to facilitate the diagrams and code samples.  For example, in Chapter 16, there is a sentence with the phrase "...which isn't suiTable 16-for all action methods."  I'm sure this should read "...which isn't suitable for all action methods", but the word "table" was replaced with "Table 16-".  This also happened with "figure" as in "... you can conFigure 17-the settings of the default factory..."

Another quirk has to do with the history of the book. As mentioned above, the 3rd edition was co-authored by Adam Freeman and Steven Sanderson. A few vestiges still exist in the 4th edition. For example, there are a few places that say, "We both agree that..." which seems a little strange if you don't know the history of the book. In addition, other books by both Freeman and Sanderson are referenced for more details. Again, it seems a little strange based on the "voice" of the author.

But none of these items would keep me from recommending this book.

Wrap Up
Pro ASP.NET MVC 4 is a complete reference of the MVC framework. I really like the practical walk-through example that takes up Part 1 of the book. And I also like the deeper dives into each feature that is covered in Part 2. It's nice to know that I can replace the view engine if I really want to (although I really don't see that happening for me).

I'm a big fan of ASP.NET MVC (especially since I spent so much time working/fighting with WebForms). It's nice to see that many of the features (such as URL Routing and Script Bundling) are making their way into the base ASP.NET libraries so that we can use them regardless of how we build our websites.

In the near future, I need to revamp my website. ASP.NET MVC is definitely a contender technology. But I may simply use it as a framework to deploy a mainly HTML/JavaScript site. We'll see what happens. One of the big challenges is to create some "pretty" URLs without breaking any of the existing links that I have scattered across the internet.

But back on topic, if you need a reference for ASP.NET MVC, I would definitely recommend this book.

Happy Coding!

Sunday, May 5, 2013

Book Review: Don't Make Me Think

I'm still powering through my Reading List for this year.  I recently finished Don't Make Me Think: A Common Sense Approach to Web Usability by Steve Krug (Amazon Link).  The second edition of this book (the one I read) was published in 2006 and is in its 13th printing, so it's been around a while.  But it has stood up to the test of time.

Krug is a usability consultant -- his job is to set up user testing of web sites and report the findings.  This book helps you do the bulk of this work yourself.  As Krug would say, it isn't a replacement for a usability professional, but most of us won't spend the money on one.  This book shows that you don't need to be a professional to get useful results out of user testing.

This is a purposefully short book (under 200 pages with lots of diagrams and pictures).  So, I won't go into too many details.  But I'll point out one or two things that I found particularly useful.

Usable Web Sites
Don't Make Me Think focuses on how to create usable web sites (note: web sites, not web applications).  With that said, you can get a lot just from the chapter titles.  Here are the first 7 chapters:
  • Don't make me think! - Krug's First Law of Usability
  • How we really use the Web - Scanning, satisficing, and mudding through
  • Billboard Design 101 - Designing pages for scanning, not reading
  • Animal, vegetable, or mineral? - Why users like mindless choices
  • Omit needless words - The art of not writing for the Web
  • Street signs and Breadcrumbs
  • The first step in recovery is admitting that the Home Page is beyond your control
This book is purposefully short and has plenty of real-world examples of web pages, how the companies have improved the pages over time, and how Krug would continue that improvement.  This is not a "let's laugh at bad web pages" book; which is good.  A lot of us know what not to do.  Where we need help is in doing it right.

Krug's Laws of Usability
In addition to the chapter titles, we get Krug's Laws:
  • Don't make me think!
  • It doesn't matter how many times I have to click, as long as each click is a mindless, unambiguous choice.
  • Get rid of half of the words on each page, then get rid of half of what's left.
These seem pretty basic.  But I have to admit that this is not the way that I've approached web design (which I'll be the first to admit isn't the greatest).

Krug bases these laws on how people actually use the web.  People don't stop to read every word on a page.  They usually go to a site for a specific purpose (such as to find the address of a store location).  They don't care about the "fluff".  They don't really care about the welcome message.  They are scanning the home page looking for a link that looks like it's "close enough."

If we keep this in mind, the laws make perfect sense.  We want information on our web site to be clearly available and for links to be as obvious as possible.

Usability as Common Courtesy
Chapter 10 talks about the Reservoir of Good Will.  This reservoir can be diminished when the user has trouble finding information, or it can be refilled by easily giving him just what he is looking for.  If the reservoir is depleted, then the user simply abandons the site.

I never thought about usability in this fashion before.  But I've noticed in the last week or so that this is exactly how I use web sites.  For example, I was looking for the hours of the local e-waste drop off location (I knew where the location was, just not when they were open).

I did a couple of web searches but didn't find what I was looking for.  Then I went to my municipality's web site and still had a bit of difficulty finding what I was looking for.  I finally stumbled across the listing of the drop-off locations, but I didn't see any hours listed.  I ended up loading up the car and heading over there only to see a "Closed Mondays" sign on the gate (and guess what day it was?).  I went back to the site later and found the hours buried in a block of text (9 am - 3 pm Tuesday through Saturday).

Krug gives a list of things that can diminish the reservoir, including hiding information that I really want or asking for information that you don't really need (do you really need my phone number to sign me up for an email newsletter?).

Conversely, there are a number of things that help to refill the reservoir such as tell me what I want to know and save me steps wherever you can.

Wrap Up
I would recommend Don't Make Me Think to anyone with a web site.  It will make you stop and think about how people actually use your site.  The examples focus on e-commerce sites (simply for consistency), but the principles apply to whatever web site you may have.  Keep the user in mind, and don't make him think.

Happy Coding!

Wednesday, April 24, 2013

Book Review: Building Windows 8 Apps with C# and XAML

I recently finished reading Building Windows 8 Apps with C# and XAML by Jeremy Likness (Amazon link).  Unfortunately, I am unable to recommend this book.

Publisher Gambling
I'm going to chalk the primary issues up to publisher gambling.  The technology industry moves quickly (as we all know).  Technical books that are based on a new/updated technology have a very short shelf life -- especially when we have new versions of tools coming out every 9 months.  This means that technical books are written with pre-release versions, and sometimes things change in the final release.

Building Windows 8 Apps with C# and XAML was released in October 2012, which means that it was written with pre-release versions of Windows 8 as well as Visual Studio 2012.  Since I haven't worked with the pre-release tools, I'm not sure how much has changed, but knowing that Jeremy Likness is a good speaker, author, and consultant, I have to give him the benefit of the doubt.

This was a gamble that the publisher lost.

What Turned Me Off
That last thing I want to do is to rip a book apart.  There is a lot of work that goes into working with the technology, writing it down in a way that makes sense, going through the editing process, and releasing it into the wild.  So, I'll just give one thing I had difficulty with.

The first difficulty was with the example in Chapter 2.  This was a "follow along at home" sample.  The scenario was to create a Windows 8 Store Application that did 3 things:
  1. Use the webcam to take photos
  2. Save photos to the Pictures Library (or SkyDrive, or wherever else)
  3. Act as a Share Target for pictures
If you've been following my blog, you know that one of the things I'm most excited about in Windows 8 is the Sharing system (see Steal My Windows 8 Idea: Share with Grandma from last December).  So, I was very glad to get "straight to the point" with a sample I was interested in.

I followed along step by step.  The application would build and deploy successfully.  I could take photos with the webcam.  But I couldn't save, and the app wasn't showing up as a Share Target.  I did what you're supposed to do in this situation: I double-checked the steps to see if I missed anything.  I took a second look at the configuration screens to see if there was anything different or obviously wrong.

I finally figured out what was wrong with the Share Target: In the application manifest on the "Declarations" page, I needed to indicate the "Supported file types" (which is empty by default).  I immediately went back to book to see if I had missed something.  The section that talked about adding the Share Target on the Declarations page did not mention needing to change supported file types.  There was a screenshot of the Declarations page, but unfortunately, this value was not shown (it was hidden under the Output window).

I checked the "Supports any file type" box, and the Share Target functionality started to work.

For the Save functionality, things were a bit trickier.  I was getting a buffer overflow exception at a runtime.  Again, I checked the code against the code in the book and everything matched.  I knew that this was not something I would be able to debug myself (since I'm not familiar with the WinRT libraries), so I went to the code download.

On the download site, there was a note that the ImageHelper application (the one I was working with) had a buffer overflow problem that had been updated.  So, I downloaded the code and things worked from there.

First Impressions are Important
I'll have to admit that this experience put me off for the rest of the book.  As I read through the other examples, I had doubts about whether they were accurate.  (I know logically that they were okay; only 1 other project was mentioned on the code download site as needing updates -- but this doesn't change the "gut feeling" based on experience.)

I have a few other concerns with the book regarding how deeply (or not) specific topics were covered, but I'd rather not focus on any more negatives.

Wrap Up
Unfortunately, I'm not able to recommend Building Windows 8 Apps with C# and XAML.  I'm still looking for a good reference on the topic.  If you have any book recommendations, feel free to leave them in the comments.  Now, I'm off to the next book in the stack.

Happy Coding!

Friday, March 29, 2013

Reading List 2013 (So Far)

I am a book person.  I realize that most people aren't.  Everyone has a preferred way of getting new information into his/her head: it could be books, it could be videos, it could be live demonstrations, it could be classroom learning, or it could be one-on-one mentoring.

I've read a ton of technical books over the years (well, I don't know if it is literally a ton, but several hundred pounds for sure).  For this year, I gave myself a goal of reading one technical book a month.  Some of the early books have been a bit on the short side, so I've managed to read a few more up to this point.  Here's what I've read so far this year and what I've got "in the stack" for the next several months:

Completed 2013 Reading (with Reviews)

Async in C# 5.0  by Alex Davies
Jeremy's Review (Jan 2013) / Amazon Link

Working Effectively with Legacy Code by Michael C. Feathers
Jeremy's Review (Feb 2013) / Amazon Link

Test-Driven Development by Example by Kent Beck
Jeremy's Review (Mar 2013) / Amazon Link

Javascript: The Good Parts by Douglas Crockford
Jeremy's Review (Mar 2013) / Amazon Link

The Agile Samurai: How Agile Masters Deliver Great Software by Jonathan Rasmusson
Jeremy's Review (Mar 2013) / Amazon Link

In Progress

Building Windows 8 Apps with C# and XAML by Jeremy Likness
Amazon Link

In the Stack

C# Smorgasbord by Filip Ekberg
Amazon Link

Don't Make Me Think: A Common Sense Approach to Web Usability by Steve Krug
Amazon Link

Refactoring: Improving the Design of Existing Code by Martin Fowler
Amazon Link

Designing with the Mind in Mind: Simple Guide to Understanding User Interface Design Rules by Jeff Johnson
Amazon Link

Peopleware: Productive Projects and Teams by Tom DeMarco & Timothy Lister
Amazon Link

Refactoring to Patterns by Joshua Kerievsky
Amazon Link

Current Themes
As you can probably tell, I've got a couple of themes with this list.  First is Best Practices.  I have had a lot of successful projects in the past as well as a number of not-so-successful projects.  I've been analyzing the differences based on my own experiences.  What I've found is that many of the conclusions that I've reached through experience are itemized in several of these classic books, such as Clean Code which I read last year.  (And as I've noted before, there are some books that I really should have read quite some time ago.)

Another theme is usability and user interaction design.  This is an area that has always interested me.  I don't have the natural eye that many designers (and a few developers) have.  I make usable (but not brilliantly usable) applications, and I'm looking to improve that skill.

The Heap
I'm a just-in-time learner on many topics, so I'll bump things out of the stack if there's something that I need to pick up more quickly (or if my whims change).  In addition to the current Stack of books, I've also got a larger Heap.  These are the books that I've been collecting, but haven't gotten to yet.

The Heap has some more user interface design books (such as About Face: The Essentials of User Interface Design).  And also a number of books about other languages (such as Haskell, Lisp, and a few others that use Scheme or Eiffel).  I'll probably start out with Seven Languages in Seven Weeks to get a taste before diving deeper.

Wrap Up
Constant learning is essential in the development world.  There's too much out there to be able to master everything, but we can get a taste for a lot of different techniques and technologies.  And we can take a deep dive to reach expert level in one or two.

Whatever your mode of learning, keep doing it.  If you've got any book suggestions, let me know.  The Heap is constantly growing, and I'm always looking for more.

Happy Coding!