DekGenius.com
Previous Section  < Day Day Up >  Next Section

2.1 The Value of Simplicity

Simplicity may be the core value. You can write simple code faster, test it more thoroughly with less effort, and depend on it once it's done. If you make mistakes, you can throw it away without reservation. When requirements change, you can refactor with impunity. If you've never thought about simplicity in software development before, let's first talk about what simplicity is not:

  • Simple does not mean simple-minded. You'll still think just as hard, but you'll spend your energy on simplicity, elegance, and the interactions between simple components. e=mc2 is a remarkably simple formula that forms the theory of relativity, one of the most revolutionary ideas ever.

  • Simple code does not necessarily indicate simple behavior. Recursion, multithreading, and composition can let you build applications out of simple building blocks with amazingly complex behavior.

  • Writing simple code does not mean taking the easy way out. Cutting and pasting is often the fastest way to write a new method, but it's not always the simplest solution, and rarely the best solution. Simple code is clean, with little replication.

  • A simple process is not an undisciplined process. Extreme programming is a process that embraces simplicity, and it's quite rigorous in many ways. You must code all of your test cases before writing your code; you must integrate every day; and you must make hard decisions on project scope in order to keep to your schedule.

Simple code is clean and beautiful. Learn to seek simplicity, and you'll step over the line from engineer to artist. Consider the evolution of a typical guitar player. Beginners aspire to play just about anything that they can master. Intermediate players learn to cram more notes and complex rhythms into ever-decreasing spaces. If you've ever heard one of the great blues players, you know that those players have mastered one more skill—they learn what not to play. Bo Diddley embraces silence and simplicity with every fiber of his being. He strips his music to the bare essence of what's required. Then, when he does add the extra, unexpected notes, they have much more power and soul.

Coding simply accrues benefits throughout the development process. Take a look at the typical object-oriented development iteration in Figure 2-1. Here, I'm trying to show the typical steps of an object-oriented cycle. Notice that you can see the tangible impact of simplicity in every phase of each iteration. I should also point out that you can have a dramatic impact outside of the typical development iterations, and into the production part of an application's lifecycle, because your code will be easier to fix and maintain.

Figure 2-1. Each iteration in an object-oriented project has steps for designing, coding, testing, and reacting to the results of those tests
figs/bflJ_0201.gif


Here are some reasons to write simple code. They correspond to the numbers in Figure 2-1:

  1. Given simple tools, takes less time, and is less prone to error.

  2. Easier to write.

  3. Usually easier to test.

  4. Usually more reliable in production.

  5. Easier to refactor before deployment.

  6. Easier to refactor to fix production problems.

  7. Easier to maintain.

You're probably wishing I would get right to the point and talk about new design patterns that help create simpler code. Here's the bad news: you can't address simplicity that way. You've got to pay attention to the process you're using to build code, the foundation you're building on, and the basic building blocks you're using in your everyday programming life before you can truly embrace simplicity.

2.1.1 Choosing the Foundations

If you want to build simple applications, you're going to have to build on simple frameworks. You need processes, tools, frameworks, and patterns that support the concepts in this book. Face it: if you build on top of an unintelligible, amorphous blob, you're probably going to be writing code that looks like sticky, tangled masses of goo. That goes for foundations you code, technologies you buy, and design patterns you reuse.

2.1.1.1 Technology you buy

Two values should govern every layer that you add to your system: value and simplicity. When it comes to value, remember that there are no free rides. Each layer must pay its own way. When I say pay, I'm generally not talking about the software sales price. Over your development cycle, most of your costs—like time and effort to develop, deploy, and maintain your code—will dwarf the sales price of any given component. You'll want to answer some pointed questions for each and every new piece of software:


How does it improve your life?

Many a project has used XML for every message, configuration file, or even document. If two elements of a system are necessarily tightly coupled, XML only adds cost and complexity. Often, pure text with hash tables works fine. Likewise, even if the two elements are loosely coupled but the data is simple enough (key/value pairs, or a simple rectangular table), then XML is probably still overkill.


What is the cost?

If a technology marginally improves your life, you should be willing to pay only a marginal cost. Too often, developers compromise on major values for minimal gain. Adopting EJB CMP for a project because it comes free with an application server often seems wise, until the true, invasive complexity of the beast shows itself.


Is it easy to integrate and extend?

Many technologies work well within their own domain, but make assumptions that make even basic extensions difficult. Be especially careful with frameworks for distributed communication, persistence, and user interfaces.


Will it cause you to compromise your core principles?

If you're striving for simplicity and independence, you should not consider ultra-invasive technologies. If you need portability at any cost, then you shouldn't use a tool that forces you to adopt nonstandard SQL.


Can you maintain it and manage it in production?

Client-server technologies often broke down because they were too expensive to deploy. Web developers live with the limitations of the user interface because the deployment advantages on the client are so significant.


Is it a fad technology that will leave you hanging when it falls from fashion?

Look across the pond at developers moving from Micrsoft's ASP to ASP.NET. While ASP was the platform, VBScript was the language of choice for many developers. Sure, it was nonstandard (the standard is JavaScript, or Ecmascript, depending on who you ask), but it looked just like VB and was comfortable. With the advent of ASP.NET, guess which language is still supported? Hint: it isn't VBScript. Now there is a lot of rewriting going on that need never have happened.

"Buy over build" is a great motto, but you've got to watch what you buy. It's really just a cost comparison. How much would it cost you and your team to develop the equivalent functionality with the equivalent stability but more targeted to your specific needs? When you look at it this way, everything is a "buy." Your own development shop is just one more vendor.

2.1.1.2 Design patterns

Treat design patterns like a framework that you purchase. Each one has a cost and a benefit. Like a purchases framework, each design pattern must pay its own way. If you want to embrace simplicity, you can't build in each and every design pattern from the famous Gang of Four book, Design Patterns, by Erich Gamma, Richard Helm, et al. (Addison-Wesley).

True, many design patterns allow for contingencies. That's good. Many Java gurus get in trouble when they try to predict what the future might hold. That's bad. The best rule of thumb is to use design patterns when you've physically established a need, today. You need expertise on your team that can recognize when a given situation is crying out for a particular pattern. Too often, developers buy the Gang of Four book, or one like it, crack it open to a random page, and apply a pattern that has no problem. Instead, it's better to find a difficult problem, and then apply the right pattern in response. You need experts on a team to apply any technology. Design patterns are no exception. In other words, don't impose design patterns. Let them emerge.

2.1.1.3 Your own code

Of course, much of your foundation will be code that you or your peers write. It goes without saying that the simplicity of each layer affects the simplicity of the layers above.

You may find that you're forced to use a particularly ugly foundation that looks only slightly better than a random string of characters. Further, you may find that it's impossible to junk it and start from scratch with a simpler foundation. When this happens, you can do what moms and pet owners do when they need to feed their charge a bitter pill: they hide it in peanut butter or cheese. I call this technique rebasing. When you rebase, your overriding concern is the interface. Your goal is to give your clients a better interface and usage model than the code below you. An example of rebasing is providing a data access object layer, which hides the details of a data store, over the EJB entities. You can then keep that skeleton deep in the closet, or clean it out at your leisure. Your clients will be protected, and be able to provide a much cleaner interface.

    Previous Section  < Day Day Up >  Next Section