Announcing Head First C#, 2nd edition

Head First C#, 2nd Edition

Jenny and I are really proud to announce that the second edition of our bestselling C# learning book, Head First C#, went to press! We worked really hard on it, and we’re very happy with how it came out.

Are you looking for the easiest way to become a great C# programmer? If want to get productive fast with C#, .NET and Visual Studio 2010, then this is the book you’re looking for. We show you how to learn C# by building over 100 different projects—including lots of games!—and solving dozens of puzzles.

Head First C# is a complete learning experience for programming with C#, the .NET Framework, and the Visual Studio IDE. Built for your brain, this book covers C# and .NET 4.0 and Visual Studio 2010, and teaches everything from inheritance to serialization.

But don’t take our word for it! Download the free Head First C# eBook [PDF], which includes the first three chapters, complete. Or have a look at this typing game project [PDF] from chapter 4 to get a preview of the kinds of projects you’ll build throughout the book.

So check out Head First C# today, and see what the buzz is all about! Available now from O’Reilly, and wherever fine books are sold.

Nonfunctional Requirements Q&A

Non-functional requirements Q&A: We answer questions from readers about using nonfunctional requirements on a real software project, and how to use them on a real software project.

Non-functional requirements: Planning out how well your software will work

A couple of months ago I wrote a post called Using nonfunctional requirements to build better software. It’s basically a step-by-step guide for creating an easy, practical technique to use nonfunctional requirements on a real software project, treating them in a way that’s similar to how a lot of Agile teams treat user stories, scenarios and other functional requirements: by sticking them on index cards and using them to do some lightweight planning.

Since then, I’ve gotten a lot of questions about nonfunctional requirements (or, as some people call them, non functional requirements, behavioral requirements, quality attributes, and probably half a dozen other names). Based on the questions I’ve been getting, a lot of people really seem to want a solid overview of exactly what they are:

  • What are nonfunctional requirements?
  • What goes into a good nonfunctional requirement?
  • Is there a nonfunctional requirements checklist that I can use?
  • How do I write down a nonfunctional requirement? Is there a nonfunctional requirements template I can use?

Luckily, Jenny and I addressed exactly those questions in our first book, Applied Software Project Management, and I’ve gotten feedback over the years from people who read it (and other writing I’ve done about requirements), and tell me it helped them get a handle on the concepts behind nonfunctional requirements. So I’ll do a little requirements Q&A and address those questions one by one, drawing from the book where possible. And I’ve posted an O’Reilly Community blog post called Understanding nonfunctional requirements with some additional information, which should also help get to the bottom of the issue.

Q: What are non-functional requirements?

Non-functional requirements — or behavioral requirements, or quality attributes — describe how well a system performs its function. This is fundamentally different than the typical functional requirements that most of us are used to, which describe what that system does.

Here’s a quick example. Whenever I’m talking about requirements, I like to use a “search and replace” feature in a word processor or text editor as an example, because we’re all familiar with how it works. So while a functional requirement for “search and replace” might describe how the case-sensitive matching works: “If the original text was all uppercase, then the replacement text must be inserted in all uppercase.” A nonfunctional requirement, on the other hand, might describe the performance (“it must be able to replace 1000 search terms in a 3MB document in under 250ms on one of our standard test VMs running at 50% load”).

Q: What goes into a good nonfunctional requirement?

A good nonfunctional requirement is one that makes it clear to everyone on the project — including the user (or someone who really understands what the user needs) — exactly how the software has to perform. Remember, a good requirement (functional or nonfunctional) is about understanding and addressing the needs of a user.

Here’s what Jenny and I wrote about nonfunctional requirements in our first book:

Users have implicit expectations about how well the software will work. These characteristics include how easy the software is to use, how quickly it executes, how reliable it is, and how well it behaves when unexpected conditions arise. The nonfunctional requirements define these aspects about the system. — Applied Software Project Management, p113 (O’Reilly 2005)

It’s really easy for non functional requirements to be unclear or ambiguous. The best way to make sure a nonfunctional requirement is clear and easy to use is to quantify it. So instead of saying that a task must be done quickly, write down the maximum number of seconds it must take to perform a task. The maximum size of a database on disk, the number of hours per day a system must be available, and the number of concurrent users supported are examples of requirements that the software must implement but do not change its behavior.

Q: Is there a nonfunctional requirements checklist that I can use?

We put together a nonfunctional requirements checklist that I’ve used many times on real projects. It’s based on a list of nonfunctional requirements we included in Applied Software Project Management.

Here’s one thing to keep in mind about this (or any other) non functional requirements checklist: as you’re reading it, you’ll probably find yourself thinking, “Wait a minute, all my software needs to be flexible (or efficient, or robust, etc.).” Yes, that’s true, of course. But are there specific non-functional requirements that affect your project in particular, above and beyond what you do on every project? That’s what this checklist is for, and that’s what you should be thinking about when you write down nonfunctional requirements.

  • Availability: Are their constraints on the system’s availability or uptime?
  • Efficiency: Are there resources the system needs to be careful about monopolizing?
  • Flexibility: Will the system need to be altered after deployment?
  • Portability: How easy it is to move to another platform?
  • Integrity: How sensitive is the project to data security, access, and privacy?
  • Robustness: Do error conditions need to be handled gracefully?
  • Scalability: Will the system need to handle a wide range of configuration sizes?
  • Usability: Are there specific constraints on how the users will understand, learn and use the software?

If you’re interested in using this on a real project , you can read more about it in that O’Reilly Broadcast post about non-functional requirements: I post a relevant excerpt from Applied Software Project Management that goes into more detail about each of these.

Q: How do I write down a nonfunctional requirement? Is there a nonfunctional requirements template I can use?

Yes. We put together a software requirements specification template, and I’ve helped a lot of teams adopt it for their own projects over the years. When we put together our requirements templates, we put a lot of effort into streamlining them as much as possible. So this is a sort of “bare minimum” template for writing down use cases, functional requirements, and nonfunctional requirements.

Here’s an example of how we’d specify a functional requirement:

Name Nonfunctional requirement #7: Performance constraints for search-and-replace
Summary The search-and-replace feature must perform a search quickly.
Rationale If a search is not fast enough, users will avoid using the software.
Requirements A case-insensitive search-and-replace performed on a 3MB document with twenty 30-character search terms to be replaced with a different 30-character search term must take under 500ms on one of our standard testing VMs at 50% CPU load.
References See use case #8: Search

And that gets back to the blog post I mentioned earlier, Using nonfunctional requirements to build better software. If you’re working on a team that uses an agile process to build software, there’s a good chance that you already write down a lot of your requirements on index cards. In that post, I outline a method that I’ve had a lot of success with in my own projects.

I went into a lot more detail in that post, but here’s a quick recap. First, I write the requirement itself on the front of an index card:

Nonfunctional requirement index card (front)

and on the back I’ll write a specific test to make sure the requirement is implemented:

nf_index_card_back.jpg

Then I use it for planning the project to make sure it actually gets included — you can see more about it in the post. As far as documenting nonfunctional requirements goes, that’s actually a really efficient way of doing it, and I’ve seen it work well on agile projects.

I hope that answers some of your questions about using nonfunctional requirements in software projects. Obviously, I’d be thrilled if you took a look at the requirements chapter in Applied Software Project Management — Jenny and I gave a lot of practical advice about how to use requirements on a software project. And I’ve got other requirements posts on Building Better Software as well. But if they don’t answer your questions, feel free to ask (or send them to us).

When team members hate each other

We don’t always get to choose our teammates, especially at work. So what do you do when you just don’t get along with someone on your team?

What's your point?

Not too long ago, I was doing our Beautiful Teams talk at a brown bag lunch for a big financial company here in New York. At the end of the talk, I got a really good question:

What do you do when you’re on a team with people who don’t get along?

We don’t get to choose our teams, and while I’ve been on plenty of teams that gelled really well, I’ve definitely had to work with people who just rubbed me the wrong way or, worse, where the feeling was mutual. It’s a tough problem, but one that should be really familiar to anyone who’s been working with teams for a long time.

I have to admit that while I’ve had success working on teams with people who didn’t get along, there have definitely been a few times when I didn’t handle that situation as well as I could have. Luckily, those are the situations where we learn the most.

That’s actually one of the main reasons Jenny and I wanted to talk to Andy Lester when we were talking to contributors for Beautiful Teams. Andy runs a great website called The Working Geek, where he talks about working life for programmers, sysadmins and other geek types. And he had some really interesting things to say about how people interact with each other — especially geeky types (like me), since we seem to be especially prone to interpersonal problems. (Imagine that!)

I really liked this quote from Andy, because I think it cuts to the heart of the matter:

I was on a team once where I said, “At the very least, can we just have minimal respect for everyone here?” And I was asked quite seriously by someone else, “Well, what if not everybody on this team is worthy of respect?” And that’s baffling to me as a human, but it’s also not uncommon. And that minimal amount of respect is something that many just don’t get.

— Andy Lester, Beautiful Teams (chapter 5)

He’s right. When I look back over my own career, I find that many of my own conflicts with people on my team stemmed from a basic lack of respect. Since I was the top programmer on the team, I thought I knew better than everyone else about everything. Once someone got something wrong technically, I’d write that person off entirely because they didn’t have my respect.

Andy offers some really good personal advice for getting past those problems, both in his Beautiful Teams chapter and on his blog.

But I wanted to go a little further than that, because sometimes interpersonal problems aren’t going to be repaired. The person who asked me the question was in this situation: when I asked him about it, it sounded like some of his teammates were simply never going to get along with each other. So what do you do about that?

As it turns out, the answer I gave him comes from another part of Beautiful Teams. When Jenny and I were putting it together, we put a lot of thought into how to divide it into sections. And so many people talked explicitly about setting goals for projects that we ended up including an entire section called Goals.

So my answer to anyone who’s got insurmountable (at least, in the short run) conflicts between team members is to make sure that you’ve established what many of our contributors referred to as an “elevating goal.”

One of those contributors was Steve McConnell, who also happens to be one of my favorite authors. We asked another one of our favorite authors (and an old friend of mine), Scott Berkun, to interview him for the book, and out of that interview came this great quote:

If you’re out digging ditches, that’s not very elevating or inspiring. But if you’re digging ditches to protect your town that’s about to be attacked by an enemy, well, that’s more inspiring, even though it’s the same activity. And so the leader’s job, really, is to try to determine or frame the activity in such a way that people can understand what the value is.

— Steve McConnell, Beautiful Teams (chapter 16)

I think that really cuts to the heart of what it means to establish an elevating vision, and it should help show why that can help get past serious team problems. I have to admit that before working on this book, I hadn’t really given that much thought to establishing a vision. Yes, establishing a goal for a project is important, but I always thought about it in terms of the work that had to be done. I’d generally dismiss anything like an “elevating vision or goal” as a business-speak buzzword. A really valuable lesson for me was just how important it is to get everyone on the team on board with that one singular vision — and I mean actually understanding and embracing the vision for the project, and not just agreeing to some sort of lame mission statement.

What’s especially useful about getting everyone on the team to see the same vision is that you don’t need to be a manager or team lead to do it. All you need to do, minimally, is talk to people on your team. I’ve been brought onto projects where people on the team thought that there were serious architecture or requirements or quality problems. But once I started I talking to people, it turned out that everyone had a completely different idea of what they were building and why they were building it. I’ve found over and over again that just writing down what we’re building and who we’re building it for (using a Vision and Scope Document, for example) is enough to help the situation. It’s uncanny how often I’ve heard people say something like, “Wait, we’re building what? I thought we were doing something completely different!”

Anyone on the team can do that, and it’s a really valuable tool to help with serious teammate problems. The clearer everyone sees the real goal of the project, the easier it is to get past the disagreements and arguments and get on with the work. It’s something I’ve seen in real life many times, and it really does work: people are much more willing to settle disagreements and just get down to business if they can see that there’s a real end that they’re working towards.

When I look back at the times where I was able to successfully navigate serious team problems that were caused by people who didn’t like each other, I can see how this is exactly what I did. Even when people didn’t get along, I found that if I was able to get each person to see the bigger picture and work towards something he or she believed in, then most of the time they were able to put their problems on the back burner, at least long enough to get through, say, a meeting or a code review. And that was enough to save the project.