<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5424291963003436578</id><updated>2012-02-17T09:44:12.721+08:00</updated><category term='ME'/><category term='Games'/><category term='MVC'/><category term='Java'/><category term='网络'/><title type='text'>Java Me Games</title><subtitle type='html'>Java 我 游戏</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nileblack.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nileblack.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Nile Black</name><uri>http://www.blogger.com/profile/03960767691354452512</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5424291963003436578.post-4684107487455558628</id><published>2007-04-02T12:26:00.000+08:00</published><updated>2007-04-02T12:26:20.776+08:00</updated><title type='text'>几个小故事</title><content type='html'>&lt;img id="BLOGGER_PHOTO_ID_" style="CLEAR: both; FLOAT: left" alt="" src="http://bp3.blogger.com/_t2QVaGGlWQg/RhCF62cSVXI/AAAAAAAAAgs/eBQT1PfRjYc/s160/story.JPG" border="0" /&gt;一.後生可畏&lt;br /&gt;小男孩问爸爸：“是不是做父亲的总比做儿子的知道得多？” 　　&lt;br /&gt;爸爸回答：“当然啦！” 　　&lt;br /&gt;小男孩问：“电灯是谁发明的？” 　　&lt;br /&gt;爸爸：“是爱迪生。” 　　&lt;br /&gt;小男孩又问：“那爱迪生的爸爸怎麽没有发明电灯？” 　　&lt;br /&gt;（很奇怪，喜欢倚老卖老的人，特别容易栽跟斗。权威往往只是一个经不起考验的空壳子，尤其在现今这个多元开放的时代。）&lt;br /&gt;二.不必紧张&lt;br /&gt;小明洗澡时不小心吞下一小块肥皂，他的妈妈慌慌张张地打电话向家庭医生求助。&lt;br /&gt;医生说：“我现在还有几个病人在，可能要半小时後才能赶过去。” 　　&lt;br /&gt;小明妈妈说：“在你来之前，我该做甚麽？” 　　&lt;br /&gt;医生说：“给小明喝一杯白开水，然後用力跳一跳，你就可以让小明用嘴巴吹泡泡消磨时间了。” 　　&lt;br /&gt;（take it easy，放轻松放轻松些，生活何必太紧张？事情既然已经发生了，何不坦然自在的面对。担心不如宽心，穷紧张不如穷开心。）&lt;br /&gt;三.钥匙&lt;br /&gt;一把坚实的大锁挂在大门上，一根铁杆费了九牛二虎之力，还是无法将它撬开。钥匙来了，他瘦小的身子钻进锁孔，只轻轻一转，大锁就“啪”地一声打开了。 　　&lt;br /&gt;铁杆奇怪地问：“为什麽我费了那麽大力气也打不开，而你却轻而易举地就把它打开了呢？” 　　&lt;br /&gt;钥匙说：“因为我最了解他的心。” 　　&lt;br /&gt;（每个人的心，都像上了锁的大门，任你再粗的铁棒也撬不开。唯有关怀，才能把自己变成一只细腻的钥匙，进入别人的心中，了解别人。）&lt;br /&gt;四.理由充份&lt;br /&gt;一辆载满乘客的公共汽车沿着下坡路快速前进着，有一个人後面紧紧地追赶着这辆车子。&lt;br /&gt;一个乘客从车窗中伸出头来对追车子的人说：“老兄！算啦，你追不上的！”&lt;br /&gt;“我必须追上它，”这人气喘吁吁地说：“我是这辆车的司机！” 　　&lt;br /&gt;(注：有些人必须非常认真努力，因为不这样的话，後果就十分悲惨了！然而也正因为必须全力以赴，潜在的本能和不为人知的特质终将充份展现出来。）&lt;div style='clear:both; text-align:LEFT'&gt;&lt;a href='http://picasa.google.com/blogger/' target='ext'&gt;&lt;img src='http://photos1.blogger.com/pbp.gif' alt='Posted by Picasa' style='border: 0px none ; padding: 0px; background: transparent none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;' align='middle' border='0' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Java Me Games&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5424291963003436578-4684107487455558628?l=nileblack.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nileblack.blogspot.com/feeds/4684107487455558628/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5424291963003436578&amp;postID=4684107487455558628' title='1 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/4684107487455558628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/4684107487455558628'/><link rel='alternate' type='text/html' href='http://nileblack.blogspot.com/2007/04/blog-post.html' title='几个小故事'/><author><name>Nile Black</name><uri>http://www.blogger.com/profile/03960767691354452512</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_t2QVaGGlWQg/RhCF62cSVXI/AAAAAAAAAgs/eBQT1PfRjYc/s72-c/story.JPG' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5424291963003436578.post-2945486865786193761</id><published>2007-03-24T09:26:00.000+08:00</published><updated>2007-03-24T09:33:21.126+08:00</updated><title type='text'>John W. Backus, Fortran语言的发明者逝世，享年82</title><content type='html'>&lt;h1&gt;&lt;a href="http://www.nytimes.com/2007/03/19/obituaries/20cnd-backus.html?ex=1332043200&amp;en=adde3ee5a1875330&amp;amp;ei=5124&amp;partner=permalink&amp;amp;exprod=permalink"&gt; John W. Backus, 82, Fortran Developer, Dies&lt;/a&gt;&lt;/h1&gt;&lt;div class="blogger-post-footer"&gt;Java Me Games&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5424291963003436578-2945486865786193761?l=nileblack.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nileblack.blogspot.com/feeds/2945486865786193761/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5424291963003436578&amp;postID=2945486865786193761' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/2945486865786193761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/2945486865786193761'/><link rel='alternate' type='text/html' href='http://nileblack.blogspot.com/2007/03/john-w-backus-fortran82.html' title='John W. Backus, Fortran语言的发明者逝世，享年82'/><author><name>Nile Black</name><uri>http://www.blogger.com/profile/03960767691354452512</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5424291963003436578.post-3093773484898352705</id><published>2007-03-22T23:13:00.000+08:00</published><updated>2007-03-22T23:14:02.608+08:00</updated><title type='text'>元宵猪</title><content type='html'>&lt;div style="TEXT-ALIGN: center"&gt;&lt;a href="http://bp0.blogger.com/_t2QVaGGlWQg/RgKdOmqaORI/AAAAAAAAAgk/NG29EbWfP8c/s1600-h/IMG_0006.JPG"&gt;&lt;img id="BLOGGER_PHOTO_ID_" alt="" src="http://bp0.blogger.com/_t2QVaGGlWQg/RgKdOmqaORI/AAAAAAAAAgk/NG29EbWfP8c/s400/IMG_0006.JPG" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;看看今年元宵留下的照片，贴一个！&lt;br /&gt;&lt;strong&gt;&lt;span style="color:#ff0000;"&gt;猪啊&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div style='clear:both; text-align:CENTER'&gt;&lt;a href='http://picasa.google.com/blogger/' target='ext'&gt;&lt;img src='http://photos1.blogger.com/pbp.gif' alt='Posted by Picasa' style='border: 0px none ; padding: 0px; background: transparent none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;' align='middle' border='0' /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Java Me Games&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5424291963003436578-3093773484898352705?l=nileblack.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nileblack.blogspot.com/feeds/3093773484898352705/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5424291963003436578&amp;postID=3093773484898352705' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/3093773484898352705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/3093773484898352705'/><link rel='alternate' type='text/html' href='http://nileblack.blogspot.com/2007/03/blog-post_22.html' title='元宵猪'/><author><name>Nile Black</name><uri>http://www.blogger.com/profile/03960767691354452512</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_t2QVaGGlWQg/RgKdOmqaORI/AAAAAAAAAgk/NG29EbWfP8c/s72-c/IMG_0006.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5424291963003436578.post-8554346105913403550</id><published>2007-03-10T10:58:00.000+08:00</published><updated>2007-03-10T20:30:07.266+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>java中的MVC设计</title><content type='html'>&lt;strong&gt;什么是MVC&lt;/strong&gt;&lt;br /&gt;什么是MVC，MVC是Trygve Reenskaug(一个SmallTalk)在1979年提出的一种分离数据和界面的模式。由三个部分组成&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Model(模型)：存储数据和规则，通常模型更接近现实模型&lt;/li&gt;&lt;br /&gt;&lt;li&gt;View(视图)：模型的展示，它描述模型数据应该如何被展示，假如模型发生变化，视图也要相应的变化。通常有“推模式”和“拉模式”，推模式是注册到视图上的模型会通知数据发生变化，更新相应的视图；而拉模式中视图会在需要的时候重新获取模型中的数据。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Control(控制器)：控制器会根据视图上用户的交互调用相应的动作执行。在一个独立的GUI程序中，可能这些交互就是按钮按下，滚动条拖动，在Web应用中，可能就是GET/POST的请求，控制器也能控制转换到新的视图。&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;strong&gt;传统的MVC结构&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://bp3.blogger.com/_t2QVaGGlWQg/RfGHvOaw8DI/AAAAAAAAAc0/T-nn-HkRRTg/s1600-h/Figure1.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_" style="clear: both; float: left;" alt="" src="http://bp3.blogger.com/_t2QVaGGlWQg/RfGHvOaw8DI/AAAAAAAAAc0/T-nn-HkRRTg/s160/Figure1.jpg" border="0" /&gt;&lt;/a&gt;当然不同的MVC结构会让M,V,C三者间有不同的交互，第一个图就是&lt;a href="http://java.sun.com/blueprints/guidelines/designing_enterprise_applications_2e/app-arch/app-arch2.html"&gt;Sun BluePrints Catalog&lt;/a&gt;中提到的一个通用的结构。下边我们进一步分析一下SUN模式的MVC。当M,V,C三者构造时会发生以下一些动作：&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt; 视图会注册一个监听器到模型，模型所有的改变都会通知所有的监听器，视图也能收到。这就是前边提到的推模式，当然，模型并不关心监听器是来自视图还是控制器，它只是简单的通知所有监听器。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;控制器绑在(be bound to)视图上，视图上的任何交互都会调用执行控制器注册的一个监听器。&lt;/li&gt;&lt;li&gt;控制器有保存一个模型的引用，用来更新操作模型。&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;假如一个交互事件发生时候，会发生以下的动作：&lt;a href="http://bp0.blogger.com/_t2QVaGGlWQg/RfGHveaw8EI/AAAAAAAAAc8/LuEx-D-Zlt0/s1600-h/Figure2.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_" style="clear: both; float: left;" alt="" src="http://bp0.blogger.com/_t2QVaGGlWQg/RfGHveaw8EI/AAAAAAAAAc8/LuEx-D-Zlt0/s160/Figure2.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;视图辨认出什么样的交互发生－比如按钮按下、滚动条拖动，相应的调用控制器注册的监听器执行。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;视图调用相应的监听器执行。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;控制器调用模型，通过合适的方法更新模型数据。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;数据模型发生变化，通知注册的监听器，比如视图。在其他一些结构中，控制器会负责更新视图。在Java的企业应用中常用到这一方法。&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;在这个图二中展示更详细调用过程。&lt;br /&gt;&lt;a href="http://bp0.blogger.com/_t2QVaGGlWQg/RfGHveaw8FI/AAAAAAAAAdE/zo7VsmGodfs/s1600-h/Figure3.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_" style="clear: both; float: left;" alt="" src="http://bp0.blogger.com/_t2QVaGGlWQg/RfGHveaw8FI/AAAAAAAAAdE/zo7VsmGodfs/s160/Figure3.jpg" border="0" /&gt;&lt;/a&gt; 正如前面所提到的，模型并不保存视图的引用，而是用模型变更事件通知，这样的一个好处就是一个模型能有多个视图，在模型变化的时候每一个视图都会得到更新，左图就表示了这么一个过程。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;修改的MVC结构&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://bp1.blogger.com/_t2QVaGGlWQg/RfGHvuaw8GI/AAAAAAAAAdM/TCsSq_wZ8Fk/s1600-h/Figure4.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_" style="clear: both; float: left;" alt="" src="http://bp1.blogger.com/_t2QVaGGlWQg/RfGHvuaw8GI/AAAAAAAAAdM/TCsSq_wZ8Fk/s160/Figure4.jpg" border="0" /&gt;&lt;/a&gt;在现代的一些MVC结构中， 把控制器放在模型和视图中间。和传统的结构的最大的区别就是模型的改变是通过控制器转到视图的，控制器协调了视图-&gt;模型和数据-&gt;视图的双向的通信。视图的事件通过控制器来更新模型，模型的更新也通过控制器转到视图。所以在三者构造的时候，模型和视图都注册到控制器，当视图发生交互事件的时候发生的过程几乎是一样的。&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;视图辨认出什么样的事件发生。对应的监听器调用。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;视图调用控制器注册的监听器。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;控制器访问模型，更新模型数据。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;数据发生变化，通知监听器，不一样的是这次的监听器是来自控制器的。&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;为什么要做这样的修改设计？这样的设计更好的分离了模型和视图，允许多个模型注册到一个控制器，控制器可以从多个模型中获取数据，和传统的一样，它也提供了同一个模型多个视图的办法。&lt;br /&gt;&lt;strong&gt;使用修改后的MVC结构&lt;/strong&gt;&lt;br /&gt;   都说事件是最好的老师，这一章节一起来把这中MVC结构事件一下。&lt;br /&gt;设想为了显示一段需要五个属性控制的文字。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;代码片断 一：&lt;br /&gt;public class TextElementModel extends AbstractModel{&lt;br /&gt;private String text;&lt;br /&gt;private Font font;&lt;br /&gt;private Integer x;&lt;br /&gt;private Integer y;&lt;br /&gt;private Integer opacity;&lt;br /&gt;private Integer rotation;&lt;br /&gt;/**&lt;br /&gt;* Provides the means to set or reset the model to&lt;br /&gt;* a default state&lt;br /&gt;*/&lt;br /&gt;public void initDefault() {&lt;br /&gt;setOpacity(89);&lt;br /&gt;setRotation(0);&lt;br /&gt;setText("Sample Text");&lt;br /&gt;setFont(new Font("Arial", Font.BOLD, 24));&lt;br /&gt;setX(50);&lt;br /&gt;setY(50);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;//  Accessors&lt;br /&gt;public String getText() {&lt;br /&gt;return text;&lt;br /&gt;}&lt;br /&gt;public void setText(String text) {&lt;br /&gt;String oldText = this.text;&lt;br /&gt;this.text = text;&lt;br /&gt;firePropertyChange(&lt;br /&gt; DefaultController.ELEMENT_TEXT_PROPERTY,&lt;br /&gt; oldText, text);&lt;br /&gt;}&lt;br /&gt;public Font getFont() {&lt;br /&gt;return font;&lt;br /&gt;}&lt;br /&gt;public void setFont(Font font) {&lt;br /&gt;Font oldFont = this.font;&lt;br /&gt;this.font = font;&lt;br /&gt;firePropertyChange(&lt;br /&gt; DefaultController.ELEMENT_FONT_PROPERTY,&lt;br /&gt; oldFont, font);&lt;br /&gt;}&lt;br /&gt;//  The remaining accessors for properties are omitted.&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;代码片断 二：&lt;br /&gt;public abstract class AbstractModel{&lt;br /&gt;  protected PropertyChangeSupport propertyChangeSupport;&lt;br /&gt;  public AbstractModel(){&lt;br /&gt;  propertyChangeSupport = new PropertyChangeSupport(this);&lt;br /&gt;  }&lt;br /&gt;  public void addPropertyChangeListener(PropertyChangeListener listener) {&lt;br /&gt;  propertyChangeSupport.addPropertyChangeListener(listener);&lt;br /&gt;  }&lt;br /&gt;  public void removePropertyChangeListener(PropertyChangeListener listener) {&lt;br /&gt;  propertyChangeSupport.removePropertyChangeListener(listener);&lt;br /&gt;  }&lt;br /&gt;  protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {&lt;br /&gt;  propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;代码片断 三：&lt;br /&gt;public abstract class AbstractController implements PropertyChangeListener {&lt;br /&gt; private ArrayList&lt;abstractviewpanel&gt; registeredViews;&lt;br /&gt; private ArrayList&lt;abstractmodel&gt; registeredModels;&lt;br /&gt; public AbstractController() {&lt;br /&gt;   registeredViews = new ArrayList&lt;abstractviewpanel&gt;();&lt;br /&gt;   registeredModels = new ArrayList&lt;abstractmodel&gt;();&lt;br /&gt; }&lt;br /&gt; public void addModel(AbstractModel model) {&lt;br /&gt;   registeredModels.add(model); &lt;br /&gt;   model.addPropertyChangeListener(this);&lt;br /&gt; }&lt;br /&gt; public void removeModel(AbstractModel model) {&lt;br /&gt;   registeredModels.remove(model);&lt;br /&gt;   model.removePropertyChangeListener(this);&lt;br /&gt; }&lt;br /&gt; public void addView(AbstractViewPanel view) {&lt;br /&gt;   registeredViews.add&lt;/abstractmodel&gt;&lt;/abstractviewpanel&gt;&lt;/abstractmodel&gt;&lt;/abstractviewpanel&gt;&lt;abstractviewpanel&gt;&lt;abstractmodel&gt;&lt;abstractviewpanel&gt;&lt;abstractmodel&gt;(view);&lt;br /&gt; }&lt;br /&gt; public void removeView(AbstractViewPanel view) {&lt;br /&gt;   registeredViews.remove(view);&lt;br /&gt; }&lt;br /&gt; //  Use this to observe property changes from registered models&lt;br /&gt; //  and propagate them on to all the views.&lt;br /&gt; public void propertyChange(PropertyChangeEvent evt) {&lt;br /&gt;   for (AbstractViewPanel view: registeredViews) {&lt;br /&gt;     view.modelPropertyChange(evt); &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;/**&lt;br /&gt;* This is a convenience method that subclasses can call upon&lt;br /&gt;* to fire property changes back to the models. This method&lt;br /&gt;* uses reflection to inspect each of the model classes&lt;br /&gt;* to determine whether it is&lt;/abstractmodel&gt;&lt;/abstractviewpanel&gt;&lt;/abstractmodel&gt;&lt;/abstractviewpanel&gt;&lt;abstractviewpanel&gt;&lt;abstractmodel&gt;&lt;abstractviewpanel&gt;&lt;abstractmodel&gt; the owner of the property&lt;br /&gt;* in question. If it isn't, a NoSuchMethodException is thrown,&lt;br /&gt;* which the method ignores.&lt;br /&gt;*&lt;br /&gt;* @param propertyName = The name of the property.&lt;br /&gt;* @param newValue = An object that represents the new value&lt;br /&gt;* of the property.&lt;br /&gt;*/&lt;br /&gt;protected void setModelProperty(String propertyName, Object newValue) {&lt;br /&gt;for (AbstractModel model: registeredModels) {&lt;br /&gt;try {         &lt;br /&gt;Method method = model.getClass().             &lt;br /&gt;getMethod("set"+propertyName, new Class[] {&lt;br /&gt;newValue.getClass()&lt;br /&gt;});&lt;br /&gt;method.invoke(model, newValue);&lt;br /&gt;} catch (Exception ex) {&lt;br /&gt;      //  Handle exception.     &lt;br /&gt;} &lt;br /&gt;}  &lt;/abstractmodel&gt;&lt;/abstractviewpanel&gt;&lt;/abstractmodel&gt;&lt;/abstractviewpanel&gt;&lt;br /&gt;&lt;abstractviewpanel&gt;&lt;abstractmodel&gt;&lt;abstractviewpanel&gt;&lt;abstractmodel&gt;}&lt;br /&gt;} &lt;/abstractmodel&gt;&lt;/abstractviewpanel&gt;&lt;/abstractmodel&gt;&lt;/abstractviewpanel&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;控制器中有两个ArrayList分别用来保存注册的模型和视图。不论何时一个模型注册，控制器也同时把自己注册到模型来监听模型变化。在最后一个方法setModelProperty中用到了一些java反射的操作，是为了把控制器和模型完全分离开来。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;代码片断 四&lt;br /&gt;public class DefaultController extends AbstractController&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;public static final String ELEMENT_TEXT_PROPERTY = "Text";&lt;br /&gt;public static final String ELEMENT_FONT_PROPERTY = "Font";&lt;br /&gt;public static final String ELEMENT_X_PROPERTY = "X";&lt;br /&gt;public static final String ELEMENT_Y_PROPERTY = "Y";&lt;br /&gt;public static final String ELEMENT_OPACITY_PROPERTY = "Opacity";&lt;br /&gt;public static final String ELEMENT_ROTATION_PROPERTY = "Rotation";&lt;br /&gt;&lt;br /&gt;//  Code omitted&lt;br /&gt;&lt;br /&gt;public void changeElementText(String newText) {&lt;br /&gt; setModelProperty(ELEMENT_TEXT_PROPERTY, newText);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void changeElementFont(Font newFont) {&lt;br /&gt; setModelProperty(ELEMENT_FONT_PROPERTY, newFont);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void changeElementXPosition(int newX) {&lt;br /&gt; setModelProperty(ELEMENT_X_PROPERTY, newX);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void changeElementYPosition(int newY) {&lt;br /&gt; setModelProperty(ELEMENT_Y_PROPERTY, newY);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void changeElementOpacity(int newOpacity) {&lt;br /&gt; setModelProperty(ELEMENT_OPACITY_PROPERTY, newOpacity);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public void changeElementRotation(int newRotation) {&lt;br /&gt; setModelProperty(ELEMENT_ROTATION_PROPERTY, newRotation);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;视图部分&lt;/strong&gt;&lt;br /&gt;这里视图部分有两个，可以用&lt;a href="http://www.netbeans.org/"&gt;Netbeans&lt;/a&gt;来创建，一个是属性配置的方式，一种是格式化显示。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;代码片断 五&lt;br /&gt;public PropertiesViewPanel(DefaultController controller) {&lt;br /&gt; this.controller = controller;&lt;br /&gt; initComponents();&lt;br /&gt; localInitialization();&lt;br /&gt;}&lt;br /&gt;/**&lt;br /&gt;* Used to provide local initialization of Swing components&lt;br /&gt;* outside of the NetBeans automatic code generator&lt;br /&gt;*/&lt;br /&gt;public void localInitialization() {&lt;br /&gt; opacitySpinner.setModel(new SpinnerNumberModel(100, 0, 100, 1));&lt;br /&gt; opacitySlider.setModel(new DefaultBoundedRangeModel(100, 0, 0, 100));&lt;br /&gt; rotationSpinner.setModel(new SpinnerNumberModel(0, -180, 180, 1));&lt;br /&gt; rotationSlider.setModel(new DefaultBoundedRangeModel(0, 0, -180, 180));&lt;br /&gt; text.getDocument().addDocumentListener(new DocumentListener() {&lt;br /&gt;     public void insertUpdate(DocumentEvent e) {&lt;br /&gt;         textDocumentChanged(e);&lt;br /&gt;     }&lt;br /&gt;     public void removeUpdate(DocumentEvent e) {&lt;br /&gt;         textDocumentChanged(e);&lt;br /&gt;     }&lt;br /&gt;     public void changedUpdate(DocumentEvent e) {&lt;br /&gt;         textDocumentChanged(e);&lt;br /&gt;     }&lt;br /&gt; });&lt;br /&gt;}&lt;br /&gt;public void modelPropertyChange(final PropertyChangeEvent evt) {&lt;br /&gt; if (evt.getPropertyName().equals(&lt;br /&gt;            DefaultController.ELEMENT_X_PROPERTY)) {&lt;br /&gt;     String newStringValue = evt.getNewValue().toString();&lt;br /&gt;     xPositionTextField.setText(newStringValue);&lt;br /&gt; } else if&lt;br /&gt;    (evt.getPropertyName().equals(&lt;br /&gt;            DefaultController.ELEMENT_Y_PROPERTY)) {&lt;br /&gt;     String newStringValue = evt.getNewValue().toString();&lt;br /&gt;     yPositionTextField.setText(newStringValue);&lt;br /&gt; } else if&lt;br /&gt;    (evt.getPropertyName().equals(&lt;br /&gt;            DefaultController.ELEMENT_OPACITY_PROPERTY)) {&lt;br /&gt;     int newIntegerValue = (Integer)evt.getNewValue();&lt;br /&gt;     opacitySpinner.setValue(newIntegerValue);&lt;br /&gt;     opacitySlider.setValue(newIntegerValue);&lt;br /&gt; } else if&lt;br /&gt;     (evt.getPropertyName().equals(&lt;br /&gt;            DefaultController.ELEMENT_ROTATION_PROPERTY)) {&lt;br /&gt;     int newIntegerValue = (Integer)evt.getNewValue();&lt;br /&gt;     rotationSpinner.setValue(newIntegerValue);&lt;br /&gt;     rotationSlider.setValue(newIntegerValue);&lt;br /&gt; } else if&lt;br /&gt;    (evt.getPropertyName().equals(&lt;br /&gt;            DefaultController.ELEMENT_TEXT_PROPERTY)) {&lt;br /&gt;     String newStringValue = evt.getNewValue().toString();&lt;br /&gt;     text.setText(newStringValue);&lt;br /&gt; } else if&lt;br /&gt;    (evt.getPropertyName().equals(&lt;br /&gt;            DefaultController.ELEMENT_FONT_PROPERTY)) {&lt;br /&gt;     Font f = (Font)evt.getNewValue();&lt;br /&gt;     String fontString = f.getFontName() + " " + f.getSize();&lt;br /&gt;     font.setText(fontString);&lt;br /&gt;     currentFont = f;&lt;br /&gt; }&lt;br /&gt; //  Remainder of the code omitted&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;代码片断 六&lt;br /&gt;//  Code omitted&lt;br /&gt;private void yPositionTextFieldFocusLost(java.awt.event.FocusEvent evt) {&lt;br /&gt; try {&lt;br /&gt;     controller.changeElementYPosition(&lt;br /&gt;         Integer.parseInt(yPositionTextField.getText()));&lt;br /&gt; } catch (Exception e) {&lt;br /&gt;     //  Handle exception.&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;private void yPositionTextFieldActionPerformed(java.awt.event.ActionEvent evt) {&lt;br /&gt; try {&lt;br /&gt;     controller.changeElementYPosition(&lt;br /&gt;         Integer.parseInt(yPositionTextField.getText()));&lt;br /&gt; } catch (Exception e) {&lt;br /&gt;     //  Handle exception.&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;//  Code omitted -- code for xPosition&lt;br /&gt;//  is nearly the same as for yPosition.&lt;br /&gt;private void changeFontButtonActionPerformed(java.awt.event.ActionEvent evt) {&lt;br /&gt; JFontChooserDialog fontChooser = new&lt;br /&gt;     JFontChooserDialog((Dialog)this.getTopLevelAncestor());&lt;br /&gt; fontChooser.setSelectedFont(currentFont);&lt;br /&gt; fontChooser.setVisible(true);&lt;br /&gt; Font returnedFont = fontChooser.getSelectedFont();&lt;br /&gt; if (returnedFont != null) {&lt;br /&gt;     controller.changeElementFont(returnedFont);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;private void opacitySliderStateChanged(javax.swing.event.ChangeEvent evt) {&lt;br /&gt; controller.changeElementOpacity((int)opacitySlider.getValue());&lt;br /&gt;}&lt;br /&gt;private void rotationSliderStateChanged(javax.swing.event.ChangeEvent evt) {&lt;br /&gt; controller.changeElementRotation((int)rotationSlider.getValue());&lt;br /&gt;}&lt;br /&gt;private void opacitySpinnerStateChanged(javax.swing.event.ChangeEvent evt) {&lt;br /&gt; controller.changeElementOpacity((Integer)opacitySpinner.getValue());&lt;br /&gt;}&lt;br /&gt;private void rotationSpinnerStateChanged(javax.swing.event.ChangeEvent evt) {&lt;br /&gt; controller.changeElementRotation((Integer)rotationSpinner.getValue());&lt;br /&gt;}&lt;br /&gt;private void textDocumentChanged(DocumentEvent evt) {&lt;br /&gt; Document document = evt.getDocument();&lt;br /&gt; try {&lt;br /&gt;     controller.changeElementText(document.getText(0,&lt;br /&gt;     document.getLength()));&lt;br /&gt; } catch (BadLocationException ex) {&lt;br /&gt;     //  Handle exception.&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;程序中的问题&lt;/strong&gt;&lt;br /&gt;程序运行起来，你马上会发现这样的问题：&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;一旦视图接受到事件，真实的用户操作。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;控制器里面的对应的方法被调用。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;模型改变，通知控制器模型改变。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;视图接收到模型改变事件，更新相应的组件，设置正确的值。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;视图改变，控制器相应的方法又被调用，模型又开始更新。&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;这种情况下有三种处理方式可以使用：&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;视图组件在通知更新的时候拒绝任何的更新。这种方式主要用在文本组件里面。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;第二种方式是模型检查数据是否有变化，新的值和原来的值是一样的就不再发变更通知。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;假如在视图和模型都没有检查，那么程序进入无限循环。&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;发生这些问题是因为Swing组件是自主的，举个例子，当用户按了JSpinner中的上箭头，JSpinner的数值+1,然后监听器被调用，模型更新。&lt;br /&gt;在传统的模式中，视图仍然是上一个值的数据，依赖于模型的更新来把视图更新到正确的数值来。尽管如此，还是没有必要更新Swing组件，因为Swing组件已经把自己设置成正确的值了，甚至在视图更新事件发出之前就完成 了。&lt;br /&gt;那么如何来规避这样的事件呢，一种机制是让模型或是控制器不要传播这样的更新事件，但这不是一个好的办法。有可能有多个视图在监听这样的事件。假如关闭了这样的传播，就会导致其他的视图得不到更新。&lt;br /&gt;理想的每一个视图组件都应该关系当前的值和新付的值，假如没有改变，就不发送通知。当然有些Swing组件已经包含了这样的逻辑，也有一些没有。有个办法来对付模型检查的，在设置模型的值的时候，检查一下新的值和老的值是否一样，假如是相同的就忽略这样的通知。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;代码片断 七&lt;br /&gt;public void modelPropertyChange(final PropertyChangeEvent evt) {&lt;br /&gt;  if (evt.getPropertyName().equals(DefaultController.ELEMENT_X_PROPERTY)) {&lt;br /&gt;      String newStringValue = evt.getNewValue().toString();&lt;br /&gt;      if (!xPositionTextField.getText().equals(newStringValue))&lt;br /&gt;          xPositionTextField.setText(newStringValue);&lt;br /&gt;  }&lt;br /&gt;  //  Remaining code omitted&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_t2QVaGGlWQg/RfGXEeaw8HI/AAAAAAAAAdU/ev1rwxwS7ho/s1600-h/Figure5.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://bp0.blogger.com/_t2QVaGGlWQg/RfGXEeaw8HI/AAAAAAAAAdU/ev1rwxwS7ho/s320/Figure5.gif" alt="" id="BLOGGER_PHOTO_ID_5039975561144889458" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;图是最后运行的结果。&lt;div class="blogger-post-footer"&gt;Java Me Games&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5424291963003436578-8554346105913403550?l=nileblack.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nileblack.blogspot.com/feeds/8554346105913403550/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5424291963003436578&amp;postID=8554346105913403550' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/8554346105913403550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/8554346105913403550'/><link rel='alternate' type='text/html' href='http://nileblack.blogspot.com/2007/03/javamvc.html' title='java中的MVC设计'/><author><name>Nile Black</name><uri>http://www.blogger.com/profile/03960767691354452512</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_t2QVaGGlWQg/RfGHvOaw8DI/AAAAAAAAAc0/T-nn-HkRRTg/s72-c/Figure1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5424291963003436578.post-8495074260449705628</id><published>2007-03-09T23:01:00.000+08:00</published><updated>2007-03-10T20:28:10.619+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Games'/><title type='text'>Second Life照片</title><content type='html'>&lt;a href="http://bp2.blogger.com/_t2QVaGGlWQg/RfF2z-aw8CI/AAAAAAAAAcs/iL6_mnQeQnM/s1600-h/secondlife-postcard.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_" style="clear: both; float: left;" alt="" src="http://bp2.blogger.com/_t2QVaGGlWQg/RfF2z-aw8CI/AAAAAAAAAcs/iL6_mnQeQnM/s160/secondlife-postcard.jpg" border="0" /&gt;&lt;/a&gt;  有几个朋友在玩Second Life的游戏。我也去看了看。发现这是一种全新的虚拟人生的游戏，人与人之间交流，可以用你的知识和能力为别人工作，帮人写脚本，盖楼。也有雇佣，你可以获得相应的报酬。&lt;br /&gt;可惜我的机器太慢了，一步一顿的，很是不爽。&lt;br /&gt;还有他们那些不知道到什么语言的英语，我这个教科书的英语无法跟上节奏了。于是还是回来逛论坛了。&lt;div style="clear: both; text-align: left;"&gt;&lt;a href="http://picasa.google.com/blogger/" target="ext"&gt;&lt;img src="http://photos1.blogger.com/pbp.gif" alt="Posted by Picasa" style="border: 0px none ; padding: 0px; background: transparent none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" align="middle" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Java Me Games&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5424291963003436578-8495074260449705628?l=nileblack.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nileblack.blogspot.com/feeds/8495074260449705628/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5424291963003436578&amp;postID=8495074260449705628' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/8495074260449705628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/8495074260449705628'/><link rel='alternate' type='text/html' href='http://nileblack.blogspot.com/2007/03/second-life.html' title='Second Life照片'/><author><name>Nile Black</name><uri>http://www.blogger.com/profile/03960767691354452512</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_t2QVaGGlWQg/RfF2z-aw8CI/AAAAAAAAAcs/iL6_mnQeQnM/s72-c/secondlife-postcard.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5424291963003436578.post-4616307045774752902</id><published>2007-03-08T23:24:00.000+08:00</published><updated>2007-03-10T20:29:14.639+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ME'/><title type='text'>Blogger开户了</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;a href="http://bp2.blogger.com/_t2QVaGGlWQg/RfAqr6RpdEI/AAAAAAAAAck/xehrWORk3gA/s1600-h/ant.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_" style="clear: none;" alt="" src="http://bp2.blogger.com/_t2QVaGGlWQg/RfAqr6RpdEI/AAAAAAAAAck/xehrWORk3gA/s400/ant.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;以前一直都在断断续续的写点豆腐渣，现在Google的股票换来的现金给我们带来了很多的方便，努力了，先贴一块。&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Java Me Games&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5424291963003436578-4616307045774752902?l=nileblack.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nileblack.blogspot.com/feeds/4616307045774752902/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5424291963003436578&amp;postID=4616307045774752902' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/4616307045774752902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/4616307045774752902'/><link rel='alternate' type='text/html' href='http://nileblack.blogspot.com/2007/03/blogger.html' title='Blogger开户了'/><author><name>Nile Black</name><uri>http://www.blogger.com/profile/03960767691354452512</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp2.blogger.com/_t2QVaGGlWQg/RfAqr6RpdEI/AAAAAAAAAck/xehrWORk3gA/s72-c/ant.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5424291963003436578.post-6609924554740142607</id><published>2007-03-08T20:32:00.001+08:00</published><updated>2009-04-27T13:08:31.759+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='网络'/><title type='text'>路由器如何工作－路由表</title><content type='html'>以前对于路由器总是似懂非懂的，今天花了点时间看看，在这里做一个记录。[摘自tcp/ip详解]&lt;div style="text-align: center;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_t2QVaGGlWQg/RfKnN-aw8KI/AAAAAAAAAds/8ioRBCXSIrY/s1600-h/network.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/_t2QVaGGlWQg/RfKnN-aw8KI/AAAAAAAAAds/8ioRBCXSIrY/s400/network.JPG" alt="" id="BLOGGER_PHOTO_ID_5040274791516401826" border="0" /&gt;&lt;/a&gt;基本的网络环境&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_t2QVaGGlWQg/RfKnHOaw8JI/AAAAAAAAAdk/PJfismsl85I/s1600-h/3-4.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_t2QVaGGlWQg/RfKnHOaw8JI/AAAAAAAAAdk/PJfismsl85I/s400/3-4.JPG" alt="" id="BLOGGER_PHOTO_ID_5040274675552284818" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p style="text-align: center;"&gt;包如何在网络上转发 参看tcp/ip协议详解第三章&lt;/p&gt;&lt;p style="text-align: left;"&gt;路由表&lt;/p&gt;&lt;p style="text-align: left;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_t2QVaGGlWQg/RfKnTuaw8LI/AAAAAAAAAd0/qWMuS9OSdOo/s1600-h/router-table-at-srv4.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_t2QVaGGlWQg/RfKnTuaw8LI/AAAAAAAAAd0/qWMuS9OSdOo/s400/router-table-at-srv4.JPG" alt="" id="BLOGGER_PHOTO_ID_5040274890300649650" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align: center;"&gt;srv4的路由表，详细参考tcp/ip协议详解第10章&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_t2QVaGGlWQg/RfKnbuaw8MI/AAAAAAAAAd8/12ozQyIPpMs/s1600-h/router-table-at-sun.JPG"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp2.blogger.com/_t2QVaGGlWQg/RfKnbuaw8MI/AAAAAAAAAd8/12ozQyIPpMs/s400/router-table-at-sun.JPG" alt="" id="BLOGGER_PHOTO_ID_5040275027739603138" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align: center;"&gt;sun的路由表，详细参考tcp/ip协议详解第10章&lt;/p&gt;&lt;p&gt;&lt;strong&gt;关于路由表的说明&lt;br /&gt;&lt;/strong&gt;对于一个给定的路由器，可以打印出五种不同的标志（ f l a g）：&lt;br /&gt;U 该路由可以使用。&lt;br /&gt;G 该路由是到一个网关（路由器）。如果没有设置该标志，说明目的地是直接相连的。&lt;br /&gt;H 该路由是到一个主机，也就是说，目的地址是一个完整的主机地址。如果没有设置该&lt;br /&gt;标志，说明该路由是到一个网络，而目的地址是一个网络地址：一个网络号，或者网&lt;br /&gt;络号与子网号的组合。&lt;br /&gt;D 该路由是由重定向报文创建的（ 9 . 5节）。&lt;br /&gt;M 该路由已被重定向报文修改（ 9 . 5节）。&lt;/p&gt; &lt;p&gt;&lt;br /&gt;路由表的搜索&lt;/p&gt; &lt;blockquote&gt; &lt;ol&gt;&lt;li&gt;搜索匹配的主机地址；&lt;/li&gt;&lt;li&gt; 搜索匹配的网络地址；&lt;/li&gt;&lt;li&gt; 搜索默认表项（默认表项一般在路由表中被指定为一个网络表项，其网络号为0）。&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;匹配主机地址步骤始终发生在匹配网络地址步骤之前。&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;&lt;br /&gt;关键的说明，需要仔细理解，可以多看几遍&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;标志G是非常重要的，因为由它区分了间接路由和直接路由（对于直接路由来说是不设置标志G的）。其区别在于，发往直接路由的分组中不但具有指明目的 端的I P地址，还具有其链路层地址（见图3 - 3）。当分组被发往一个间接路由时， I P地址指明的是最终的目的地，但是链路层地址指明的是网关（即下一站路由器）。我们在图3 - 4已看到这样的例子。在这个路由表例子中，有一个间接路由（设置了标志G），因此采用这一项路由的分组其I P地址是最终的目的地（1 4 0 . 2 5 2 . 1 3 . 6 5），但是其链路层地址必须对应于路由器1 4 0 . 2 5 2 . 1 3 . 3 5。&lt;br /&gt;理解G和H标志之间 的区别是很重要的。G标志区分了直接路由和间接路由，如上所述。但是H标志表明，目的地址（ n e t s t a t命令输出第一行）是一个完整的主机地址。没有设置H标志说明目的地址是一个网络地址（主机号部分为0）。当为某个目的I P地址搜索路由表时，主机地址项必须与目的地址完全匹配，而网络地址项只需要匹配目的地址的网络号和子网号就可以了。另外，大多数版本的n e t s t a t命令首先打印出所有的主机路由表项，然后才是网络路由表项。&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;不理解的一个问题&lt;/p&gt; &lt;p&gt;在sun的路由表上为什么会有140.252.1.183 140.252.1.29 uh 0 0 sl0这么一条路由，它什么时候有用呢？&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;Java Me Games&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5424291963003436578-6609924554740142607?l=nileblack.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nileblack.blogspot.com/feeds/6609924554740142607/comments/default' title='帖子评论'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5424291963003436578&amp;postID=6609924554740142607' title='0 条评论'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/6609924554740142607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5424291963003436578/posts/default/6609924554740142607'/><link rel='alternate' type='text/html' href='http://nileblack.blogspot.com/2007/03/blog-post.html' title='路由器如何工作－路由表'/><author><name>Nile Black</name><uri>http://www.blogger.com/profile/03960767691354452512</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_t2QVaGGlWQg/RfKnN-aw8KI/AAAAAAAAAds/8ioRBCXSIrY/s72-c/network.JPG' height='72' width='72'/><thr:total>0</thr:total></entry></feed>
