Better Faster Lighter Java [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Better Faster Lighter Java [Electronic resources] - نسخه متنی

Justin Gehtland; Bruce A. Tate

نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
افزودن یادداشت
افزودن یادداشت جدید








2.2 Process and Simplicity


Kent Beck, the father


of XP, says "Pick the
simplest thing that will work." Building the
simplest house or making the simplest of car repairs is difficult
without the right tools and process. Building great software is no
different. If you want to build simple software,
you've got to strip all the extraneous junk out of
your process that clutters your mind, your motivations, and your
code. As you've seen in Chapter 1, I don't think that most
development shops are moving in the right direction. The same forces
that bloat frameworks, languages, and tools can also convolute the
everyday development process:

Overkill


Heavy-duty processes used in the mainstream are designed for the most
difficult problems. For the most part, UML diagrams such as sequence
diagrams, class diagrams, and the like provide more harm than value.
To me, UML belongs in books, on white boards, and possibly in the
classroom, but rarely in design documents.


Complexity


When you do need to add tools like UML, keep it simple. A box with
the class name and the two most important methods is often more
useful than a multisymbol mish-mash with every UML bell and whistle
embedded.


Indirection


It's hard to keep those phone book-sized
requirements documents in sync with the code. It's
even harder to keep that 350-class set of UML diagrams up to date.
I've got another, more effective rule for
synchronizing documents: code always wins. Code is the primary
artifact that you'll deliver.


Rigidity


Those that sell methodology also often sell dogma. It
doesn't matter whether you're going
with a high-end process like Rational Unified Process (RUP) or a
lower-intervention process like XP.


Over-specialization


Too many complex development frameworks segregate team members into
roles that are too specialized, and code becomes isolated from
documents, programmers from testers, and code from the warning,
healing light of day.



Effective development processes do none of these things. The best
development processes add just enough rigor to get the job done. They
let you work primarily on the artifacts that you will deliver
directly to your customer, and minimize the work spent on other
documents that live to support the process.

But few methods work out of the box. To make a development method
effective, tailor it to your needs. Teams vary in size, skill,
preference, and prejudice. If you don't like class
diagrams or object interaction diagrams, don't use
them. If pair programming feels like overkill, don't
do it. If you can't deal with an on-site customer,
use some other way to introduce an effective surrogate. If a
particular diagram is not clear or useful, don't
create it. As James Duncan Davidson, the author of Tomcat and Ant,
once told me, "If it feels good, do it. If it
doesn't, quit."


2.2.1 The Best of Agile


Programming methods

like XP and SCRUM advocate
simplicity, and make it easier to achieve. Many of the authors of
these methods are part of the Agile Alliance, which defines Agile
software development principles. These ideas are rapidly shaping the
way modern teams build software. The methods run contrary to many of
the other methods that you may use. These rules in particular cut
against the grain:

Code rules


While other methods like RUP require you to build many different
types of diagrams as artifacts, Agile methods encourage you to focus
on working code as the primary artifact. Everything else is
secondary.


Embrace change


Other methods try to limit change; Agile methods encourage it.
Developers refactor whenever they think it's
necessary or helpful. Safety measures like continuous integration and
automated tests protect the code base. Customers understand that as
new features are added, others are removed.



Agile methods make it much easier to develop simple code. They can
help you to minimize your development process to the bare essentials
that you'll need to get the job done. Even if you
don't fully embrace all Agile ideas, you can make
tremendous gains by embracing some of the Agile principles:

Strive for simplicity


This is a cornerstone of all Agile methods, and among the most
important.


Get and make use of feedback as early as possible


The rest of the principles are based on this one: shortening the
feedback loop and applying what you learn as soon as possible is
vital to being agile.


Automate testing


Some of the methods are stronger, requiring test cases before code.
While such a principle may seem cumbersome and time-consuming, most
developers find that in the long run, testing actually saves you time
by catching problems early, while they are still easy to solve.


Integrate continuously


Paradoxically, integrating more frequently actually takes less time.
When you do, you catch errors quickly and find potential stumbling
blocks before they get out of control.


Refactor


To be agile, you must respond to change. That means you need to
refactor early and often. It also means you need to build in the
safety precautions that protect you from potential damage caused by
refactoring.



These principles stand alone, and work well with just about any
development process. When you use them together, you multiply their
benefit. All of the principles build upon simplicity, a core value,
but simplicity is difficult to maintain through successive iterations
without refactoring. Automated unit tests and continuous integration
build in a safety net to protect the code base from errors injected
through refactoring. JUnit is rapidly becoming one of the most
critical Java tools in my toolbox and the toolboxes of the best
developers that I know.

Other ideas can help you to tailor your process, too. You can remove
some requirement documents such as rigid functional specifications
and heavy-duty use cases, and replace them with better customer
contact and simple stories. You can work from source code, and
relegate heavy-duty diagrams to the whiteboard. Seek regular informal
communication, whenever and wherever you need it. Eschew all wasteful
meetings. Abhor complexity, in any form. These ideas are independent
of any methodology. They represent a philosophy, from the inside out,
based on simplicity.


2.2.2 Pick Your Battles


A couple of years ago, I had a mental breakthrough: I was coding
scared. I was afraid of trying simple solutions because I feared that
they would not be rich enough. I didn't want to ever
discard code; often, I'd invested too much of myself
in it. I was afraid to change anything because I might break
something else. I wasn't always that way. As the
frameworks that I used and the algorithms that I used became more
complex, I became more fearful. Fearful programming is an easy habit
to make, and also an easy one to break. All you've
got to do is embrace the simple solution instead of cracking open
that jar of scorpions that you've been dreading. If
you feel trapped, you'll code scared. The secret is
leaving yourself an escape hatch.

The bottom line is this: you can't embrace
simplicity without also embracing refactoring. Don't
be afraid of serious changes, or even throwing away code.
You'll likely find that you fear the wrong things.
Because you've saved time with simple solutions
along the way, you'll have more time to deal with
your toughest problems when you need it most.

Think of your programming as the simple decision chart in Figure 2-2. Your goal is to keep as much code as simple
as possible for as long as possible. The left-hand side of the chart
represents simplicity. The right side is your escape hatch. You can
use the escape hatch to inject as much complexity as you require.
You'll find that you won't need
your escape hatch nearly as much as you thought.



Figure 2-2. Your goal is to keep as many decisions as possible to the left of the diagram

The chart says to try something simple. How simple? Use your
judgment. You don't want to waste time with
solutions that you know will break; neither do
you want to guess which things will break, or
are likely to break. It's an important distinction
that most programmers do not observe, especially as they become more
experienced.

The bottom line is this: when you guess wrong, and you guess simple,
it's cheap. When you guess wrong, and you guess
complex, it's very expensive. You can apply this
type of thinking in many places.


2.2.2.1 Algorithms


When you hear about

simplicity, it's usually
in the context of algorithms. I'm not saying that
you should always reach for that bubble sort, but I am saying that
you should leave all of the tiny, ugly optimizations out until you
measure the need for change. Take the example of object allocation.
Which code is easier to read, this one:

String middle = "very, ";
String prefix "This code is ";
String suffix = "ugly."
String result = ";
StringBuffer buffer = new StringBuffer( );
buffer.append(prefix);
for (int i= 0; i<5; i++) {
buffer.append(middle);
}
buffer.append(suffix);
result = buffer.toString( );

or this one:

String result = "This code is ";
for (int i= 0; i<5; i++) {
result = result + "much, ";
}
result = result + "simpler, and neater.";

If you've ever read an earlier Java book with
performance tips, you were probably warned that the first example is
better code. In fact, some applications had real problems with object
allocation. As a result, you can still see huge blobs of code like
the first one all over the place.

But remember what I said about developer intuition? It stinks, and
things change. Now, compilers can heavily optimize object allocation.
But let's give it the benefit of the doubt, and say
that you are working on an older compiler. And let's
further assume that the loop is a little longer. Would you really
notice the difference? Unless you were doing nothing but processing
huge numbers of strings, you would never see the difference. And
you'd be forced to maintain a bigger blob of uglier
code until the end of time. Trade a little less performance for
better readability every time. Your correct guesses will save you
more than enough time to refactor the wrong ones.


2.2.2.2 Architecture


Most of the applications that


you build with Java are distributed, and
it's easy to distribute more broadly than you need.
Distribution can add flexibility, scalability, and availability.
Distribution also forces some decisions and architectures that make
your code much more difficult to write and understand. When in doubt,
guess simple. I'm not suggesting that you hardwire
your application so that distribution is impossible.
I'm merely making the point that distance will cost
you. Keep in mind that the vendors that build generic J2EE
architectures sell either hardware, software, or both. The network
may be the computer, but it's an expensive,
unreliable computer. Use it when you must, but lean on it only when
it's necessary.


2.2.2.3 Performance


Most of the developers

that I know try to optimize as they go.
The best of them are wrong more than half of the time. You probably
can't predict exactly which piece of code will cause
bottlenecks in your system. Don't try. When you do,
you introduce (probably useless) complexity into your application,
reducing your ability to maintain and adapt your code over time.
Instead, code simple solutions and save your time for measuring and
repairing the bottlenecks as they occur. Let your tools, like a good
profiler, do the heavy lifting.


2.2.2.4 Design patterns


There's an inside joke among many Java consultants.
You can often tell which books inexperienced developers are reading
by reading their code. Sometimes, it's the
reader's fault. When you read about a technique,
you're anxious to try it out. But
don't just start coloring on the walls. Use a
coloring book firstlike a sample application.

Sometimes, the problem lies with authors, who often oversell ideas or
solutions. Other times, the problem lies with frameworks. If you want
to know what I mean, pick up a book that deals with EJB design
patterns. Now, count the number of design patterns that do nothing
more than work around EJB features that stink. Or look to the seminal
Gang of Four patterns; they are workarounds for problems with C++.

For this reason alone, many influential consultants abhor design
patterns. I'm not in that camp. But let the need for
a design pattern emerge before you work it into an application. In
other words, wait until you have a problem before you look for a
solution.


/ 111