??xml version="1.0" encoding="utf-8" standalone="yes"?>一区二区视频在线播放,国产成人精品久久久,九色精品免费永久在线http://www.aygfsteel.com/freesky/自由天空zh-cnThu, 19 Jun 2025 09:35:59 GMTThu, 19 Jun 2025 09:35:59 GMT60Debugging makehttp://www.aygfsteel.com/freesky/archive/2008/07/27/217881.htmlfreeskyfreeskySun, 27 Jul 2008 13:26:00 GMThttp://www.aygfsteel.com/freesky/archive/2008/07/27/217881.htmlhttp://www.aygfsteel.com/freesky/comments/217881.htmlhttp://www.aygfsteel.com/freesky/archive/2008/07/27/217881.html#Feedback0http://www.aygfsteel.com/freesky/comments/commentRss/217881.htmlhttp://www.aygfsteel.com/freesky/services/trackbacks/217881.html         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.



Most UNIX® and Linux® programs are built by running make. 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 autoconf/automake 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.

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).

Less common but still relevant are Jörg Schilling's smake, 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.

Let's review some of the most common problems you'll encounter when working with makefiles.

Understanding the makefile

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 dependency management: 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:


Listing 1. Form of dependency rule
target: dependencies
            instructions
            

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:


Listing 2. Berkeley make error message
make: "Makefile" line 2: Need an operator
            make: Fatal errors encountered -- cannot continue
            

GNU make, while still unable to process the file, gives a more helpful suggestion:


Listing 3. GNU make error message
Makefile::2: *** missing separator (did you mean TAB instead of 8 spaces?).  Stop.
            

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 target, 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 target exists and is at least as new as all of the items listed in dependencies, nothing is done. If target does not exist, or one or more dependencies is newer, then make executes instructions. Dependencies are processed in the order that they are specified. If no dependencies are specified, the instructions are followed anyway. Dependencies are also called sources.

If a target is given on the command line (for example, make foo), 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:


Listing 4. Commonly used first target convention
default: all
            

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.

Phony targets

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:


Listing 5. Example phony target
all: hello goodbye fibonacci
            

This rule instructs make -- if it wishes to build the target all -- 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."

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:


Listing 6. Intelligently used phony target
build: clean all install
            

This specifies an order of operations for the build process.

Special targets and sources

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 .SUFFIXES 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.

Some versions of make allow special sources to be specified along with the dependencies for a given target, such as .IGNORE, 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.

Generic rules

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 make hello:


Listing 7. Example of implicit rule for C files
$ make hello
            cc -O2   -o hello hello.c
            

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:


Listing 8. Rule for converting .c to .o files
.c.o:
            cc $(CFLAGS) -c $<
            

In fact, most make utilities have a rule very much like this built in already; if you ask make to build file.o, and it has file.c, it'll do the right thing. The term "$<" is a special predefined make variable that refers to the "source" for a rule. That brings us to make variables.

Generic rules depend on the declaration of "suffixes," which make then recognizes as filename extensions rather than part of a name.

Variables

The make program uses variables to make it easier to reuse common values. The most set value is probably CFLAGS. 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:

  1. Command-line variable settings
  2. Variables set in a parent make process's makefile
  3. Variables set in this make process's makefile
  4. Environment variables

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.)

A common problem people run into with make is variables inexplicably being replaced by parts of their names: for instance, $CFLAGS being replaced by "FLAGS". To refer to a make variable, put its name in parentheses: $(CFLAGS). Otherwise, you get $C followed by FLAGS.

A number of variables have special meanings that are a function of the rule they're being used in. The most commonly used are:

  • $< - The source from which the target is to be made
  • $* - The base name of the target (no extensions or directory)
  • $@ - The full name of the target

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.

Shell scripting

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.

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:


Listing 9. Breaking lines in a shell script
all:
            for i in $(ALLDIRS) ; \
            do      ( cd $$i ; $(MAKE) all ) ; \
            done
            

This illustrates the three things to keep in mind. First, the use of semicolons and backslashes. Second, the use of $(VARIABLE) for make variables. Third, the use of $$ to pass a dollar sign to the shell. That's it! It really is that easy.

Prefixes

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.

If you don't want to echo a command, prefix it with an at-sign (@). This is most commonly used for displaying messages:


Listing 10. Suppressing echo
all:
            @echo "Beginning build at:"
            @date
            @echo "--------"
            

Without the @ signs, this would produce the output:


Listing 11. Commands without @
echo "Beginning build at:"
            Beginning build at:
            date
            Sun Jun 18 01:13:21 CDT 2006
            echo "--------"
            --------
            

While the @ sign doesn't really change what make does, it's a very popular feature.



Back to top


Things you can't do portably

Some things that everyone wants to do cannot be portably done. But there are some workarounds to be had.

Include files

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 include file. The traditional Berkeley syntax is .include "file". At least one Berkeley make now supports the GNU notation as well, but not all do. The portable solution, discovered by both autoconf and Imake, is just to include every variable assignment you think you might want.

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.)

Getting variables to nested builds

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!

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...

This is amplified by the lack of include files, as anyone who has ever struggled with Imake's multi-thousand-line makefiles can attest.

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 Resources) is probably the canonical source.



Back to top


What to do when there's a problem

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.

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.

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.

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.

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.

Debugging flags can be pretty useful. For GNU make, the -d flag will give you a HUGE amount of information, some of it useful. For Berkeley make, the -d flag takes a set of flags; -d A is the complete set, or you can use subsets; for instance, -d vx will give debugging information about variable assignments (v) and cause all commands to be run through sh -x so the shell will echo the exact command it received. The -n 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.

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.



Back to top


Documentation

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 man make and look for information about it. However, the documentation is reasonably complete.

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.

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.



Resources

Learn

Get products and technologies
  • Order the SEK for Linux, a two-DVD set containing the latest IBM trial software for Linux from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®.

  • With IBM trial software, available for download directly from developerWorks, build your next development project on Linux.


Discuss

转自:http://www-128.ibm.com/developerworks/library/l-debugmake.html



freesky 2008-07-27 21:26 发表评论
]]>
MakeFile学习Q{Q?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/freesky/archive/2008/07/27/217878.html</guid><wfw:comment>http://www.aygfsteel.com/freesky/comments/217878.html</wfw:comment><comments>http://www.aygfsteel.com/freesky/archive/2008/07/27/217878.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/freesky/comments/commentRss/217878.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/freesky/services/trackbacks/217878.html</trackback:ping><description><![CDATA[     摘要: 跟我一起写 Makefile   陈皓 概述 什么是makefileQ或许很多Winodws的程序员都不知道q个东西Q因为那些Windows的IDE都ؓ你做了这个工作,但我觉得要作一个好的和professional的程序员Qmakefileq是要懂。这好像现在有q么多的HTML的编辑器Q但如果你想成ؓ一个专业h士,你还是要了解HTML的标识的含义。特别在Unix下的...  <a href='http://www.aygfsteel.com/freesky/archive/2008/07/27/217878.html'>阅读全文</a><img src ="http://www.aygfsteel.com/freesky/aggbug/217878.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/freesky/" target="_blank">freesky</a> 2008-07-27 21:19 <a href="http://www.aygfsteel.com/freesky/archive/2008/07/27/217878.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java模式设计之模板方法模?http://www.aygfsteel.com/freesky/archive/2007/05/14/117275.htmlfreeskyfreeskyMon, 14 May 2007 02:40:00 GMThttp://www.aygfsteel.com/freesky/archive/2007/05/14/117275.htmlhttp://www.aygfsteel.com/freesky/comments/117275.htmlhttp://www.aygfsteel.com/freesky/archive/2007/05/14/117275.html#Feedback0http://www.aygfsteel.com/freesky/comments/commentRss/117275.htmlhttp://www.aygfsteel.com/freesky/services/trackbacks/117275.html q是一个很单的模式Q却被非常广泛的使用。之所以简单是因ؓ在这个模式中仅仅使用Cl承关系?br>
l承关系׃自n的缺P被专家们扣上?#8220;|恶”的帽子?#8220;使用委派关系代替l承关系”Q?#8220;量使用接口实现而不是抽象类l承”{等专家警告Q让我们q些菜鸟对?#8220;另眼相看”?br>
其实Q承还是有很多自n的优Ҏ(gu)在。只是被大家滥用的似乎缺Ҏ(gu)加明显了。合理的利用l承关系Q还是能对你的系l设计v到很好的作用的。而模板方法模式就是其中的一个用范例?br>
二、定义与l构

GOFl模板方法(Template MethodQ模式定义一个操作中的算法的骨架Q而将一些步骤gq到子类中。得子cd以不改变一个算法的l构卛_重定义该法的某些特定步骤。这里的?法的l构Q可以理解ؓ你根据需求设计出来的业务程。特定的步骤是指那些可能在内容上存在变数的环节?br>
可以看出来,模板Ҏ(gu)模式也是Z巧妙解决变化对系l带来的影响而设计的。用模板方法ɾpȝ扩展性增强,最化了变化对pȝ的媄响。这一点,在下面的举例中可以很明显的看出来?br>
来看下这个简单模式的l构吧:

1) AbstractClassQ抽象类Q:定义了一到多个的抽象Ҏ(gu)Q以供具体的子类来实现它们;而且q要实现一个模板方法,来定义一个算法的骨架。该模板Ҏ(gu)不仅调用前面的抽象方法,也可以调用其他的操作Q只要能完成自n的命?br>
2) ConcreteClassQ具体类Q:实现父类中的抽象Ҏ(gu)以完成算法中与特定子cȝ关的步骤?br>
下面是模板方法模式的l构图。直接把《设计模式》上的图拿过来用下:


三、D?/strong>

q是在我刚刚分析完源码的JUnit中找个例子吧。JUnit中的TestCase以及它的子类是一个模板方法模式的例子。在TestCaseq个?象类中将整个试的流E设|好了,比如先执行SetupҎ(gu)初始化测试前提,在运行测试方法,然后再TearDown来取消测试设|。但是你在 Setup、TearDown里面作些什么呢Q鬼才知道呢Q!因此Q而这些步骤的具体实现都gq到子类中去Q也是你实现的试cM?br>
来看下相关的源代码吧?br>
q是TestCase中,执行试的模板方法。你可以看到Q里面正像前面定义中所说的那样Q它制定?#8220;法”的框架——先执行setUpҎ(gu)来做下初始化Q然后执行测试方法,最后执行tearDown释放你得到的资源?br>
public void runBare() throws Throwable {
setUp();

try {
runTest();
}

finally {
tearDown();
}
}

q就是上面用的两个Ҏ(gu)。与定义中不同的是,q两个方法ƈ没有被实Cؓ抽象Ҏ(gu)Q而是两个I的无ؓҎ(gu)Q被UCؓ钩子Ҏ(gu)Q。这是因为在试中,我们q?不是必须要让试E序使用q两个方法来初始化和释放资源的。如果是抽象Ҏ(gu)Q则子类们必ȝ它一个实玎ͼ不管用到用不到。这昄是不合理的。用钩子方 法,则你在需要的时候,可以在子cM重写q些Ҏ(gu)?br>
protected void setUp() throws Exception {}
protected void tearDown() throws Exception {}

四、适用情况

Ҏ(gu)上面对定义的分析Q以及例子的说明Q可以看出模板方法适用于以下情况:

1) 一ơ性实C个算法的不变的部分,q将可变的行为留l子cL实现?br>
2) 各子cM公共的行为应被提取出来ƈ集中C个公qcM以避免代码重复。其实这可以说是一U好的编码习惯了?br>
3) 控制子类扩展。模板方法只在特定点调用操作Q这样就只允许在q些点进行扩展。比如上面runBareQ)Ҏ(gu)只在runTest前面适用setUp?法。如果你不愿子类来修改你的模板方法定义的框架Q你可以采用两种方式来做Q一是在API中不体现Z的模板方法;二、将你的模板Ҏ(gu)|ؓfinal可 以了?br>
可以看出Q用模板方法模式可以将代码的公p为提取出来,辑ֈ复用的目的。而且Q在模板Ҏ(gu)模式中,是由父类的模板方法来控制子类中的具体实现。这样你在实现子cȝ时候,Ҏ(gu)不需要对业务程有太多的了解?/td>


 

转蝲Q?a >http://fly-net-cn.javaeye.com/blog/78611



freesky 2007-05-14 10:40 发表评论
]]>
Java设计模式之策略模?/title><link>http://www.aygfsteel.com/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.aygfsteel.com/freesky/archive/2007/05/14/117266.html</guid><wfw:comment>http://www.aygfsteel.com/freesky/comments/117266.html</wfw:comment><comments>http://www.aygfsteel.com/freesky/archive/2007/05/14/117266.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/freesky/comments/commentRss/117266.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/freesky/services/trackbacks/117266.html</trackback:ping><description><![CDATA[<p>{略模式QStrategy PatternQ中体现了两个非常基本的面向对象设计的基本原则:装变化的概念;~程中用接口,而不是对接口实现。策略模式的定义如下Q?</p> <p>定义一l算法,每个算法都装hQƈ且它们之间可以互换。策略模式ɘq些法在客L(fng)调用它们的时候能够互不媄响地变化?</p> <p>{略模式使开发h员能够开发出p多可替换的部分组成的软gQƈ且各个部分之间是p接的关系。弱q接的特性软gh更强的可扩展性,易于l护Q更重要的是Q它大大提高了Y件的可重用性?</p> <p>Z说明{略模式Q我们将首先讨论一下在Swing中是如何利用{略模式来绘制组件边界的Q然后讨论在Swing中用策略模式带来的好处Q最后讨论如何在软g中实现策略模式?</p> <center><font color=#000099><strong>SwingҎ(gu)</strong></font></center> <p>Ҏ(gu)有的SwinglgQ例如按钮、列表单{,都还可以l制Ҏ(gu)。在Swing中提供了各种 Ҏ(gu)cdQ例如bevel、etched、line、titled{。Swinglg的边框是通过JComponentcLl制的,该类是所有Swing lg的基c,实现了所有Swinglg公共的功能。在JComponent中有一个paintBorder()Ҏ(gu)Q该Ҏ(gu)为组件绘制边框。Swing?开发h员可以象下面的例子中所C那hl制Ҏ(gu)Q?</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>// 一D实现paintBorderQ)Ҏ(gu)代码<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>h意上面的代码只是一U假设,事实上Swing的开发h员ƈ没有q样实现 paintBorderQ)Ҏ(gu)。在上面的代码中Q在JComponent中绘制边框的代码被直接写入了paintBorderQ)Ҏ(gu)中,q意味着 JComponent和绘制边框的功能被紧密地l合在了一赗很自然地大家会联想到如果需要实CU新的边框类型,开发h员必M改至三处代码:首先?加一个常量,该常量代表新d的边框的cd|其次需要在Switch语句中增加一个case语句Q最后开发h员需要实现paintXXXBorder Q)Ҏ(gu)Q其中XXX代表新边框的名称?</p> <p>很显然要扩展上面paintBorder()Ҏ(gu)的功能是一件很困难的事情,不仅 仅是因ؓ开发h员需要增加一U新的边框类型,更麻烦的是开发h员很难修改JComponentcRJComponentcdl被~译CSwing的开?工具中,如果开发h员想修改它的话,必须获得Swing的源代码Q修改后重新~译Swing。同时在用户的计机上与需要用新~译的Swing API。另外所有的Swinglg都可以用开发h员新d的边框类型。有可能开发h员只希望新的Ҏ(gu)被某些组件用,但是现在开发h员无法对使用该边?的组件进行限制?</p> <p>开发h员有更好的实现方法吗Q答案就是策略模式。通过{略模式Q可以将 JComponent和实现绘制边框的代码分离开来,q样开发h员在增加或修改绘制边框的代码使就不需要修改JComponent的代码。通过应用{略?式,开发h员将变化的概念(在这个例子中是绘制边框)装hQ然后通过一个Border接口QɽE序能够重用l制Ҏ(gu)的功能。下面让我们来看 JComponent是如何利用策略模式来实现l制Ҏ(gu)的功能的Q?</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()Ҏ(gu)的源代码<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()Ҏ(gu)通过一个border对象l制了组件的Ҏ(gu)?q样border对象替代了前一个例子中的JComponent装了边框绘制的功能。我们还应该注意到JComponent一个对自己的引用传递给?Border.paintBorderQ)Ҏ(gu)Q这是因为Border的实例必ȝ道它对应的组件的信息Q这U方式通常被称为委托。通过q种方式Q一个对 象可以将功能委托l另一个对象来实现?</p> <p>在JComponentcM引用了一个Border对象Q通过JComponent.getBorderQ)Ҏ(gu)可以获得该Border对象。下面的代码演示了如何设定和获得Border对象Q?</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>当开发h员通过JComponent.setBorderQ)Ҏ(gu)讑֮了一个组件的 Ҏ(gu)后,JComponentcdZ个属性更C件。如果新的边框和以前的边框不同的话,setBorderQ)Ҏ(gu)重新绘制边框?getBorderQ)Ҏ(gu)仅仅q回对Border对象的引用。图1昄了Border的类l构图: </p> <center><img alt="" src="http://industry.ccidnet.com/col/attachment/2003/2/99506.jpg"></center> <center>? Border的类l构?/center> <p>通过cȝ构图我们可以看到QJComponentcM保存了一个对Border对象的引用。由于Border是一个接口,Swinglg可以使用M一个实CBorder接口的类?</p> <p>现在我们已经知道了JComponent是如何利用策略模式来l制lg的边框的。下面让我们通过实现一个新的边框类型来试一下它的可扩展性?</p> <center><font color=#000099><strong>实现一个新的边框类?/strong></font></center> <p>?中是一个有三个JPanel对象的小E序Q每个JPanel对象有各自不同的Ҏ(gu)Q每个边框对应一个HandleBorder实例?</p> <center><img alt="" src="http://industry.ccidnet.com/col/attachment/2003/2/99507.jpg"></center> <center>? 新的Ҏ(gu)cd</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>HandleBordercȝ承了 javax.swing.border.AbstractBordercdƈ重写了paintBorderQ)和getBorderInsetsQ)?HandleBorder是如何实现的其实q不重要Q重要的是由于Swing使用了策略模型,开发h员能够很方便地增加新的边框类型。下面的代码昄了如 何用HandleBordercR在q个例子中创Z三个JPanel对象QƈҎ(gu)个JPanel对象讑֮一个HandleBorder实例作ؓҎ(gu)?</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 < 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>q记得在上面的例子中曾提到在有些情况下,对组件的引用会作为参C递给 Border.paintBorderQ)Ҏ(gu)。虽然上面的HandleBordercL有保存对lg的引用,但是有些情况下Border接口的实现类?使用到对lg的引用ƈ从中获得关于lg的信息。例如在EtchedBorder中,paintBorderQ)Ҏ(gu)通过对组件的引用获得它对应的lg的阴 影和高光Ԍ </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>通过以下步骤Q开发h员可以很Ҏ(gu)地在软g中实现策略模型: </p> <p>1Q对{略对象定义一个公共接口?</p> <p>2Q编写策略类Q该cdC上面的公共接口?</p> <p>3Q在使用{略对象的类中保存一个对{略对象的引用?</p> <p>4Q在使用{略对象的类中,实现对策略对象的set和getҎ(gu)?</p> <p>在SwingҎ(gu)的例子中Q公共接口是javax.swing.Border。策略类是LineBorder、EtchedBorder、HandleBorder{。而用策略对象的cLJComponent?</p> <p><br> </p> <p>转蝲Q?a >http://fly-net-cn.javaeye.com/blog/78615</a></p> <img src ="http://www.aygfsteel.com/freesky/aggbug/117266.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/freesky/" target="_blank">freesky</a> 2007-05-14 10:28 <a href="http://www.aygfsteel.com/freesky/archive/2007/05/14/117266.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>架构师书?2nd Editionhttp://www.aygfsteel.com/freesky/archive/2007/05/13/117130.htmlfreeskyfreeskySun, 13 May 2007 09:22:00 GMThttp://www.aygfsteel.com/freesky/archive/2007/05/13/117130.htmlhttp://www.aygfsteel.com/freesky/comments/117130.htmlhttp://www.aygfsteel.com/freesky/archive/2007/05/13/117130.html#Feedback0http://www.aygfsteel.com/freesky/comments/commentRss/117130.htmlhttp://www.aygfsteel.com/freesky/services/trackbacks/117130.html

   作者:江南白衣Q原文出处: http://blog.csdn.net/calvinxiu/archive/2007/03/06/1522032.aspx

   一、Software Architecture?/h2>

     q个领域没有什?畅销?Q可能读者中本来是开发设计h员与目l理占了多数Q真正定位ؓ架构师而且做的也是架构师工作的不多吧,你懂的尽是偏?ni)人生?/p>

   1.软g架构入门 
《Large-Scale Software Architecture --大型软g体系l构Q用UML实践指南?br>   
C架构师的入行指南Q从什么是架构和架构师一直到以构件ؓ_度的大型系l架构UML实例?/p>

 

 2. 软g架构q阶 

《Software Architecture in Practice,2nd Edition--软g构架实践(W???/strong>

   W一版是W九(ji)届JOLT作品Q一本被引用很多的架构书?/p>

《Documenting Software Architectures --软g构架~档?/strong>

   W?3届JOLT大奖作品Q捕h构的q程Q?a id=AjaxHolder_Comments_CommentList_ctl16_NameLink target=_blank>徐昊推荐?/p>

《Applied Software Architecture --实用软g体系l构?/strong>

   另一本被引用很多的架构之书?br>
《The Art of Software Architecture --软g体系l构的艺术?/strong>

    薄薄的一本,上面几本的理论抽象与薄化?br>
《Evaluating Software Architectures --软g构架评估?

    SEI出品Q正儿八l的ATAM架构评估Ҏ(gu)和两个评估案例,带介绍了SAAM和ARID?strong>




 

 

二、RUP/UML ?/h2>

RUP、UML?+1视图始终是架构师界最通用的东西,L一U向世界妥协的方式?br>
 1. RUP 文档
《RUP 7.0.1文档?/strong>在Rational Method Composer 7.0试用版之中,是最好架构师的行动指南与自助?br>《The Rational Unified Process:An Introduction.3rd Edition --RUPD(W???/strong>是RUP2003文档的羃略版Q在啃文档细节前可以先拿中文版来M下?br>   但公叔RL充满对RUP的误?strong>Q《The Rational Unified Process Made Easy:A Practitioner's Guide to the RUP--Rationall一q程Q实践者指南?/strong>是排除各U误解的RUP实施指南?br>
  2. UML2工具?br>《UML2 Toolkit--UML2.0工具》或者《UML_aW??-UML Distilled 3rd?/strong>都不错,后一本略薄。UML2.0相比UML1.x Q对于模型派的架构师来说是天大的恩物Q一定要补课?/p>

  3.《UML和模式应?W??--Applying UML and Patterns 3rd?/strong>
   UML+RUP作的OOADq程?/p>


三、特定领域篇

    开发h员有GOF23 PatternQ架构师同样也有架构师的Pattern。不同领域的架构师需要不同的知识?br>1. 公共领域
《Domain-Specific Application Frameworks --特定领域应用框架Q行业的框架体验?br>  ozzzzzz推荐Q介l了30个特定领域特定框架的设计。我自己最喜欢看h家的设计与思考?/p>

《Object Oriented Reengineering Patterns--软g再造:面向对象的Y件再工程模式 ?/strong>
  逆向工程与再工程的模式,架构师整天都要和旧系l打交道Q接手一个架构师已跑路,文档不全的系l开?.0版本?br>
《Head First Design Patterns?nbsp;
  最好的GOF23l典设计模式阐释Q适合被[GAMMA95]折磨的架构师拿来复习Q中文版卛_发行?br>
 




2. Java EE领域
 
  《Patterns of Enterprise Application Architecture --企业应用架构模式?
    
 Martin Fowlerl典Q企业应用各Layers上的模式?nbsp;  
  

  《Effective Enterprise Java--中文版?/strong>    
      Neward, Ted作品Q作者学贯东?.Net与Java)Q像写Blog一P每一里面都有大量的信息?/p>

  




3. EAI/SOA领域 
《Enterprise Integration Patterns --企业集成模式Q设计、构建及部v消息传递解x案?/strong>
 


4. |络与后台服务编E领?br>《Pattern-Oriented Software Architecture, Volume 2 --面向模式的Y件体pȝ??:用于q发和网l化对象的模式?br>
《Pattern-Oriented Software Architecture, Volume 3
--面向模式的Y件体pȝ构卷3Q资源管理模式?/strong>

    著名的POSA2与POSA3?br> 
 

四、闲书篇

《Code Complete 2 --代码大全2?/strong> 
   一本你教育弟时的代言人?/p>

《The Pragmatic Programmer --E序员修g道:从小工到专家?/strong> 
   一本你启发弟的代a人?/p>

《The Art of Unix Programming --UNIX~程艺术?/strong>
 

 

 

五、高效读书心?/h2>

   刚好Head Firstpd开头都有一D|人如何读书的话,再加工整理如下:

1.量阅读中文?/strong>
  虽然有h英文很强Q有的翻译很差,但AnyWay 中文阅读与理解的旉Q略M快速定位的速度q是要快一些?br> 
2.xҎ(gu)、ȝW记与交?/strong>
  虽然׃Q但发现最有效的读书方式还是不断的刉脂Ҏ(gu)Q读书时在重要的文字下划U,把自q心得写在|?br>  在明天复习一ơ批注,最好可以有I重新整理笔讎ͼ或者拿来与论?nbsp;
 
3.大量思考或重复记忆
  看书最郁闷的事情就是看完之后脑袋空IZ。技术书q好点,虽然看的时候可能很辛苦Q但像学会了骑单RQ之后再骑的时候L会的Q而偏设计与管理的书,最Ҏ(gu)的事情就是看的时候很快,看完没什么留下到实践中?br>  所以,我们不能以看说的速度来看设计书,要寻找思考的ZQ思考是最好的记忆?br>  又或者,大量的重复记忆,重复多遍直到无意识的记忆?nbsp;
 
4.Z工学
  那些见缝插针的时间与地点不是看这个书单的好地斏V?br>  环境不要有电(sh)视,音乐{强输入源,而微风阳光鸟语等p入源则有助活跃大脑?br>  看书时大量的喝水?br>  如果发现自己的大脑已l疲累,已经在Q光掠qȝQ就要休息?br>  留给大脑消化的时_看完书不要接着看其他有隑ֺ的书或事情?/p>



freesky 2007-05-13 17:22 发表评论
]]>
观点与展望,W?3 部分: 什么是最有h(hun)值的 IT 体系l构技能,如何学习http://www.aygfsteel.com/freesky/archive/2007/05/13/117128.htmlfreeskyfreeskySun, 13 May 2007 09:17:00 GMThttp://www.aygfsteel.com/freesky/archive/2007/05/13/117128.htmlhttp://www.aygfsteel.com/freesky/comments/117128.htmlhttp://www.aygfsteel.com/freesky/archive/2007/05/13/117128.html#Feedback0http://www.aygfsteel.com/freesky/comments/commentRss/117128.htmlhttp://www.aygfsteel.com/freesky/services/trackbacks/117128.html
可以在很多地Ҏ(gu)到成为好的架构师所需的技能列表——书上、培训课E、大学、有关体pȝ构的其他|站上等{。例如,IBM 的内部专业提高网站就提出以下几点 IT 架构师的理想特征Q?

设计体系l构的技能和l验
有序的以Ҏ(gu)为驱动源的Q务执?
完整生命周期l验
行业部门l验
领导能力
很强的沟通和专业技?

和可能看到的很多其他列表cMQ这个列表相当泛泛,可能q不如?zhn)所期望的那h可操作性。而这正是我们询问前面的问题的原因所在:帮助(zhn)确定一个明的方向?

  阅读全文

freesky 2007-05-13 17:17 发表评论
]]>
观点与展望,W?2 部分: 如何业务需求{转换?IT 要求http://www.aygfsteel.com/freesky/archive/2007/05/13/117124.htmlfreeskyfreeskySun, 13 May 2007 09:11:00 GMThttp://www.aygfsteel.com/freesky/archive/2007/05/13/117124.htmlhttp://www.aygfsteel.com/freesky/comments/117124.htmlhttp://www.aygfsteel.com/freesky/archive/2007/05/13/117124.html#Feedback0http://www.aygfsteel.com/freesky/comments/commentRss/117124.htmlhttp://www.aygfsteel.com/freesky/services/trackbacks/117124.html
而这是我们Z实现高效率而需要着手处理的问题Q理解这两种语言q执行必要的转换Q以?IT 能反映业务的需求,q能在适当的时候对业务目标q行更改Q其与 IT 的能力相适应。这q不是一个容易完成的工作Q但q正是?zhn)能够获得很大利益的原因?

׃q部分工作可能会非常困难而棘手,因此Q我们向 IBM 体系l构专家队伍L指导。本月我们邀误些专家分享他们用来将业务需求表qCؓ明晰z的技术要求的Ҏ(gu)Q以?IT 团队能成功地实现?

  阅读全文

freesky 2007-05-13 17:11 发表评论
]]>
观点与展望,W?1 部分: 选择 SOA 的原因和时机http://www.aygfsteel.com/freesky/archive/2007/05/13/117122.htmlfreeskyfreeskySun, 13 May 2007 09:04:00 GMThttp://www.aygfsteel.com/freesky/archive/2007/05/13/117122.htmlhttp://www.aygfsteel.com/freesky/comments/117122.htmlhttp://www.aygfsteel.com/freesky/archive/2007/05/13/117122.html#Feedback0http://www.aygfsteel.com/freesky/comments/commentRss/117122.htmlhttp://www.aygfsteel.com/freesky/services/trackbacks/117122.html
赞誉之词。但q些看法是否真的很有吸引力,能让(zhn)开始着手?zhn)自己?SOA 吗?让我们来看看一位参?Open Group d?SOA 大会的架构师的问题。在 IBM Global Services 副总裁 Michael Liebow 的主题发a后的提问期间Q这位架构师问道Q“SOA 是不是我们需要知道的唯一体系l构Q(Z提一下,Liebow 先生的回{是“是的”)在稍后,另一位架构师大声问道Q“SOA 和我们多q前q道的lg体系l构很相伹{如果我们采用了它,是否意味着我们又多M一个技术竖井(另一个开发死胡同Q,从而需要进行更多的集成Q”(而这ơ,会议参加者——包括^C应商、企?IT 架构师、顾问、系l集成商和其他h员——回  阅读全文

freesky 2007-05-13 17:04 发表评论
]]>
վ֩ģ壺 ǿ| | Ϫ| ̨| ʡ| | | | | ξ| | | ɽ| | | | ̨ɽ| | Ȫ| | | żҸ| ״| μԴ| | Ϫ| | | ֹ| | ˳| Ϫ| | | ½| | | | | ƽ| ͩ|