2.1 The Value of Simplicity
Simplicity may be
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
your energy on simplicity,
, and the interactions between simple
is a remarkably simple formula that forms the theory of
, one of the most revolutionary ideas ever.
Simple code does not
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
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
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
spaces. If you've ever
one of the great blues players, you know that those players have mastered one more skill—they learn what
to play. Bo Diddley embraces silence and simplicity with every fiber of his being. He
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
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
to the results of those tests
Here are some reasons to write simple code. They
in Figure 2-1:
Given simple tools, takes less time, and is less prone to error.
Easier to write.
Usually easier to test.
Usually more reliable in production.
Easier to refactor before deployment.
Easier to refactor to fix production problems.
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.
18.104.22.168 Technology you buy
Two values should
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
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
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
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
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
careful with frameworks for distributed communication, persistence, and
Will it cause you to compromise your core principles?
If you're striving for simplicity and independence, you should not consider
-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
just like VB and was comfortable. With the
of ASP.NET, guess which language is still supported? Hint: it isn't VBScript. Now there is a
of rewriting going on that need never have
"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
to your specific needs? When you look at it this way, everything is a "buy." Your own development shop is just one more vendor.
22.214.171.124 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,
, 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
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.
126.96.36.199 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
You may find that you're forced to use a particularly ugly foundation that looks only slightly better than a random string of
. Further, you may find that it's
to junk it and start from scratch with a simpler foundation. When this happens, you can do what moms and pet
do when they need to feed their charge a bitter pill: they hide it in
butter or cheese. I call this technique
. When you rebase, your overriding concern is the interface. Your goal is to give your
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.