Archive for the ‘Books’ Category

Review: Domain-Driven Design

Domain-Driven Design by Eric Evans

Domain-Driven Design by Eric Evans

I read Eric Evans’ Domain-Driven Design: Tackling Complexity in the Heart of Software nearly six months ago, but I wanted to take some time to mull over my response to it before posting a review.

Reading Domain-Driven Design can be a challenge. It’s taken me a while to sort through all the concepts in my head. It’s also taken me some time to chase down the references and articles related to the book. Eric Evans makes frequent references to design patterns and often cites other books in the software design canon. If you’re not familiar with these, you’ll find the book slow going. It’s definitely worth the effort, however, especially if you work with large codebases.

The key is large codebases. For simple software applications, a straightforward procedural approach to code works just fine. At larger scales, Object Oriented approaches to code work quite well. But neither procedural code nor OO principles give much guidance about large-scale software structures.

After your application grows beyond a dozen classes or so, you need to start thinking about the overall organization of your code. And once you start work on an application with different logical layers or physical tiers, or one that integrates with other software applications, you ought to give Domain-Driven Design a thorough read.

DDD defined

Software applications are tools that help people solve problems. The scope of the problem is called the problem domain, or simply the domain. The process of setting up your software to tackle the problem is called domain modeling. The domain model consists of the core concepts that help users of the software get the job done or the problem solved.

Domain-Driven Design recognizes that software applications have essential features needed to solve problems in the domain as well as supporting infrastructure. It places the core domain at the center of the design process and lets everything flow outward from that. It’s an approach sometimes called onion architecture, in contrast to the traditional “layer-cake” architecture diagrams you often see.

We write software to solve problems, so it makes sense that our software should model those problems as accurately as possible. It sounds so simple!

Sadly, in practice, it’s really hard to get right. Computers force us programmers to think about all sorts of things that have nothing at all to do with the problem we’re trying to solve:

  • Resource management
  • Data access and persistence
  • Responding to user input
  • Maintaining state
  • Etc. etc. etc.

These things can easily overshadow the problem we’re trying to solve. For many applications, the amount of infrastructure code you’ll write will far exceed the amount of domain logic required to solve the problem. And if you’re not careful, this infrastructure code can spread throughout your application, making it very hard to identify the core concerns of your system.

Eric Evans’ book describes how to see the forest for the trees in large-scale applications.

Three key DDD concepts

One of the things Eric Evans said after he wrote the book was that he wished he’d put it in a different order. I agree! Here are the three most important concepts discussed in the book, from back to front.

Bounded Contexts are a way to separate concerns within a software application. While the core of your application might deal with video editing or insurance claims processing, you will have other parts of your application that deal with corollary concerns.

If your system interacts with another software application or uses a web service, you obviously have a different context. These third-party components likely have different ways to model the domain, and you’ll need to translate these to your model.

But sometimes it’s not clear when you’ve moved from one problem domain to another. For example, within an employee timekeeping application you might have two subsystems that consider timesheets from a cost accounting perspective and a billing perspective. Though they might look at the same underlying data, the logic of how they work is different.

It’s important to explicitly recognize these boundaries. These edges will help determine the structure of your application.

Domain Modeling helps you determine the essential features of your system. Your code should be the literal embodiment of these features. If it’s a paint application, we’d expect to see concepts like Canvas and Brush and Color. If it’s a airline scheduling application, we’d expect concepts like Seat and Booking and Destination.

Software is an abstract thing. We humans have a difficult time thinking about abstract concepts. The more concrete you can make your core domain concerns, the easier it is for you to reason about.

Ubiquitous Language is the idea that your software development team should be using, as much as possible, the language of your customer. They need to understand the domain as completely as the client does — otherwise they’ll have a hard time designing software to solve the problem!

This is essentially another argument in favor of using real, concrete concepts from the problem domain in your application model. When the junior developer says, “I get exceptions when I assign this SpecialNeedsPassenger to an ExitRowSeat”, the airline executive will have some inkling what is going on. And when the customer says to the lead developer, “Oh no, we always show accumulated vacation within the current pay period” the developer will have some idea of what needs to change in the code.

Specific techniques

Much of the book is an exploration of how these three principles can be used to design (or refactor) a software application so that it makes more sense. Eric Evans discusses several diagramming techniques that can be used to illustrate relationships and boundaries in the domain model. He also highlights several design patterns that are helpful as well.

You can get good advice on applying specific techniques from reading blogs and looking at programming Q&A sites like StackOverflow. But it’s worthwhile to explore Eric Evans’ take on these and to get a solid grip on the terminology used by the DDD community.

If you’re a C# developer in particular, it’s easy to get confused by DDD terms like “Value Object” and “Entity” which are also used within the Microsoft .NET Framework. They have special meaning to folks in the DDD crowd.

Conclusion

This is the single most important book I’ve read on large-scale software construction. But it’s a challenging read because you need to know quite a bit about design patterns and have had some experience working on large scale projects.

The book also suffers a bit from the way it’s organized. As Eric Evans mentions in the introduction, the most important parts of the book are Parts I and IV. It’s easy to get bogged down in all the detail in the middle.

But those issues shouldn’t stop you from reading the book or becoming familiar with the concepts of Domain-Driven Design. It’s quickly become an essential part of the software design canon. We keep it on our Infovark bookshelf among the other key technical books..

Software architects and software team leads will get the most benefit from the book, but if you’re a developer on a large enterprise software project or commercial product, you’ll find the Domain-Driven approach to software construction very useful in your work.

If you want to learn more, check out the Domain-Driven Design article on Wikipedia and the Domain-Driven Design Community. You can also listen to this short interview about Domain-Driven Design with Eric Evans on InfoQ.

But the best way to get started is to read the book itself.

Review: Code

Sometimes it’s nice to go back to your roots. And sometimes, it’s nice to go back to the roots you never had.

As a computer science dropout, I’d never gotten the fundamentals presented to me in a coherent fashion. I’d picked up many of the connections between mathematics, logic, and electrical engineering from reading online, but it’s no substitute for having the progress of computer science laid out in a systematic way. Code: The Hidden Language of Computer Hardware and Software by Charles Petzold is the Computer Science 101 course I’d wish I’d had in college.

Code: The Hidden Language of Computer Hardware and Software

Code is a great trip through the fundamentals of computing. Starting from first principles the author takes you through the basic computer theory to the point where you could create your own computer. It’s a journey that begins with a simple light switch and ends with advent of the Internet.

Morse Code, combinatorial theory, the telegraph, logic circuits — are all parts of the story of the computer. It’s a story told without analogies, but in a straightforward building-block fashion. It describes the insights and intuitive leaps that lie behind the most important tool of our age.

At times, it can seem like computers and high-tech gadgets are magic. What reading a book like Code reminds us is that there’s no wizardry involved, just careful engineering.

A few things I learned

We were close to steampunk era computing. All the insights required to make simple calculators and computers were present in the late 19th century. Most of the equipment had been invented for the telegraph. But it took several decades more before the pieces came together, in a 1938 master’s thesis written by Claude Shannon while at MIT. (Shannon also coined the name used for the basic unit of digital information, the binary digit, or bit.)

The idea of separating code from data — something that every programmer gets beaten into them at the beginning — goes all the way back to the origin of computing. Even though it’s all binary numbers and logic gates at the hardware level, some of those numbers represent instructions and some represent data. Many of today’s higher-level languages are so far removed from the basic circuitry that you can (sometimes) treat them as one and the same.

It turns out the longstanding distinction between positive and negative numbers in most programming languages derives from electrical engineering. The circuitry needed to subtract two numbers can be greatly simplified if you accept a few constraints on the size of the number and apply some tricks for how they’re encoded. I’d assumed that the reason had to do with storage space alone, but it simplifies the electrical circuitry required as well.

I had no idea that assembly language was essentially machine language with human annotations and symbols. I thought that they were fundamentally different, somehow.

And speaking of assembly language, I now have an vague idea of what the disassembly code Visual Studio shows me during debugging means. By the time you’re finished with Code, you’ll have a basic understanding of it as well, and for how tedious it was to program. I’m glad to be working with today’s much more expressive programming languages.

Parting thoughts

Code was a great read, and ought to sit on every professional programmer’s bookshelf. Part Wired, part Make, part junior high science class, it’ll teach you the inner workings of the complicated and ubiquitous devices that run everything these days.

My only criticism of the book was that it wrapped up too quickly. The graphical user interface gets only a chapter, and events since the rise of the Internet barely half of one. I’d like to see another volume (or two!) covering in depth everything that’s happened since the Apple Macintosh.

But that’s really more of a compliment than a criticism.

Review: Framework Design Guidelines

Framework Design Guidelines

I’m almost embarrassed to admit that I really enjoyed Framework Design Guidelines by Krzysztof Cwalina and Brad Abrams. I mean, it’s a book about coding standards.

Maybe I ought to get out more… but before I leave the glare of my monitor behind, I’ll type up my review.

Code is literature, not language

Computing languages, just like human languages, have grammar and syntax. There are correct ways to form sentences and paragraphs, with well-defined rules (and exceptions). Just like word processors can check spelling and verify basic sentence structure, most IDEs today can ensure your code will compile and run.

That doesn’t mean that your story or program is an easy or enjoyable read, though. Most newspapers have accumulated extensive guidelines for matters of style and substance, and most software companies have their own guides as well. If you’re writing as part of a team project, or writing programs intended to be used by other programmers, it’s important to make your code consistent, clear, and direct.

Just like many journalists keep a copy of The Associated Press Stylebook or the New York Times Manual of Style and Usage handy — even if they don’t actually work for the New York Times or the AP — lots of programmers keep a copy of Microsoft’s Framework Design Guidelines as reference.

Or they should. That’s probably my roots as a maintenance programmer showing.

Know your genre

Ideally, you’d want any code you write for other Windows programmers’ use to look as if it came from Microsoft itself. That is, you want it to feel like a natural extension of the .NET framework and not some third-party bolt-on with odd stylistic touches. You’d also like your code to use the full power and expressiveness of .NET, and not appear like some watered-down Java-esque port. (Far too many open source projects retain awkward Java-isms after being converted to .NET, in my opinion. NUnit is a notable exception.)

This helps your fellow programmers gain a better understanding of your code in less time. And it can also make your programming tasks easier, too. Just like design patterns can help you lay out your application architecture, programming guidelines can help you structure your code at the class or method level.

About the book

The Framework Design Guidelines covers a lot of ground in its 400 pages. It describes what conventions Microsoft uses when designing types, methods, and exceptions. It also describes the naming and design patterns that Microsoft uses in their public APIs. The topics are grouped by category and heavily cross referenced, making it easy to find your way around. The rationale of each guideline is explained, and the authors indicate the strength of each recommendation by marking it with the terms Do, Consider, Avoid or Do Not.

But the best part of the book is the stories and comments given by members of the Microsoft team. These are sprinkled throughout the book and give insight into why the guideline exists. Some of these discuss lessons Microsoft learned the hard way, places in the .NET Framework where the rules are violated, and how real-world programmers feel about certain guidelines. You can get a flavor of these by checking out the Framework Design Guidelines section of Brad Abrams‘ blog.

If you find his posts interesting or helpful, you’ll feel the same way about the book. Highly recommended.

Review: Working Effectively with Legacy Code

Working Effectively with Legacy Code

I know what you’re thinking: “Infovark’s been around for barely a year! Surely you guys aren’t having to deal with legacy code already?” If you accept Michael Feather’s expansive definition of legacy code — code without unit tests — then yes, despite our best efforts, we have lots of legacy code.

But even if you don’t buy that definition, and even if you’re working on a completely greenfield application, chances are you’ll have a lot of code in your project that isn’t fully understood. Or perhaps isn’t fully understood by all members of the team. And it’s in dealing with this issue that Working Effectively with Legacy Code really shines.

What happens when you need to change code that isn’t fully understood? Are you making it better or worse? The author says that you can’t know the answer to this question without tests in place. Having documentation is nice, but unit testing provides measurable output.

The brass tacks

Unlike many programming books, this one is organized in a Q&A format. Once past the introduction — which you can skip if you already understand the importance of refactoring and test-driven development — you’ll find the chapters organized by topic. Here’s a sample of a few chapter headings:

  • It Takes Forever to Make a Change
  • I Can’t Run This Method in a Test Harness
  • Dependencies on Libraries are Killing Me
  • I Don’t Understand the Code Well Enough to Change It
  • This Class is Too Big and I Don’t Want It to Get Any Bigger

This is a great way to organize a highly technical book. Each chapter has a specific purpose. The author then spends the chapter discussing the ways you can get out of the jam and weighing the pros and cons of each.

You’ll find in-depth examples of each of the techniques used, but be prepared to shift between languages. To get the most out of the book, you’ll need to be comfortable scanning unfamiliar syntax.

As a bonus, the book contains an index of common refactoring patterns. Certain patterns make appearances in more than one chapter, and the index provides another place for the author to work through some real-world examples.

All in all, this is a practical field manual for a set of problems that occur too often out in the wild. I highly recommend it.

Review: The Pragmatic Programmer

The Pragmatic Programmer: From Journeyman to Master

You’ll find The Pragmatic Programmer: From Journeyman to Master on many software developers’ must-read books lists. After reading it from cover to cover, I’ve added it to my essential reading list as well.

It’s not a book for beginners, though. The subtitle of the book, “From Journeyman to Master” sums it up. The Pragmatic Programmer describes the skills, attributes, and attitudes that a mid-level programmer needs to become a professional developer.

Its purpose is to distill the wisdom gathered from a career in programming into about 70 tips. Each of these tips is explained and illustrated with examples that most programmers will find familiar.

The tips are not necessarily about writing code. The authors, Andrew Hunt and David Thomas, take a holistic approach to the craft of programming. They cover topics like communicating effectively, planning and scheduling, and building teams.

I’d read somewhere that you can judge the quality of a craftsman by the quality of his tools. The Pragmatic Programmer is a book I’d expect to see on any professional developer’s shelf.

Review: Restful Web Services

As we mentioned recently, we’re building the infovark server using the REST pattern. Since REST is more a loose set of guidelines than a strict series of rules, it’s hard for implementers to know where to begin.

OK, you could go to the source, chapter 5 of Roy Fielding’s dissertation. Or you could check out the somewhat academic discussions on the REST wiki, though there hasn’t been much activity lately. You can occasionally find good advice from the odd blog post, like the REST for the Rest of Us article at Open Garden. But ironically, there’s not a whole lot of material about implementing REST web services available on the web yet. (If you know of good links, leave a comment.)

RESTful Web Services

For the practical, gritty details of how it’s actually done, you’ll need the Restful Web Services book by Sam Ruby and Leonard Richardson. They describe the principles that inform REST-ian (RESTafarian?) design in detail, taking you step-by-step through two different sample applications. If you’re a Ruby programmer using Rails, you’ll find the book especially valuable, since that’s the language and framework in which most of the examples are done. For those of us using different technology, it’s the thought process behind the examples that is most illuminating.

This is because the key challenge of the REST paradigm is the fact that it can’t really be implemented on today’s web without some workarounds. REST will come into its own with HTML 5. The book steers an interesting course between how REST web services might be done in HTML 5 with how they must be done today. I think the authors get the balance right, but at times it can make for a frustrating read for someone wanting practical advice about building a REST service right now.

But that’s less a criticism of the book than of the openness of the REST concept itself. The occasional what-if digression the authors make is a small price to pay for the amount of sound guidance you get. The appendixes alone, which discuss things like which HTTP status codes and headers are worth implementing and which are worth forgetting, will save you far more time than you’ll lose in reading how great things will be when HTML forms finally support the PUT method.

Until that day comes, keep this book handy.