📄 tij320.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html lang="en">
<!--
This document was converted from RTF source:
By r2net 5.8 r2netcmd Windows
See http://www.logictran.com
-->
<head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Thinking in Java, 3rd ed. Revision 4.0: B: Java Programming Guidelines</title>
<link rel="stylesheet" href="stylesheet.css" type="text/css"></head>
<body >
<CENTER> <a href="http://www.MindView.net"> <img src="mindview.gif" alt="MindView Inc." BORDER = "0"></a> <Font FACE="Verdana, Tahoma, Arial, Helvetica, Sans"> <h2>Thinking in Java, 3<sup>rd</sup> ed. Revision 4.0</h2> <FONT size = "-1"><br> [ <a href="README.txt">Viewing Hints</a> ] [ <a href="http://www.mindview.net/Books/TIJ/">Book Home Page</a> ] [ <a href="http://www.mindview.net/Etc/MailingList.html">Free Newsletter</a> ] <br> [ <a href="http://www.mindview.net/Seminars">Seminars</a> ] [ <a href="http://www.mindview.net/CDs">Seminars on CD ROM</a> ] [ <a href="http://www.mindview.net/Services">Consulting</a> ] <br><br> </FONT></FONT> </CENTER>
<font face="Georgia"><div align="CENTER"><a href="TIJ319.htm" target="RightFrame"><img src="./prev.gif" alt="Previous " border="0"></a>
<a href="TIJ321.htm" target="RightFrame"><img src="./next.gif" alt="Next " border="0"></a>
<a href="TIJ3_t.htm"><img src="./first.gif" alt="Title Page " border="0"></a>
<a href="TIJ3_i.htm"><img src="./index.gif" alt="Index " border="0"></a>
<a href="TIJ3_c.htm"><img src="./contents.gif" alt="Contents " border="0"></a>
</div>
<hr>
<h1>
<a name="_Toc375545509"></a><a name="_Toc24272657"></a><a name="_Toc24776012"></a><a name="Heading25755"></a>B:
Java Programming Guidelines</h1>
<p class="Intro">This appendix contains suggestions to help guide you in performing low-level program design and in writing code.<br></p>
<p><a name="Index2208"></a><a name="Index2209"></a><a name="Index2210"></a><a name="Index2211"></a>Naturally, these are guidelines and not rules. The idea is to use them as inspirations and to remember that there are occasional situations where they should be bent or broken. <font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2834" title="Send BackTalk Comment">Feedback</a></font><br></p>
<h2>
<a name="_Toc24776013"></a><a name="Heading25758"></a>Design</h2>
<ol>
<li><b>Elegance always pays off</b>. In the short term it might seem like it
takes much longer to come up with a truly graceful solution to a problem, but
when it works the first time and easily adapts to new situations instead of
requiring hours, days, or months of struggle, you’ll see the rewards (even
if no one can measure them). Not only does it give you a program that’s
easier to build and debug, but it’s also easier to understand and
maintain, and that’s where the financial value lies. This point can take
some experience to understand, because it can appear that you’re not being
productive while you’re making a piece of code elegant. Resist the urge to
hurry; it will only slow you down. <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2835" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>First make it work, then make it fast</b>. This is true even if you are
certain that a piece of code is really important and that it will be a principal
bottleneck in your system. Don’t do it. Get the system going first with as
simple a design as possible. Then if it isn’t going fast enough, profile
it. You’ll almost always discover that “your” bottleneck
isn’t the problem. Save your time for the really important stuff. <font
size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2836"
title="Send BackTalk Comment">Feedback</a></font></li>
<li><b>Remember the “divide and conquer” principle</b>. If the
problem you’re looking at is too confusing, try to imagine what the basic
operation of the program would be, given the existence of a magic
“piece” that handles the hard parts. That “piece” is an
object—write the code that uses the object, then look at the object and
encapsulate <i>its</i> hard parts into other objects, etc. <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2837" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>Separate the class creator from the class user (<i>client
programmer</i>)</b>. The class user is the “customer” and
doesn’t need or want to know what’s going on behind the scenes of
the class. The class creator must be the expert in class design and write the
class so that it can be used by the most novice programmer possible, yet still
work robustly in the application. Think of the class as a <i>service provider
</i>for other classes. Library use will be easy only if it’s transparent.
<font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2838"
title="Send BackTalk Comment">Feedback</a></font></li>
<li><b>When you create a class, attempt to make your names so clear that
comments are unnecessary</b>. Your goal should be to make the client
programmer’s interface conceptually simple. To this end, use method
overloading when appropriate to create an intuitive, easy-to-use interface.
<font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2839"
title="Send BackTalk Comment">Feedback</a></font></li>
<li><b>Your analysis and design must produce, at minimum, the classes in your
system, their public interfaces, and their relationships to other classes,
especially base classes</b>. If your design methodology produces more than that,
ask yourself if all the pieces produced by that methodology have value over the
lifetime of the program. If they do not, maintaining them will cost you. Members
of development teams tend not to maintain anything that does not contribute to
their productivity; this is a fact of life that many design methods don’t
account for. <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2840" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>Automate everything</b>.<b> </b>Write the test code first (before you
write the class), and keep it with the class. Automate the running of your tests
through a build tool—you’ll probably want to use Ant, the defacto
standard Java build tool. This way, any changes can be automatically verified by
running the test code, and you’ll immediately discover errors. Because you
know that you have the safety net of your test framework, you will be bolder
about making sweeping changes when you discover the need. Remember that the
greatest improvements in languages come from the built-in testing provided by
type checking, exception handling, etc., but those features take you only so
far. You must go the rest of the way in creating a robust system by filling in
the tests that verify features that are specific to your class or program. <font
size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2841"
title="Send BackTalk Comment">Feedback</a></font></li>
<li><b>Write the test code first (before you write the class) in order to verify
that your class design is complete</b>. If you can’t write test code, you
don’t know what your class looks like. In addition, the act of writing the
test code will often flush out additional features or constraints that you need
in the class—these features or constraints don’t always appear
during analysis and design. Tests also provide example code showing how your
class can be used. <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2842" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>All software design problems can be simplified by introducing an extra
level of conceptual indirection</b><i>.</i> This fundamental rule of software
engineering<sup><a name="fnB122" href="#fn122">[122]</a></sup><a name="Index2212"></a>
is the basis of abstraction, the primary feature of object-oriented programming.
In OOP, we could also say this as: “If your code is too complicated, make
more objects.” <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2843" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>An indirection should have a meaning </b>(in concert with guideline 9).
This meaning can be something as simple as “putting commonly used code in
a single method.” If you add levels of indirection (abstraction,
encapsulation, etc.) that don’t have meaning, it can be as bad as not
having adequate indirection. <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2844" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>Make classes as atomic as possible</b>. Give each class a single, clear
purpose—a cohesive service that it provides to other classes. If your
classes or your system design grows too complicated, break complex classes into
simpler ones. The most obvious indicator of this is sheer size; if a class is
big, chances are it’s doing too much and should be broken up.<br>Clues to
suggest redesign of a class are:<br>1) A complicated switch statement: consider
using polymorphism. <br>2) A large number of methods that cover broadly
different types of operations: consider using several classes.<br>3) A large
number of member variables that concern broadly different characteristics:
consider using several classes. <br>4) Other suggestions can be found in
<i>Refactoring: Improving the Design of Existing Code</i> by Martin Fowler
(Addison-Wesley 1999). <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2845" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>Watch for long argument lists</b>. Method calls then become difficult to
write, read, and maintain. Instead, try to move the method to a class where it
is (more) appropriate, and/or pass objects in as arguments. <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2846" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>Don’t repeat yourself</b>. If a piece of code is recurring in many
methods in derived classes, put that code into a single method in the base class
and call it from the derived-class methods. Not only do you save code space, but
you provide for easy propagation of changes. Sometimes the discovery of this
common code will add valuable functionality to your interface. A simpler version
of this guideline also occurs without inheritance: If a class has methods that
repeat code, factor that code into a common method and call it from the other
methods. <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2847" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>Watch for <i>switch</i> statements or chained <i>if-else</i> clauses</b>.
This is typically an indicator of <i>type-check coding</i>, which means that you
are choosing what code to execute based on some kind of type information (the
exact type may not be obvious at first). You can usually replace this kind of
code with inheritance and polymorphism; a polymorphic method call will perform
the type checking for you and allow for more reliable and easier extensibility.
<font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2848"
title="Send BackTalk Comment">Feedback</a></font></li>
<li><b>From a design standpoint, look for and separate things that change from
things that stay the same</b>. That is, search for the elements in a system that
you might want to change without forcing a redesign, then encapsulate those
elements in classes. You can learn much more about this concept in <i>Thinking
in Patterns (with Java)</i> at <i>www.BruceEckel.com</i>. <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2849" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>Don’t extend fundamental functionality by subclassing</b>. If an
interface element is essential to a class it should be in the base class, not
added during derivation. If you’re adding methods by inheriting, perhaps
you should rethink the design. <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2850" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>Less is more</b>. Start with a minimal interface to a class, as small and
simple as you need to solve the problem at hand, but don’t try to
anticipate all the ways that your class <i>might</i> be used. As the class is
used, you’ll discover ways you must expand the interface. However, once a
class is in use, you cannot shrink the interface without breaking client code.
If you need to add more methods, that’s fine; it won’t break code.
But even if new methods replace the functionality of old ones, leave the
existing interface alone (you can combine the functionality in the underlying
implementation if you want). If you need to expand the interface of an existing
method by adding more arguments, create an overloaded method with the new
arguments; this way, you won’t disturb any calls to the existing method.
<font size="-2"><a href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2851"
title="Send BackTalk Comment">Feedback</a></font></li>
<li><b>Read your classes aloud to make sure they’re logical</b>. Refer to
the relationship between a base class and derived class as “is-a”
and member objects as “has-a.” <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2852" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>When deciding between inheritance and composition, ask if you need to
upcast to the base type</b>. If not, prefer composition (member objects) to
inheritance. This can eliminate the perceived need for multiple base types. If
you inherit, users will think they are supposed to upcast. <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2853" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>Use fields for variation in value, and method overriding for variation in
behavior</b>. That is, if you find a class that uses state variables along with
methods that switch behavior based on those variables, you should probably
redesign it to express the differences in behavior within subclasses and
overridden methods. <font size="-2"><a
href="mailto:TIJ3@MindView.net?Subject=[TIJ3]AppendC_2854" title="Send BackTalk
Comment">Feedback</a></font></li>
<li><b>Watch for overloading</b>. A method should not conditionally execute code
based on the value of an argument. In this case, you should create two or more
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -