﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-freesky</title><link>http://www.blogjava.net/freesky/</link><description>自由天空</description><language>zh-cn</language><lastBuildDate>Wed, 15 Apr 2026 13:44:31 GMT</lastBuildDate><pubDate>Wed, 15 Apr 2026 13:44:31 GMT</pubDate><ttl>60</ttl><item><title>Debugging make</title><link>http://www.blogjava.net/freesky/archive/2008/07/27/217881.html</link><dc:creator>freesky</dc:creator><author>freesky</author><pubDate>Sun, 27 Jul 2008 13:26:00 GMT</pubDate><guid>http://www.blogjava.net/freesky/archive/2008/07/27/217881.html</guid><wfw:comment>http://www.blogjava.net/freesky/comments/217881.html</wfw:comment><comments>http://www.blogjava.net/freesky/archive/2008/07/27/217881.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freesky/comments/commentRss/217881.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freesky/services/trackbacks/217881.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Make utilities such as GNU make, System V make, and Berkeley make, are fundamental tools for streamlining the application build process, but each one is just a little different from the others. Learn the structure of the makefile and how to avoid common mistakes in its creation, discover how to fix or work around portability issues, and pick up hints for solving other problems as they crop up.</p>
<!--start RESERVED FOR FUTURE USE INCLUDE FILES--><script language="javascript" type="text/javascript">
	     capture_referrer();
</script><!-- START : HTML FOR SEARCH REFERRER --><!-- START KRUGLE SEARCH HEADING PLAY
					<table width="580" cellspacing="0" cellpadding="0" border="0">
                    <tr>
                      <td class="v14-header-5">
                     <strong>Show more developerWorks content related to my search</strong>
                      </td>
                    </tr>
                  </table> --><!-- START : HTML FOR ARTICLE SEARCH --><!-- END : HTML FOR ARTICLE SEARCH --><!-- START : HTML FOR CODE SEARCH --><!-- END : HTML FOR CODE SEARCH --><br />
<br />
<!-- END : HTML FOR SEARCH REFERRER --><!--end RESERVED FOR FUTURE USE INCLUDE FILES-->
<p>Most UNIX&#174; and Linux&#174; programs are built by running <code>make</code>. The make utility reads a file (generally named either "makefile" or "Makefile," but hereafter merely referred to as "a makefile") that contains instructions and performs various actions to build a program. In many build processes, the makefile is itself generated entirely by other software; for instance, the <code>autoconf/automake</code> programs are used to develop build routines. Other programs may ask you to directly edit a makefile, and of course, new development may require you to write one.</p>
<p>The phrase "the make utility" is misleading. There are at least three distinct variants in common use: GNU make, System V make, and Berkeley make. Each grew from a core specification from the early UNIX days, and each adds new features. This results in a difficult situation: fairly commonly used features, such as including other files in a makefile by reference, cannot be done portably! The decision to simply write a program to create makefiles is one solution. Because GNU make is free and widely distributed, some developers simply code for it; similarly, a few projects with BSD origins require you to use Berkeley make (which is also free).</p>
<p>Less common but still relevant are J&#246;rg Schilling's <code>smake</code>, and the absentee fifth member of the family, historical make, which defines the common feature subset that all the others share. While smake is not the default make on any system, it's a good make implementation, and some programs (especially Schilling's) use it by preference.</p>
<p>Let's review some of the most common problems you'll encounter when working with makefiles.</p>
<p><a name="N10063"><span class="atitle">Understanding the makefile</span></a></p>
<p>To debug make, you have to be able to read a makefile. As you know, the purpose of a makefile is to give instructions for building a program. One of make's key features is <em>dependency management</em>: make attempts to rebuild only what it has to when a program is updated. In general, this is expressed through a series of dependency rules. A dependency rule looks like this:</p>
<br />
<a name="N10073"><strong>Listing 1. Form of dependency rule</strong></a><br />
<table cellspacing="0" cellpadding="0" width="60%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">target: dependencies
            instructions
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>The main problem people encounter when writing their first makefile is visible in this construction; or rather, invisible. The indentation is a tab. It is not any number of spaces. The Berkeley make error message for a file using spaces in this format is not terribly helpful:</p>
<br />
<a name="N10080"><strong>Listing 2. Berkeley make error message</strong></a><br />
<table cellspacing="0" cellpadding="0" width="60%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">make: "Makefile" line 2: Need an operator
            make: Fatal errors encountered -- cannot continue
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>GNU make, while still unable to process the file, gives a more helpful suggestion:</p>
<br />
<a name="N1008D"><strong>Listing 3. GNU make error message</strong></a><br />
<table cellspacing="0" cellpadding="0" width="60%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">Makefile::2: *** missing separator (did you mean TAB instead of 8 spaces?).  Stop.
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>Note that both the dependencies and the instructions are optional; only the target and the colon are required. So, that's the syntax. What are the semantics? The semantics are that, if make wishes to build <code>target</code>, it will first look at dependencies. In fact, it will recursively attempt to build them; if the dependencies in turn have dependencies, those will be dealt with before this rule continues. If <code>target</code> exists and is at least as new as all of the items listed in <code>dependencies</code>, nothing is done. If <code>target</code> does not exist, or one or more dependencies is newer, then make executes <code>instructions</code>. Dependencies are processed in the order that they are specified. If no dependencies are specified, the instructions are followed anyway. Dependencies are also called <em>sources</em>.</p>
<p>If a target is given on the command line (for example, <code>make foo</code>), then make will attempt to build that target. Otherwise, it will try to build the first target listed in the file. One convention some developers use is to have the first target look like this:</p>
<br />
<a name="N100B8"><strong>Listing 4. Commonly used first target convention</strong></a><br />
<table cellspacing="0" cellpadding="0" width="60%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">default: all
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>Some people assume that make uses this rule because it's named "default." Not so; it's used because it's the first rule in the file. You could name it anything you wanted, but the name "default" is a good choice because it communicates to the reader. Remember that your makefile is going to be read by humans, not just make programs.</p>
<p><a name="N100C1"><span class="smalltitle">Phony targets</span></a></p>
<p>In general, it is asserted that a target's function is to create a file from other files. In fact, this is not always the case. Most makefiles have at least a couple of rules that never create a target. Consider the following example rule:</p>
<br />
<a name="N100CE"><strong>Listing 5. Example phony target</strong></a><br />
<table cellspacing="0" cellpadding="0" width="60%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">all: hello goodbye fibonacci
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>This rule instructs make -- if it wishes to build the target <code>all</code> -- to first make sure that hello, goodbye, and fibonacci are up to date. Then...nothing. No instructions are provided. After this rule is complete, no file named "all" is created. The target is a fake. The technical term used in some varieties of make is "phony."</p>
<p>Phony targets are used for organizational purposes and are a wonderful thing in writing a clear and legible makefile. For instance, one often sees rules like this:</p>
<br />
<a name="N100E2"><strong>Listing 6. Intelligently used phony target</strong></a><br />
<table cellspacing="0" cellpadding="0" width="60%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">build: clean all install
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>This specifies an order of operations for the build process.</p>
<p><a name="N100EB"><span class="smalltitle">Special targets and sources</span></a></p>
<p>A few special targets are defined that have special effects on make, providing a configuration mechanism. The exact set varies from one implementation to another; the most common is the <code>.SUFFIXES</code> target, the "sources" for which are a series of patterns to be added to the list of recognized file suffixes. Special targets don't count for purposes of the usual rule that make builds the first target in the makefile by default.</p>
<p>Some versions of make allow special sources to be specified along with the dependencies for a given target, such as <code>.IGNORE</code>, which indicates that errors from commands used to build this target should be ignored, as though a dash preceded them. These flags are not especially portable but may be necessary to understand in debugging a makefile.</p>
<p><a name="N100FF"><span class="smalltitle">Generic rules</span></a></p>
<p>There are implicit rules in make for performing generic transforms based on filename suffixes. For instance, with no makefile present, create a file called "hello.c" and run <code>make hello</code>:</p>
<br />
<a name="N10110"><strong>Listing 7. Example of implicit rule for C files</strong></a><br />
<table cellspacing="0" cellpadding="0" width="60%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">$ <span class="boldcode">make hello</span>
            cc -O2   -o hello hello.c
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>makefiles for larger programs may simply specify a list of object modules they need (hello.o, world.o, and so on), then provide a rule for converting .c files to .o files:</p>
<br />
<a name="N10120"><strong>Listing 8. Rule for converting .c to .o files</strong></a><br />
<table cellspacing="0" cellpadding="0" width="60%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">.c.o:
            cc $(CFLAGS) -c $&lt;
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>In fact, most make utilities have a rule very much like this built in already; if you ask make to build <em>file</em>.o, and it has <em>file</em>.c, it'll do the right thing. The term "$&lt;" is a special predefined make variable that refers to the "source" for a rule. That brings us to make variables.</p>
<p>Generic rules depend on the declaration of "suffixes," which make then recognizes as filename extensions rather than part of a name.</p>
<p><a name="N10132"><span class="smalltitle">Variables</span></a></p>
<p>The make program uses variables to make it easier to reuse common values. The most set value is probably <code>CFLAGS</code>. A few things should be clarified about make variables. They are not necessarily environment variables. If no make variable with a given name exists, make will check for environment variables; however, that doesn't mean that make variables are exported to the environment. The precedence rules are arcane; in general, the order from highest to lowest precedence is this:</p>
<ol>
    <li>Command-line variable settings
    <li>Variables set in a parent make process's makefile
    <li>Variables set in this make process's makefile
    <li>Environment variables </li>
</ol>
<p>Thus, environment variables are used only if a variable is not set in any makefile or on the command line. (Note: parent makefile variables are sometimes, but not always, passed down. The rules, as you may have guessed, vary from one flavor of make to another.)</p>
<p>A common problem people run into with make is variables inexplicably being replaced by parts of their names: for instance, <code>$CFLAGS</code> being replaced by "FLAGS". To refer to a make variable, put its name in parentheses: <code>$(CFLAGS)</code>. Otherwise, you get <code>$C</code> followed by <code>FLAGS</code>.</p>
<p>A number of variables have special meanings that are a function of the rule they're being used in. The most commonly used are:</p>
<ul>
    <li><code>$&lt;</code> - The source from which the target is to be made
    <li><code>$*</code> - The base name of the target (no extensions or directory)
    <li><code>$@</code> - The full name of the target </li>
</ul>
<p>Berkeley make deprecates these variables, but they are (for now) still portable. Sort of portable, anyway; the exact definitions may vary between make implementations. Anything complicated you write with these will likely end up specific to a given implementation.</p>
<p><a name="N1017F"><span class="smalltitle">Shell scripting</span></a></p>
<p>It's occasionally desirable to perform some sort of task beyond the scope of what can be done portably in make. The conventional solution, since make runs everything through the shell, is to write an inline shell script. Here's how.</p>
<p>First, be aware that while shell scripts are traditionally written on multiple lines, they can be compressed to a single line with semicolons to separate statements. Second, be aware that this is illegible. The solution is a compromise: write the script with the usual indentation, but with each line ending with "; \". This ends each shell command syntactically (with a semicolon) but makes the text part of a single make command that will be passed to the shell all at once. For instance, the following might show up in a top-level makefile:</p>
<br />
<a name="N1018F"><strong>Listing 9. Breaking lines in a shell script</strong></a><br />
<table cellspacing="0" cellpadding="0" width="60%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">all:
            for i in $(ALLDIRS) ; \
            do      ( cd $$i ; $(MAKE) all ) ; \
            done
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>This illustrates the three things to keep in mind. First, the use of semicolons and backslashes. Second, the use of <code>$(VARIABLE)</code> for make variables. Third, the use of <code>$$</code> to pass a dollar sign to the shell. That's it! It really is that easy.</p>
<p><a name="N101A0"><span class="smalltitle">Prefixes</span></a></p>
<p>By default, make prints every command it runs, and aborts if any command fails. In some cases, it's possible that a command will appear to fail, but you will want the build to continue. If the first character of a command is a hyphen (-), the remainder of the line is executed, but its exit status is ignored.</p>
<p>If you don't want to echo a command, prefix it with an at-sign (@). This is most commonly used for displaying messages:</p>
<br />
<a name="N101B0"><strong>Listing 10. Suppressing echo</strong></a><br />
<table cellspacing="0" cellpadding="0" width="60%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">all:
            @echo "Beginning build at:"
            @date
            @echo "--------"
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>Without the @ signs, this would produce the output:</p>
<br />
<a name="N101BD"><strong>Listing 11. Commands without @</strong></a><br />
<table cellspacing="0" cellpadding="0" width="60%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">echo "Beginning build at:"
            Beginning build at:
            date
            Sun Jun 18 01:13:21 CDT 2006
            echo "--------"
            --------
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>While the @ sign doesn't really change what make does, it's a very popular feature.</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /></td>
        </tr>
    </tbody>
</table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tbody>
        <tr align="right">
            <td>
            <table cellspacing="0" cellpadding="0" border="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                        </td>
                        <td valign="top" align="right"><a class="fbox" href="http://www-128.ibm.com/developerworks/library/l-debugmake.html#main" cmimpressionsent="1"><strong>Back to top</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="N101C6"><span class="atitle">Things you can't do portably</span></a></p>
<p>Some things that everyone wants to do cannot be portably done. But there are some workarounds to be had.</p>
<p><a name="N101CF"><span class="smalltitle">Include files</span></a></p>
<p>One of the most frustrating historical compatibility problems is handling inclusion in makefiles. Historical make implementations didn't always provide a way to do this, although all modern varieties appear to. The GNU make syntax is simply <code>include <em>file</em></code>. The traditional Berkeley syntax is <code>.include "file"</code>. At least one Berkeley make now supports the GNU notation as well, but not all do. The portable solution, discovered by both <code>autoconf</code> and <code>Imake</code>, is just to include every variable assignment you think you might want.</p>
<p>Some programs simply require the use of GNU make. Some require Berkeley make. Still others, smake. If you need include files badly enough, it's not unthinkable to simply specify a make utility that your tree will be built with. (Of the three portable ones distributed in source, my favorite is Berkeley make.)</p>
<p><a name="N101ED"><span class="smalltitle">Getting variables to nested builds</span></a></p>
<p>There is no really good way to do this. If you use an include file, you run into the portability problem of including the file cleanly. If you set the variables in every file, it becomes very hard to overwrite them all. If you set them only in a top-level file, independent builds in subdirectories will fail because the variables aren't set!</p>
<p>Depending on your version of make, one reasonably good solution is to conditionally set variables in every file only if they are not already set; then a change in the top-level file will affect subdirectories in a full build. Of course, then going into a subdirectory and running make there will get different and incompatible results...</p>
<p>This is amplified by the lack of include files, as anyone who has ever struggled with Imake's multi-thousand-line makefiles can attest.</p>
<p>Some writers advocate a simpler solution: don't use recursive make at all. For most projects, this is entirely feasible and can dramatically simplify (and speed up!) compilation. The article by Peter Miller, "Recursive Make Considered Harmful" (see <a href="http://www-128.ibm.com/developerworks/library/l-debugmake.html#resources" cmimpressionsent="1">Resources</a>) is probably the canonical source.</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /></td>
        </tr>
    </tbody>
</table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tbody>
        <tr align="right">
            <td>
            <table cellspacing="0" cellpadding="0" border="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                        </td>
                        <td valign="top" align="right"><a class="fbox" href="http://www-128.ibm.com/developerworks/library/l-debugmake.html#main" cmimpressionsent="1"><strong>Back to top</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="N10203"><span class="atitle">What to do when there's a problem</span></a></p>
<p>First, don't panic. Developers have been having weird problems with make since before a complete version was written. Implicit rules, unexpected variable substitutions, and syntax errors from embedded shell scripts are just where the fun begins.</p>
<p>Read the error message. Is it actually from make, or is it from something make is calling? If you have a nested build, you might need to thread up through a bunch of error messages to find the actual error.</p>
<p>If a program isn't being found, first check to see whether it's installed. If it is, check paths; some developers have the habit of specifying the absolute path to a program in makefiles, which may fail on other systems. If you installed something in /opt, and the makefile refers to /usr/local/bin, the build will fail. Fix the path.</p>
<p>Check your clock; more importantly, look at the dates of files in your build tree, and other files on your system, and your clock. The behavior of make when confronted with chronologically inconsistent input data can range from harmless to surreal. If you had clock problems (some "new" files datestamped in 1970, for instance), you will need to fix those. The "touch" utility is your friend. The error messages you will get from clock skew will not generally be obvious.</p>
<p>If the error messages you're getting imply that you have syntax errors, or tons of variables unset or set incorrectly, try a different version of make; for instance, some programs will get cryptic errors from gmake but build fine with smake. Really weird errors may indicate that you're running a Berkeley makefile with GNU make, or vice versa. Programs native to Linux often assume GNU make and fail in inexplicable ways with anything else, even if there's no hint of this in the documentation.</p>
<p>Debugging flags can be pretty useful. For GNU make, the <code>-d</code> flag will give you a HUGE amount of information, some of it useful. For Berkeley make, the <code>-d</code> flag takes a set of flags; <code>-d A</code> is the complete set, or you can use subsets; for instance, <code>-d vx</code> will give debugging information about variable assignments (<code>v</code>) and cause all commands to be run through <code>sh -x</code> so the shell will echo the exact command it received. The <code>-n</code> debugging flag causes make to print a list of things it thinks it needs to do; it's not always correct, but it often gives you an idea of what's wrong.</p>
<p>Your goal in debugging a makefile is to figure out what make is trying to build, and what commands it thinks will build it. If make is picking the right commands, and they're failing, you may be done debugging make -- or you may not. For instance, if the attempt to compile a program fails due to unresolved symbols, it's possible that an earlier phase of the build process did something wrong! If you are unable to figure out what's wrong with a command, and it looks like it should work, it's quite possible that one of the files already created by make was created incorrectly.</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /></td>
        </tr>
    </tbody>
</table>
<table class="no-print" cellspacing="0" cellpadding="0" align="right">
    <tbody>
        <tr align="right">
            <td>
            <table cellspacing="0" cellpadding="0" border="0">
                <tbody>
                    <tr>
                        <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br />
                        </td>
                        <td valign="top" align="right"><a class="fbox" href="http://www-128.ibm.com/developerworks/library/l-debugmake.html#main" cmimpressionsent="1"><strong>Back to top</strong></a></td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="N1023A"><span class="atitle">Documentation</span></a></p>
<p>As is often the case, the primary documentation for GNU make is not available in man format, unfortunately; you have to use the info system instead, and you can't just run <code>man make</code> and look for information about it. However, the documentation is reasonably complete.</p>
<p>It is fairly hard to get good documentation on the "safe subset" of features that all implementations support. The Berkeley and GNU make documentation both tend to mention when they're describing an extension, but it's good to test things before relying too heavily on guesses about the exact boundaries.</p>
<p>Over time, drift between the BSDs has resulted in subtle differences between their implementations of make. Of the three, NetBSD is the one for which make is most actively supported on other systems; the NetBSD pkgsrc system is in use on other platforms, and relies heavily on NetBSD's implementation of make.</p>
<br />
<br />
<p><a name="resources"><span class="atitle">Resources</span></a></p>
<strong>Learn</strong><br />
<ul>
    <li>"<a href="http://www.canb.auug.org.au/~millerp/rmch/recu-make-cons-harm.html" cmimpressionsent="1">Recursive Make Considered Harmful</a>" examines problems associated with using recursive make, boils the problems down to first principles, and offers a straightforward solution. <br />
    <br />
    <li>Peter's earlier article, "<a href="http://www.ibm.com/developerworks/linux/library/l-debcon.html" cmimpressionsent="1">Debugging configure</a>" (developerWorks, December 2003), offers help to those who have stumbled over a broken configuration script and gives advice to developers on how to keep failures to a minimum. <br />
    <br />
    <li>In the <a href="http://www.ibm.com/developerworks/linux/" cmimpressionsent="1">developerWorks Linux zone</a>, find more resources for Linux developers. <br />
    <br />
    <li>Stay current with <a href="http://www.ibm.com/developerworks/offers/techbriefings/?S_TACT=105AGX03&amp;S_CMP=art" cmimpressionsent="1">developerWorks technical events and Webcasts</a>. </li>
</ul>
<br />
<strong>Get products and technologies</strong><br />
<ul>
    <li><a href="http://www.ibm.com/developerworks/offers/sek/?S_TACT=105AGX03&amp;S_CMP=art" cmimpressionsent="1">Order the SEK for Linux</a>, a two-DVD set containing the latest IBM trial software for Linux from DB2&#174;, Lotus&#174;, Rational&#174;, Tivoli&#174;, and WebSphere&#174;. <br />
    <br />
    <li>With <a href="http://www.ibm.com/developerworks/downloads/?S_TACT=105AGX03&amp;S_CMP=art" cmimpressionsent="1">IBM trial software</a>, available for download directly from developerWorks, build your next development project on Linux. <br />
    <br />
    </li>
</ul>
<br />
<strong>Discuss</strong><br />
<ul>
    <li>Check out <a href="http://www.ibm.com/developerworks/blogs/" cmimpressionsent="1">developerWorks blogs</a> and get involved in the <a href="http://www.ibm.com/developerworks/community" cmimpressionsent="1">developerWorks community</a>. <br />
    </li>
</ul>
<p>转自:http://www-128.ibm.com/developerworks/library/l-debugmake.html<br />
</p>
<img src ="http://www.blogjava.net/freesky/aggbug/217881.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freesky/" target="_blank">freesky</a> 2008-07-27 21:26 <a href="http://www.blogjava.net/freesky/archive/2008/07/27/217881.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MakeFile学习（转）</title><link>http://www.blogjava.net/freesky/archive/2008/07/27/217878.html</link><dc:creator>freesky</dc:creator><author>freesky</author><pubDate>Sun, 27 Jul 2008 13:19:00 GMT</pubDate><guid>http://www.blogjava.net/freesky/archive/2008/07/27/217878.html</guid><wfw:comment>http://www.blogjava.net/freesky/comments/217878.html</wfw:comment><comments>http://www.blogjava.net/freesky/archive/2008/07/27/217878.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freesky/comments/commentRss/217878.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freesky/services/trackbacks/217878.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 跟我一起写 Makefile&nbsp;陈皓 概述 什么是makefile？或许很多Winodws的程序员都不知道这个东西，因为那些Windows的IDE都为你做了这个工作，但我觉得要作一个好的和professional的程序员，makefile还是要懂。这就好像现在有这么多的HTML的编辑器，但如果你想成为一个专业人士，你还是要了解HTML的标识的含义。特别在Unix下的...&nbsp;&nbsp;<a href='http://www.blogjava.net/freesky/archive/2008/07/27/217878.html'>阅读全文</a><img src ="http://www.blogjava.net/freesky/aggbug/217878.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freesky/" target="_blank">freesky</a> 2008-07-27 21:19 <a href="http://www.blogjava.net/freesky/archive/2008/07/27/217878.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java模式设计之模板方法模式 </title><link>http://www.blogjava.net/freesky/archive/2007/05/14/117275.html</link><dc:creator>freesky</dc:creator><author>freesky</author><pubDate>Mon, 14 May 2007 02:40:00 GMT</pubDate><guid>http://www.blogjava.net/freesky/archive/2007/05/14/117275.html</guid><wfw:comment>http://www.blogjava.net/freesky/comments/117275.html</wfw:comment><comments>http://www.blogjava.net/freesky/archive/2007/05/14/117275.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freesky/comments/commentRss/117275.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freesky/services/trackbacks/117275.html</trackback:ping><description><![CDATA[<table width="100%">
    <tbody>
        <tr>
            <td>这是一个很简单的模式，却被非常广泛的使用。之所以简单是因为在这个模式中仅仅使用到了继承关系。<br><br>继承关系由于自身的缺陷，被专家们扣上了&#8220;罪恶&#8221;的帽子。&#8220;使用委派关系代替继承关系&#8221;，&#8220;尽量使用接口实现而不是抽象类继承&#8221;等等专家警告，让我们这些菜鸟对继承&#8220;另眼相看&#8221;。<br><br>其实，继承还是有很多自身的优点所在。只是被大家滥用的似乎缺点更加明显了。合理的利用继承关系，还是能对你的系统设计起到很好的作用的。而模板方法模式就是其中的一个使用范例。<br><br><strong>二、定义与结构</strong><br><br>GOF给模板方法（Template Method）模式定义一个操作中的算法的骨架，而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。这里的算 法的结构，可以理解为你根据需求设计出来的业务流程。特定的步骤就是指那些可能在内容上存在变数的环节。<br><br>可以看出来，模板方法模式也是为了巧妙解决变化对系统带来的影响而设计的。使用模板方法使系统扩展性增强，最小化了变化对系统的影响。这一点，在下面的举例中可以很明显的看出来。<br><br>来看下这个简单模式的结构吧：<br><br>1) AbstractClass（抽象类）：定义了一到多个的抽象方法，以供具体的子类来实现它们；而且还要实现一个模板方法，来定义一个算法的骨架。该模板方法不仅调用前面的抽象方法，也可以调用其他的操作，只要能完成自身的使命。<br><br>2) ConcreteClass（具体类）：实现父类中的抽象方法以完成算法中与特定子类相关的步骤。<br><br>下面是模板方法模式的结构图。直接把《设计模式》上的图拿过来用下：<br><br>
            <table width="90%" align=center border=0>
                <tbody>
                    <tr>
                        <td>
                        <div align=center><img alt="" src="http://dev.yesky.com/imagelist/05/08/6n18udc5gbnm.jpg"></div>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br><strong>三、举例</strong><br><br>还是在我刚刚分析完源码的JUnit中找个例子吧。JUnit中的TestCase以及它的子类就是一个模板方法模式的例子。在TestCase这个抽 象类中将整个测试的流程设置好了，比如先执行Setup方法初始化测试前提，在运行测试方法，然后再TearDown来取消测试设置。但是你将在 Setup、TearDown里面作些什么呢？鬼才知道呢！！因此，而这些步骤的具体实现都延迟到子类中去，也就是你实现的测试类中。<br><br>来看下相关的源代码吧。<br><br>这是TestCase中，执行测试的模板方法。你可以看到，里面正像前面定义中所说的那样，它制定了&#8220;算法&#8221;的框架——先执行setUp方法来做下初始化，然后执行测试方法，最后执行tearDown释放你得到的资源。<br><br>
            <table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
                <tbody>
                    <tr>
                        <td>public void runBare() throws Throwable {<br>setUp();<br><br>try {<br>runTest();<br>}<br><br>finally {<br>tearDown();<br>}<br>}</td>
                    </tr>
                </tbody>
            </table>
            <br>这就是上面使用的两个方法。与定义中不同的是，这两个方法并没有被实现为抽象方法，而是两个空的无为方法（被称为钩子方法）。这是因为在测试中，我们并 不是必须要让测试程序使用这两个方法来初始化和释放资源的。如果是抽象方法，则子类们必须给它一个实现，不管用到用不到。这显然是不合理的。使用钩子方 法，则你在需要的时候，可以在子类中重写这些方法。<br><br>
            <table borderColor=#cccccc width="90%" align=center bgColor=#e3e3e3 border=1>
                <tbody>
                    <tr>
                        <td>protected void setUp() throws Exception {}<br>protected void tearDown() throws Exception {}</td>
                    </tr>
                </tbody>
            </table>
            <br>四、适用情况<br><br>根据上面对定义的分析，以及例子的说明，可以看出模板方法适用于以下情况：<br><br>1) 一次性实现一个算法的不变的部分，并将可变的行为留给子类来实现。<br><br>2) 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。其实这可以说是一种好的编码习惯了。<br><br>3) 控制子类扩展。模板方法只在特定点调用操作，这样就只允许在这些点进行扩展。比如上面runBare（）方法就只在runTest前面适用setUp方 法。如果你不愿子类来修改你的模板方法定义的框架，你可以采用两种方式来做：一是在API中不体现出你的模板方法；二、将你的模板方法置为final就可 以了。<br><br>可以看出，使用模板方法模式可以将代码的公共行为提取出来，达到复用的目的。而且，在模板方法模式中，是由父类的模板方法来控制子类中的具体实现。这样你在实现子类的时候，根本不需要对业务流程有太多的了解。</td>
        </tr>
    </tbody>
</table>
<p><br>&nbsp;</p>
<p>转载：<a href="http://fly-net-cn.javaeye.com/blog/78611">http://fly-net-cn.javaeye.com/blog/78611</a></p>
<img src ="http://www.blogjava.net/freesky/aggbug/117275.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freesky/" target="_blank">freesky</a> 2007-05-14 10:40 <a href="http://www.blogjava.net/freesky/archive/2007/05/14/117275.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java设计模式之策略模式</title><link>http://www.blogjava.net/freesky/archive/2007/05/14/117266.html</link><dc:creator>freesky</dc:creator><author>freesky</author><pubDate>Mon, 14 May 2007 02:28:00 GMT</pubDate><guid>http://www.blogjava.net/freesky/archive/2007/05/14/117266.html</guid><wfw:comment>http://www.blogjava.net/freesky/comments/117266.html</wfw:comment><comments>http://www.blogjava.net/freesky/archive/2007/05/14/117266.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freesky/comments/commentRss/117266.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freesky/services/trackbacks/117266.html</trackback:ping><description><![CDATA[<p>策略模式（Strategy Pattern）中体现了两个非常基本的面向对象设计的基本原则：封装变化的概念；编程中使用接口，而不是对接口实现。策略模式的定义如下： </p>
<p>定义一组算法，将每个算法都封装起来，并且使它们之间可以互换。策略模式使这些算法在客户端调用它们的时候能够互不影响地变化。 </p>
<p>策略模式使开发人员能够开发出由许多可替换的部分组成的软件，并且各个部分之间是弱连接的关系。弱连接的特性使软件具有更强的可扩展性，易于维护；更重要的是，它大大提高了软件的可重用性。 </p>
<p>为了说明策略模式，我们将首先讨论一下在Swing中是如何利用策略模式来绘制组件边界的，然后讨论在Swing中使用策略模式带来的好处，最后讨论如何在软件中实现策略模式。 </p>
<center><font color=#000099><strong>Swing边框</strong></font></center>
<p>对所有的Swing组件，例如按钮、列表单等，都还可以绘制边框。在Swing中提供了各种 边框类型，例如bevel、etched、line、titled等。Swing组件的边框是通过JComponent类来绘制的，该类是所有Swing 组件的基类，实现了所有Swing组件公共的功能。在JComponent中有一个paintBorder()方法，该方法为组件绘制边框。Swing的 开发人员可以象下面的例子中所示那样来绘制边框： </p>
<p><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code>// 一段实现paintBorder（）方法代码<br>protected void paintBorder(Graphics g) {<br>   switch(getBorderType()) {<br>      case LINE_BORDER:   paintLineBorder(g);<br>                          break;<br>      case ETCHED_BORDER: paintEtchedBorder(g);<br>                          break;<br>      case TITLED_BORDER: paintTitledBorder(g);<br>                          break;<br>      ...<br>   }<br>}</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>请注意上面的代码只是一种假设，事实上Swing的开发人员并没有这样实现 paintBorder（）方法。在上面的代码中，在JComponent中绘制边框的代码被直接写入了paintBorder（）方法中，这意味着 JComponent和绘制边框的功能被紧密地结合在了一起。很自然地大家会联想到如果需要实现一种新的边框类型，开发人员必须修改至少三处代码：首先增 加一个常量，该常量代表新添加的边框的类型值；其次需要在Switch语句中增加一个case语句；最后开发人员需要实现paintXXXBorder （）方法，其中XXX代表新边框的名称。 </p>
<p>很显然要扩展上面paintBorder()方法的功能是一件很困难的事情，不仅 仅是因为开发人员需要增加一种新的边框类型，更麻烦的是开发人员很难修改JComponent类。JComponent类已经被编译到了Swing的开发 工具中，如果开发人员想修改它的话，必须获得Swing的源代码，修改后重新编译Swing。同时在用户的计算机上与需要使用新编译的Swing API。另外所有的Swing组件都可以使用开发人员新添加的边框类型。有可能开发人员只希望新的边框被某些组件使用，但是现在开发人员无法对使用该边框 的组件进行限制。 </p>
<p>开发人员有更好的实现方法吗？答案就是策略模式。通过策略模式，可以将 JComponent和实现绘制边框的代码分离开来，这样开发人员在增加或修改绘制边框的代码使就不需要修改JComponent的代码。通过应用策略模 式，开发人员将变化的概念（在这个例子中是绘制边框）封装起来，然后通过一个Border接口，使程序能够重用绘制边框的功能。下面让我们来看 JComponent是如何利用策略模式来实现绘制边框的功能的： </p>
<p><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code>// Swing中paintBorder()方法的源代码<br>protected void paintBorder(Graphics g) {<br>   Border border = getBorder();<br>   if (border != null) {<br>      border.paintBorder(this, g, 0, 0, getWidth(), getHeight());<br>   }<br>}</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>上面的paintBorder()方法通过一个border对象绘制了组件的边框。 这样border对象替代了前一个例子中的JComponent封装了边框绘制的功能。我们还应该注意到JComponent将一个对自己的引用传递给了 Border.paintBorder（）方法，这是因为Border的实例必须知道它对应的组件的信息，这种方式通常被称为委托。通过这种方式，一个对 象可以将功能委托给另一个对象来实现。 </p>
<p>在JComponent类中引用了一个Border对象，通过JComponent.getBorder（）方法可以获得该Border对象。下面的代码演示了如何设定和获得Border对象： </p>
<p><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code>...<br>private Border border;<br>...<br>public void setBorder(Border border) {<br>   Border oldBorder = this.border;<br>   this.border = border;<br>   firePropertyChange("border", oldBorder, border);<br>   if (border != oldBorder) {<br>      if (border == null || oldBorder == null || !(border.getBorderInsets(this).<br>                                    equals(oldBorder.getBorderInsets(this)))) {<br>         revalidate();<br>      }       <br>      repaint();<br>   }<br>}<br>...<br>public Border getBorder() {<br>   return border;<br>}</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>当开发人员通过JComponent.setBorder（）方法设定了一个组件的 边框后，JComponent类发出一个属性更新事件。如果新的边框和以前的边框不同的话，setBorder（）方法就重新绘制边框。 getBorder（）方法仅仅返回对Border对象的引用。图1显示了Border的类结构图： </p>
<center><img alt="" src="http://industry.ccidnet.com/col/attachment/2003/2/99506.jpg"></center>
<center>图1 Border的类结构图</center>
<p>通过类结构图我们可以看到，JComponent类中保存了一个对Border对象的引用。由于Border是一个接口，Swing组件可以使用任何一个实现了Border接口的类。 </p>
<p>现在我们已经知道了JComponent是如何利用策略模式来绘制组件的边框的。下面让我们通过实现一个新的边框类型来测试一下它的可扩展性。 </p>
<center><font color=#000099><strong>实现一个新的边框类型</strong></font></center>
<p>图2中是一个有三个JPanel对象的小程序，每个JPanel对象有各自不同的边框，每个边框对应一个HandleBorder实例。 </p>
<center><img alt="" src="http://industry.ccidnet.com/col/attachment/2003/2/99507.jpg"></center>
<center>图2 新的边框类型</center>
<p><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code>// HandleBorder.java<br>import java.awt.*;<br>import javax.swing.*;<br>import javax.swing.border.*;<br>public class HandleBorder extends AbstractBorder {<br>   protected Color lineColor;<br>   protected int thick;<br>   public HandleBorder() {<br>      this(Color.black, 6);<br>   }<br>   public HandleBorder(Color lineColor, int thick) {<br>      this.lineColor = lineColor;<br>      this.thick = thick;<br>   }<br>   public void paintBorder(Component component, <br>                                  Graphics g, int x, int y, int w, int h) {<br>      Graphics copy = g.create();<br>      if(copy != null) {<br>         try {<br>            copy.translate(x,y);<br>            paintRectangle(component,copy,w,h);<br>            paintHandles(component,copy,w,h);<br>         }<br>         finally {<br>            copy.dispose();<br>         }<br>      }<br>   }<br>   public Insets getBorderInsets() {<br>      return new Insets(thick,thick,thick,thick);<br>   }<br>   protected void paintRectangle(Component c, Graphics g,<br>                           int w, int h) {<br>      g.setColor(lineColor);<br>      g.drawRect(thick/2,thick/2,w-thick-1,h-thick-1);<br>   }<br>   protected void paintHandles(Component c, Graphics g,<br>                           int w, int h) {<br>      g.setColor(lineColor);<br>      g.fillRect(0,0,thick,thick); <br>      g.fillRect(w-thick,0,thick,thick); <br>      g.fillRect(0,h-thick,thick,thick); <br>      g.fillRect(w-thick,h-thick,thick,thick); <br>      g.fillRect(w/2-thick/2,0,thick,thick); <br>      g.fillRect(0,h/2-thick/2,thick,thick); <br>      g.fillRect(w/2-thick/2,h-thick,thick,thick); <br>      g.fillRect(w-thick,h/2-thick/2,thick,thick); <br>   }   <br>}</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>HandleBorder类继承了 javax.swing.border.AbstractBorder类并重写了paintBorder（）和getBorderInsets（）。 HandleBorder是如何实现的其实并不重要，重要的是由于Swing使用了策略模型，开发人员能够很方便地增加新的边框类型。下面的代码显示了如 何使用HandleBorder类。在这个例子中创建了三个JPanel对象，并对每个JPanel对象设定一个HandleBorder实例作为边框。 </p>
<p><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code>// Test.java<br>import javax.swing.*;<br>import javax.swing.border.*;<br>import java.awt.*;<br>import java.awt.event.*;<br>public class Test extends JFrame {<br>   public static void main(String[] args) {<br>      JFrame frame = new Test();<br>      frame.setBounds(100, 100, 500, 200);<br>      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);<br>      frame.show();<br>   }<br>   public Test() {<br>      super("实现一个新的边框类型");<br>      Container contentPane = getContentPane();<br>      JPanel[] panels = { new JPanel(), <br>                     new JPanel(), new JPanel() };<br>      Border[] borders = { new HandleBorder(),<br>                     new HandleBorder(Color.red, 8),<br>                     new HandleBorder(Color.blue, 10) };<br>      contentPane.setLayout(<br>               new FlowLayout(FlowLayout.CENTER,20,20));<br>      for(int i=0; i &lt; panels.length; ++i) {<br>         panels[i].setPreferredSize(new Dimension(100,100));<br>         panels[i].setBorder(borders[i]);<br>         contentPane.add(panels[i]);<br>      }<br>   }<br>}</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>还记得在上面的例子中曾提到在有些情况下，对组件的引用会作为参数传递给 Border.paintBorder（）方法。虽然上面的HandleBorder类没有保存对组件的引用，但是有些情况下Border接口的实现类会 使用到对组件的引用并从中获得关于组件的信息。例如在EtchedBorder中，paintBorder（）方法通过对组件的引用获得它对应的组件的阴 影和高光色： </p>
<p><ccid_nobr></ccid_nobr>
<table cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=550 align=center borderColorLight=black border=1>
    <tbody>
        <tr>
            <td class=code bgColor=#e6e6e6>
            <pre><ccid_code>// 下面的代码截取自javax.swing.border.EtchedBorder<br>public void paintBorder(Component component, Graphics g, int x, int y, <br>                         int width, int height) {<br>   int w = width;<br>   int h = height;<br>   g.translate(x, y);<br>   g.setColor(etchType == LOWERED? getShadowColor(component) : <br>getHighlightColor(component));<br>   g.drawRect(0, 0, w-2, h-2);<br>   g.setColor(etchType == LOWERED? getHighlightColor(component) : <br>getShadowColor(component));<br>   g.drawLine(1, h-3, 1, 1);<br>   g.drawLine(1, 1, w-3, 1);<br>   g.drawLine(0, h-1, w-1, h-1);<br>   g.drawLine(w-1, h-1, w-1, 0);<br>   g.translate(-x, -y);<br>}</ccid_code></pre>
            </td>
        </tr>
    </tbody>
</table>
</p>
<center><font color=#000099><strong>如何实现策略模型</strong></font></center>
<p>通过以下步骤，开发人员可以很容易地在软件中实现策略模型： </p>
<p>1．对策略对象定义一个公共接口。 </p>
<p>2．编写策略类，该类实现了上面的公共接口。 </p>
<p>3．在使用策略对象的类中保存一个对策略对象的引用。 </p>
<p>4．在使用策略对象的类中，实现对策略对象的set和get方法。 </p>
<p>在Swing边框的例子中，公共接口是javax.swing.Border。策略类是LineBorder、EtchedBorder、HandleBorder等。而使用策略对象的类是JComponent。 </p>
<p><br>&nbsp;</p>
<p>转载：<a href="http://fly-net-cn.javaeye.com/blog/78615">http://fly-net-cn.javaeye.com/blog/78615</a></p>
<img src ="http://www.blogjava.net/freesky/aggbug/117266.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freesky/" target="_blank">freesky</a> 2007-05-14 10:28 <a href="http://www.blogjava.net/freesky/archive/2007/05/14/117266.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>架构师书单 2nd Edition</title><link>http://www.blogjava.net/freesky/archive/2007/05/13/117130.html</link><dc:creator>freesky</dc:creator><author>freesky</author><pubDate>Sun, 13 May 2007 09:22:00 GMT</pubDate><guid>http://www.blogjava.net/freesky/archive/2007/05/13/117130.html</guid><wfw:comment>http://www.blogjava.net/freesky/comments/117130.html</wfw:comment><comments>http://www.blogjava.net/freesky/archive/2007/05/13/117130.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freesky/comments/commentRss/117130.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freesky/services/trackbacks/117130.html</trackback:ping><description><![CDATA[<div class=post>
<div class=postText>
<p>&nbsp;&nbsp;&nbsp;作者：<a href="http://blog.csdn.net/calvin/" temp_href="http://blog.csdn.net/calvin/"><u><font color=#0000ff>江南白衣</font></u></a>，原文出处： <a href="http://blog.csdn.net/calvinxiu/archive/2007/03/06/1522032.aspx" temp_href="http://blog.csdn.net/calvinxiu/archive/2007/03/06/1522032.aspx"><u><font color=#0000ff>http://blog.csdn.net/calvinxiu/archive/2007/03/06/1522032.aspx</font></u></a><a href="http://writeblog.csdn.net/calvin/archive/2007/02/09/98914.html" target=_blank temp_href="http://writeblog.csdn.net/calvin/archive/2007/02/09/98914.html"></a>，转载请保留。<br><br>&nbsp;&nbsp;&nbsp;为了2007年的目标，列了下面待读或重读的书单。&nbsp;<br>&nbsp;&nbsp; "其实中国程序员，现在最需要的是一张安静的书桌。"，的确，中国架构师大多缺乏系统的基础知识，与其自欺欺人的宣扬"读书无用，重在实践变通，修身立命哲学书更重要"，把大好时间用来追逐互联网上的片言只语，不如直面缺陷，系统的学习一次。</p>
<h2>&nbsp;&nbsp; 一、Software Architecture篇</h2>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 这个领域没有什么"畅销书"，可能读者中本来就是开发设计人员与项目经理占了多数，真正定位为架构师而且做的也是架构师工作的不多吧，你懂的尽是偏僻的人生。</p>
<p>&nbsp;&nbsp; 1<strong>.软件架构入门&nbsp;<br>《Large-Scale Software Architecture --大型软件体系结构：使用UML实践指南》<br>&nbsp;&nbsp;&nbsp;</strong>现代架构师的入行指南，从什么是架构和架构师一直到以构件为粒度的大型系统架构UML实例。</p>
<p><img alt="" src="http://ec1.images-amazon.com/images/P/0470848499.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec1.images-amazon.com/images/P/0470848499.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"> <img alt="" src="http://www.dearbook.com/Book/BookImage/21/TS_750539497101top.jpg" temp_src="http://www.dearbook.com/Book/BookImage/21/TS_750539497101top.jpg">&nbsp;<br><br><strong>&nbsp;2. 软件架构进阶&nbsp;</strong></p>
<p><strong>《Software Architecture in Practice,2nd Edition--软件构架实践(第2版)》</strong></p>
<p>&nbsp;&nbsp; 第一版是第九届JOLT作品，一本被引用很多的架构书。</p>
<p><strong>《Documenting Software Architectures --软件构架编档》</strong></p>
<p>&nbsp;&nbsp;&nbsp;第13届JOLT大奖作品，捕获架构的过程，<a id=AjaxHolder_Comments_CommentList_ctl16_NameLink target=_blank>徐昊</a>推荐。</p>
<p><strong>《Applied Software Architecture --实用软件体系结构》</strong></p>
<p><strong>&nbsp;&nbsp;</strong> 另一本被引用很多的架构之书。<br><br><strong>《The Art of Software Architecture --软件体系结构的艺术》</strong></p>
<p><strong>&nbsp;&nbsp;&nbsp; </strong>薄薄的一本，上面几本的理论抽象与薄化。<br><strong><br>《Evaluating Software Architectures --软件构架评估》 </strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;SEI出品，正儿八经的ATAM架构评估方法和两个评估案例，顺带介绍了SAAM和ARID。<strong><br></strong><br><img alt="" src="http://ec1.images-amazon.com/images/P/0321154959.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com/Book/BookImage/21/TS_730208042801top.jpg"><br><img alt="" src="http://ec1.images-amazon.com/images/P/0201703726.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec1.images-amazon.com/images/P/0201703726.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com/book/images/TS0012776top.jpg" temp_src="http://www.dearbook.com/book/images/TS0012776top.jpg"></p>
<p><img alt="" src="http://ec1.images-amazon.com/images/P/0201325713.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com/book/BookImage/32/lastTS0032221__.jpg"><br><br><img alt="" src="http://ec2.images-amazon.com/images/P/0471228869.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec2.images-amazon.com/images/P/0471228869.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com/Book/BookImage/22/TS_711113438101top.jpg" temp_src="http://www.dearbook.com/Book/BookImage/22/TS_711113438101top.jpg">&nbsp;<br><img alt="" src="http://ec2.images-amazon.com/images/P/020170482X.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec2.images-amazon.com/images/P/020170482X.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com/book/images/730206020801.jpg" temp_src="http://www.dearbook.com/book/images/730206020801.jpg"></p>
<h2>&nbsp;</h2>
<h2>二、RUP/UML 篇</h2>
<p>RUP、UML、4+1视图始终是架构师界最通用的东西，寻找一种向世界妥协的方式。<br><strong><br>&nbsp;1.&nbsp;RUP 文档<br></strong><strong>《RUP 7.0.1文档》</strong>在Rational Method Composer 7.0试用版之中，是最好架构师的行动指南与自助餐。<br><strong>《The Rational Unified Process:An Introduction.3rd Edition --RUP导论(第3版)》</strong>是RUP2003文档的缩略版，在啃文档细节前可以先拿中文版来翻一下。<br>&nbsp;&nbsp; 但公司里总是充满对RUP的误解<strong>，《The Rational Unified Process Made Easy:A Practitioner's Guide to the RUP--Rational统一过程：实践者指南》</strong>是排除各种误解的RUP实施指南。<br><br>&nbsp; <strong>2. UML2工具书<br>《UML2 Toolkit--UML2.0工具箱》或者《UML精粹第3版--</strong><strong>UML Distilled 3rd》</strong>都不错，后一本略薄。UML2.0相比UML1.x ，对于模型派的架构师来说是天大的恩物，一定要补课。</p>
<p><strong>&nbsp; 3.《UML和模式应用(第3版)--Applying UML and Patterns 3rd》</strong><br>&nbsp;&nbsp; UML+RUP作的OOAD过程。</p>
<p><br><img alt="" src="http://ec1.images-amazon.com/images/P/0131489062.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com/book/BookImage/lastTS00107202__.jpg"></p>
<h2>三、特定领域篇</h2>
<p>&nbsp;&nbsp;&nbsp;&nbsp;开发人员有GOF23 Pattern，架构师同样也有架构师的Pattern。不同领域的架构师需要不同的知识。<br><strong>1. 公共领域<br></strong><strong>《Domain-Specific Application Frameworks --特定领域应用框架：行业的框架体验》<br></strong>&nbsp; ozzzzzz推荐，介绍了30个特定领域特定框架的设计。我自己最喜欢看人家的设计与思考。</p>
<p><strong>《Object Oriented Reengineering Patterns--软件再造：面向对象的软件再工程模式 》</strong><br>&nbsp; 逆向工程与再工程的模式，架构师整天都要和旧系统打交道，接手一个架构师已跑路，文档不全的系统开发2.0版本。<br><br><strong>《Head First Design Patterns》&nbsp;<br></strong>&nbsp;&nbsp;最好的GOF23经典设计模式阐释，适合被[GAMMA95]折磨的架构师拿来复习，中文版即将发行。<br><br><strong><img alt="" src="http://ec1.images-amazon.com/images/P/0471332801.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec1.images-amazon.com/images/P/0471332801.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com.cn/Book/BookImage/23/TS_tdn01top.jpg" temp_src="http://www.dearbook.com.cn/Book/BookImage/23/TS_tdn01top.jpg">&nbsp; <br><img alt="" src="http://ec1.images-amazon.com/images/P/1558606394.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com/Book/BookImage/27/TS_711115018301top.jpg"><br><br><img alt="" src="http://ec2.images-amazon.com/images/P/0596007124.01._AA240_SCLZZZZZZZ_.jpg" temp_src="http://ec2.images-amazon.com/images/P/0596007124.01._AA240_SCLZZZZZZZ_.jpg"><br><br>2. Java EE领域</strong>&nbsp;<br><strong>&nbsp; 《Patterns of Enterprise Application Architecture --企业应用架构模式》 <br>&nbsp;&nbsp;&nbsp;&nbsp; </strong>&nbsp;Martin Fowler经典，企业应用各Layers上的模式。&nbsp;&nbsp;<strong>&nbsp;<br>&nbsp;&nbsp;</strong><br><strong>&nbsp; 《Effective Enterprise Java--中文版》</strong>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Neward, Ted作品，作者学贯东西(.Net与Java)，像写Blog一样，每一页里面都有大量的信息。</p>
<p><img alt="" src="http://ec1.images-amazon.com/images/P/0321127420.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec1.images-amazon.com/images/P/0321127420.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com/Book/BookImage/22/TS_711114305101top.jpg" temp_src="http://www.dearbook.com/Book/BookImage/22/TS_711114305101top.jpg">&nbsp;&nbsp;<br><br><img alt="" src="http://ec2.images-amazon.com/images/P/0321130006.01._AA240_SCLZZZZZZZ_.jpg" temp_src="http://ec2.images-amazon.com/images/P/0321130006.01._AA240_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com.cn/Book/BookImage/30/TS_711117114001top.jpg" temp_src="http://www.dearbook.com.cn/Book/BookImage/30/TS_711117114001top.jpg"><br><br><strong><br>3. EAI/SOA领域&nbsp;<br></strong><strong>《Enterprise Integration Patterns --企业集成模式：设计、构建及部署消息传递解决方案》</strong><br><img alt="" src="http://ec1.images-amazon.com/images/P/0321200683.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec1.images-amazon.com/images/P/0321200683.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com/book/BookImage/lastTS00106277__.jpg" temp_src="http://www.dearbook.com/book/BookImage/lastTS00106277__.jpg">&nbsp; <br><br><br><strong>4. 网络与后台服务编程领域<br></strong><strong>《Pattern-Oriented Software Architecture, Volume 2 --面向模式的软件体系结构 卷2:用于并发和网络化对象的模式》<br><br>《Pattern-Oriented Software Architecture, Volume&nbsp;3 </strong><strong>--面向模式的软件体系结构卷3：资源管理模式》</strong></p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;</strong>著名的POSA2与POSA3。<br><img alt="" src="http://ec1.images-amazon.com/images/P/0471606952.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec1.images-amazon.com/images/P/0471606952.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com.cn/book/images/TS0012515top.jpg" temp_src="http://www.dearbook.com.cn/book/images/TS0012515top.jpg">&nbsp; <br><img alt="" src="http://ec2.images-amazon.com/images/P/0470845252.01._AA240_SCLZZZZZZZ_.jpg" temp_src="http://ec2.images-amazon.com/images/P/0470845252.01._AA240_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com.cn/book/BookImage/35/lastTS0044414__.jpg" temp_src="http://www.dearbook.com.cn/book/BookImage/35/lastTS0044414__.jpg">&nbsp; <br></p>
<h2>四、闲书篇</h2>
<p><strong>《Code Complete 2 --代码大全2》</strong>&nbsp;<br>&nbsp;&nbsp; 一本你教育小弟时的代言人。</p>
<p><strong>《The Pragmatic Programmer --程序员修炼之道：从小工到专家》</strong>&nbsp;<br><strong>&nbsp;&nbsp; </strong>一本你启发小弟的代言人。</p>
<p><strong>《The Art of Unix Programming --UNIX编程艺术》</strong><br><img alt="" src="http://ec2.images-amazon.com/images/P/0735619670.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec2.images-amazon.com/images/P/0735619670.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com.cn/book/BookImage/lastTS0090969__.jpg" temp_src="http://www.dearbook.com.cn/book/BookImage/lastTS0090969__.jpg">&nbsp;<br><br><img alt="" src="http://ec2.images-amazon.com/images/P/020161622X.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec2.images-amazon.com/images/P/020161622X.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com.cn/book/BookImage/47/lastTS0090353__.jpg" temp_src="http://www.dearbook.com.cn/book/BookImage/47/lastTS0090353__.jpg">&nbsp;<br><img alt="" src="http://ec1.images-amazon.com/images/P/0131429019.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec1.images-amazon.com/images/P/0131429019.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg"><img alt="" src="http://www.dearbook.com.cn/book/BookImage/lastTS0091589__.jpg" temp_src="http://www.dearbook.com.cn/book/BookImage/lastTS0091589__.jpg"></p>
<h2>&nbsp;</h2>
<h2>五、高效读书心得</h2>
<p>&nbsp;&nbsp; 刚好Head First系列开头都有一段教人如何读书的话，再加工整理如下：<br><br><strong>1.尽量阅读中文版</strong><br>&nbsp; 虽然有人英文很强，有的翻译很差，但AnyWay 中文阅读与理解的时间，略读与快速定位的速度还是要快一些。<br>&nbsp; <br><strong>2.即时批注、总结笔记与交流</strong><br>&nbsp; 虽然爱书，但发现最有效的读书方式还是不断的制造脂批本，读书时在重要的文字下划线，把自己的心得写在页旁。<br>&nbsp; 在明天复习一次批注，最好可以有空重新整理笔记，或者拿来与人讨论。&nbsp;<br>&nbsp;<br><strong>3.大量思考或重复记忆</strong><br>&nbsp; 看书最郁闷的事情就是看完之后脑袋空空了。技术书还好点，虽然看的时候可能很辛苦，但就像学会了骑单车，之后再骑的时候总是会的；而偏设计与管理的书，最容易的事情就是看的时候很快，看完没什么留下到实践中。<br>&nbsp; 所以，我们不能以看小说的速度来看设计书，要寻找思考的机会，思考是最好的记忆。<br>&nbsp; 又或者，大量的重复记忆，重复多遍直到无意识的记忆。&nbsp;<br>&nbsp; <br><strong>4.人体工学</strong><br>&nbsp;&nbsp;那些见缝插针的时间与地点不是看这个书单的好地方。<br>&nbsp; 环境不要有电视，音乐等强输入源，而微风阳光鸟语等弱输入源则有助活跃大脑。<br>&nbsp; 看书时大量的喝水。<br>&nbsp; 如果发现自己的大脑已经疲累，已经在浮光掠影的翻看，就要休息。<br>&nbsp; 留给大脑消化的时间，看完书不要接着看其他有难度的书或事情。</p>
</div>
</div>
<img src ="http://www.blogjava.net/freesky/aggbug/117130.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freesky/" target="_blank">freesky</a> 2007-05-13 17:22 <a href="http://www.blogjava.net/freesky/archive/2007/05/13/117130.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>观点与展望，第 3 部分: 什么是最有价值的 IT 体系结构技能，如何学习</title><link>http://www.blogjava.net/freesky/archive/2007/05/13/117128.html</link><dc:creator>freesky</dc:creator><author>freesky</author><pubDate>Sun, 13 May 2007 09:17:00 GMT</pubDate><guid>http://www.blogjava.net/freesky/archive/2007/05/13/117128.html</guid><wfw:comment>http://www.blogjava.net/freesky/comments/117128.html</wfw:comment><comments>http://www.blogjava.net/freesky/archive/2007/05/13/117128.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freesky/comments/commentRss/117128.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freesky/services/trackbacks/117128.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 知道了成为一个成功的 IT 架构师需要投入多少工作后，我们就想知道哪些因素对成为一个不错的架构师起决定性作用。因此，我们向专家组提出了这样的问题：“什么技能对 IT 架构师最有价值，架构师如何学习这些技能？”<br><br>可以在很多地方找到成为好的架构师所需的技能列表——书上、培训课程、大学、有关体系结构的其他网站上等等。例如，IBM 的内部专业提高网站就提出以下几点 IT 架构师的理想特征：<br><br>设计体系结构的技能和经验 <br>有序的以方法为驱动源的任务执行 <br>完整生命周期经验 <br>行业部门经验 <br>领导能力 <br>很强的沟通和专业技能 <br><br>和可能看到的很多其他列表类似，这个列表相当泛泛，可能并不如您所期望的那样有可操作性。而这正是我们询问前面的问题的原因所在：帮助您确定一个明确的方向。<br><br>&nbsp;&nbsp;<a href='http://www.blogjava.net/freesky/archive/2007/05/13/117128.html'>阅读全文</a><img src ="http://www.blogjava.net/freesky/aggbug/117128.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freesky/" target="_blank">freesky</a> 2007-05-13 17:17 <a href="http://www.blogjava.net/freesky/archive/2007/05/13/117128.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>观点与展望，第 2 部分: 如何将业务需求转转换为 IT 要求</title><link>http://www.blogjava.net/freesky/archive/2007/05/13/117124.html</link><dc:creator>freesky</dc:creator><author>freesky</author><pubDate>Sun, 13 May 2007 09:11:00 GMT</pubDate><guid>http://www.blogjava.net/freesky/archive/2007/05/13/117124.html</guid><wfw:comment>http://www.blogjava.net/freesky/comments/117124.html</wfw:comment><comments>http://www.blogjava.net/freesky/archive/2007/05/13/117124.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freesky/comments/commentRss/117124.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freesky/services/trackbacks/117124.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 作为 IT 架构师，您可能经常会发现自己处于进退维谷的境地，前有您的业务目标，后有您的 IT 系统。这两方面都具有规模大、不易改变和灵活性差的特点。制定业务目标的人员和开发系统的人员不一定了解彼此的工作内容和成果。似乎是这样，业务人员使用一种语言来表达他们希望实现的业务目标，而开发人员则使用另一种语言来表述技术要求。<br><br>而这就是我们为了实现高效率而需要着手处理的问题：理解这两种语言并执行必要的转换，以便 IT 能反映业务的需求，并能在适当的时候对业务目标进行更改，使其与 IT 的能力相适应。这并不是一个容易完成的工作，但这正是您能够获得很大利益的原因。<br><br>由于这部分工作可能会非常困难而棘手，因此，我们向 IBM 体系结构专家队伍寻求指导。本月我们邀请这些专家分享他们用来将业务需求表述为明晰简洁的技术要求的方法，以便 IT 团队能成功地实现。 <br><br>&nbsp;&nbsp;<a href='http://www.blogjava.net/freesky/archive/2007/05/13/117124.html'>阅读全文</a><img src ="http://www.blogjava.net/freesky/aggbug/117124.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freesky/" target="_blank">freesky</a> 2007-05-13 17:11 <a href="http://www.blogjava.net/freesky/archive/2007/05/13/117124.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>观点与展望，第 1 部分: 选择 SOA 的原因和时机</title><link>http://www.blogjava.net/freesky/archive/2007/05/13/117122.html</link><dc:creator>freesky</dc:creator><author>freesky</author><pubDate>Sun, 13 May 2007 09:04:00 GMT</pubDate><guid>http://www.blogjava.net/freesky/archive/2007/05/13/117122.html</guid><wfw:comment>http://www.blogjava.net/freesky/comments/117122.html</wfw:comment><comments>http://www.blogjava.net/freesky/archive/2007/05/13/117122.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/freesky/comments/commentRss/117122.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/freesky/services/trackbacks/117122.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 面向服务的体系结构 (SOA) 已成为了一项事实标准，用于开发基于组件的应用程序，可使用标准接口通过网络（Internet 或其他网络）访问这些应用程序。至少 IBM 高级管理人员和很多其他供应商、分析师、顾问和软件开发人员都这么说。他们还将告诉您，整个行业都在逐步采用 SOA，如果您尚未开始 SOA 开发，将很快跟不上时代的步伐了。<br><br>赞誉之词。但这些看法是否真的很有吸引力，能让您开始着手您自己的 SOA 吗？让我们来看看一位参加 Open Group 主办的 SOA 大会的架构师的问题。在 IBM Global Services 副总裁 Michael Liebow 的主题发言后的提问期间，这位架构师问道：“SOA 是不是我们需要知道的唯一体系结构？（顺便提一下，Liebow 先生的回答是“是的”）在稍后，另一位架构师大声问道：“SOA 和我们多年前就知道的组件体系结构很相似。如果我们采用了它，是否意味着我们又多添了一个技术竖井（另一个开发死胡同），从而需要进行更多的集成？”（而这次，会议参加者——包括平台供应商、企业 IT 架构师、顾问、系统集成商和其他人员——回&nbsp;&nbsp;<a href='http://www.blogjava.net/freesky/archive/2007/05/13/117122.html'>阅读全文</a><img src ="http://www.blogjava.net/freesky/aggbug/117122.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/freesky/" target="_blank">freesky</a> 2007-05-13 17:04 <a href="http://www.blogjava.net/freesky/archive/2007/05/13/117122.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>