tag:blogger.com,1999:blog-11548844466672828152024-03-13T21:28:31.584-07:00微语小言何以解忧,唯有絮叨。Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.comBlogger23125tag:blogger.com,1999:blog-1154884446667282815.post-67579366180213948432014-12-16T18:29:00.000-08:002014-12-16T18:41:19.611-08:00VIM相关<div dir="ltr" style="text-align: left;" trbidi="on">
这两天一直在使用VIM,相关想法如下:<br />
<ul style="text-align: left;">
<li>并不难学</li>
<li>插件开发似乎也不是很难</li>
<li>不打算使用第三方的插件</li>
</ul>
<div>
要做的插件:</div>
<div>
<ul style="text-align: left;">
<li>括弧匹配检查</li>
<li>在括弧之间跳动,特别是花括弧。仅在“{”之间跳跃。</li>
<li><strike>在各种符号之间跳动。代码事实上是由符号和英文标识符组成,符号在代码中占有很大的一个比例,包括加减乘除、大于小于、与或非等、各种括弧、标点符号。</strike><b>此功能没有价值</b></li>
</ul>
<div>
<b>哲学与思索</b></div>
</div>
<div>
<br /></div>
<div>
做软件开发工作其实也有一定的年头了,自觉有些感悟,但是总是有一种欲说还休的感觉。但是说道这个工作中的一些事实,总是不会变得。引用别人说过的一句“Programmers shape ideas into text.”所以文本编辑其实就是一个根本。这一点和网络作家其实有些相似,我们都是码字的。</div>
<div>
<br /></div>
<div>
<b>卡顿</b></div>
<div>
<b><br /></b></div>
<div>
这个是绝对不允许的。</div>
<div>
<br /></div>
<div>
<b>tag跳转</b></div>
<div>
<br /></div>
<div>
tag跳转是很必要的,特别是在阅读别人的代码的时候。改别人的程序是很通常的一件事情。当然也是一件不幸的工作。</div>
<div>
<br /></div>
<div>
<b>代码补全</b></div>
<div>
<b><br /></b></div>
<div>
个人认为其实代码补全功能不是很重要。</div>
<div>
<br /></div>
<div>
<b>语法检查</b></div>
<div>
<br /></div>
<div>
对于一些动态的语言,这个其实不是非常的重要。对于Java之流似乎有些用处。个人认为不一定需要这个功能。</div>
<div>
<br /></div>
<div>
<b>语法高亮</b></div>
<div>
<br /></div>
<div>
这个必须得有,而且要很灵活,能够动态的高亮一些特殊需要的东西,具体想法还在形成中。</div>
<div>
<br /></div>
<div>
<b>括弧检查</b></div>
<div>
<br /></div>
<div>
这个其实还是有需要的。<br />
<br />
<b>插件</b><br />
<br />
VIM的一个很大的乐趣就是自己定制,所以不要去网上下别人的插件,尽可能的自己实现一些常用的功能。量身定制显然更高大上。而且在一个新的环境上也不会影响你的效率。</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
</div>
Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-66767617686219555942014-11-12T19:33:00.001-08:002014-11-12T19:33:53.940-08:00算法<div dir="ltr" style="text-align: left;" trbidi="on">
面向对象的解决方案和算法解决有很大的差别。从问题的理解和分析上也有所不同,我不知道哪个好,但是面向对象的方式的性能明显不是最优的。在解决实际问题上,我一向倾向于使用面向对象的方法来处理。但是显然使用面向对象的方式解决问题其性能的确是比较差的。而理解性也并非十分的好。唯一的优势在于多人分工的时候,比较容易解决分工合作的问题。<br />
<br />
而在面对算法问题的时候,还是需要考虑性能的。尽可能的使用高性能的处理方式,不要使用JAVA的集合类。使用最最基础的数组来进行处理。或者不要使用递归,而使用循环,递归的性能很差,尤其在JAVA语言中。</div>
Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-3618468937823149722014-08-14T20:41:00.000-07:002014-08-14T20:41:41.842-07:00Joana Zimmer Luky Star<div dir="ltr" style="text-align: left;" trbidi="on">
非常喜欢这首歌,旋律和歌词都很不错。不过其实英文歌的歌词是非常露骨的,非常直接。也许英文的表达就是这样,我其实不太关注英文的诗歌,因此也不太懂。这段时间决定去了解学习一下。<br />
<br />
下面是我的翻译。不是直译了。基本上是一种意译,像这样的艺术作品,直译是不可取的。而且也基本不可能。<br />
<br />
Can't you see you are<br />
the one I'm always thinking of<br />
为何你对我的思念视而不见<br />
<br />
In my Dreams you are already mine<br />
在我梦中,你早已和我相伴<br />
<br />
If you show me love<br />
I promise I'll be there for sure<br />
若你爱我,我将矢志不渝<br />
<br />
I would stay forever by your side<br />
我会日夜陪伴在你身畔<br />
<br />
Look at me now!<br />
看着我<br />
<br />
can't you see all the love in my eyes<br />
难道你读不出我眼中的痴情<br />
<br />
And will you give it a try<br />
难道你不曾被我打动<br />
<br />
Will you be my lucky star<br />
你是否会是那个带给我幸运的人<br />
<br />
Be the one to show me who you are<br />
你是否会是那个示我以真心的人<br />
<br />
will you guide me through the nights<br />
你是否会是那个带我穿越黑夜的人<br />
<br />
be my every shining light<br />
你是否会是那个带给我永远光明的人<br />
<br />
will you be my lucky star<br />
你是否会是那个能带给我幸运的人<br />
<br />
Be the one to show me who you are<br />
你是否会是那个能示我以真心的人<br />
<br />
cause I know this could be love<br />
shining on my heart<br />
因为我知道,这将会是照亮我心间的真爱<br />
<br />
wu m<br />
What if I would tell<br />
exactly how I feel for you<br />
如果我向你诉说我的一往情深<br />
<br />
would you run<br />
你是否会默默逃避<br />
<br />
Would you oh would you let me down<br />
你是否会让我忧伤失望<br />
<br />
look at me now<br />
看着我<br />
<br />
Will you give this love a try<br />
你是否会对我的爱视而不见<br />
<br />
I got nothing to hide<br />
我从不曾隐藏我对你的情感<br />
<br />
Will you be my lucky star<br />
你是否会是那个带给我幸运的人<br />
<br />
Be the one to show me who you are<br />
你是否会是那个示我以真心的人<br />
<br />
will you guide me through the nights<br />
你是否会是那个带我穿越黑夜的人<br />
<br />
be my every shining light<br />
你是否会是那个带给我永远光明的人<br />
<br />
will you be my lucky star<br />
你是否会是那个带给我幸运的人<br />
<br />
Be the one to show me who you are<br />
你是否会是那个示我以真心的人<br />
<br />
cause I know this could be love<br />
shining on my heart<br />
因为我知道,这将会是照亮我心间的真爱<br />
<br />
m<br />
ho ye<br />
<br />
Look at me now!<br />
看着我<br />
<br />
can't you see all the love in my eyes<br />
难道你读不出我眼中的痴情<br />
<br />
And will you give it a try<br />
难道你不曾被我打动<br />
<br />
Will you be my lucky star<br />
你是否会是那个带给我幸运的人<br />
<br />
Be the one to show me who you are<br />
你是否会是那个示我以真心的人<br />
<br />
will you guide me through the nights<br />
你是否会是那个带我穿越黑夜的人<br />
<br />
be my every shining light<br />
你是否会是那个带给我永远光明的人<br />
<br />
will you be my lucky star<br />
你是否会是那个能带给我幸运的人<br />
Be the one to show me who you are<br />
你是否会是那个能示我以真心的人<br />
<br />
cause I know this could be love<br />
shining on my heart<br />
因为我知道,这将会是照亮我心间的真爱<br />
<br />
不知道这样翻译对不对,反正也找不到可以交流的人。<br />
<br />
<br /></div>
Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-33961856517539147502014-04-29T18:58:00.000-07:002014-05-23T03:22:11.631-07:00开发与工具<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">今天在网上随便逛了一下,看了看一些人在osChina里面对于编程语言与技术的一些争论。让我有了一些想法。</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">其实我觉得编程技术的发展其实和人类社会在其他领域上技术的发展本质上来说没有大的区别。而技术的发展方向本质上来说是从效率和质量这两个方向上进化的,也就是说,新的技术总是能够带来更好的质量,或者更好的效率,不过使用起来可能会更复杂一些。而从根本上来说新技术总是依托在某种工具上来实现的。比如,现在在土木工程上面,随处可见的大大小小的工程机械,特别是挖掘机,大大小小,种类俱全。而挖掘机的工作实际上就是替代了铁锹和镐头。但是它使用起来要比铁锹和镐头要复杂很多。挖土这种工作显然,质量上很容易保证,但显而易见,挖土机的工作效率比人高多了。软件开发基本也是如此,我们和其他工业领域,没有本质上的差别。</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">开发技术的发展其方向大体上也基本等同于工具的发展,总是向利于高效的方向来发展的。因此我们也应该看到,技术在很大程度上不可能一成不变,发展与进步是一种必然。</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">软件开发一个有趣的地方在于,你所使用的语言和工具很大程度上也是一种材料,一旦你使用了某一种,就不太容易换另一种。所以现代的开发平台,大体上都允许你使用多种语言来开发,比如微软的开发平台,上面支持很多种语言。Java也是走的这个路线,Java平台上现在已经有很多的语言实现了。</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">人类,总是趋向于使用某种工具的。人类总是趋向于使用抽象的,易于理解的,高效的工具。开发也是一样。因此我趋向于应用规范标准的类库,而不是私有的类库。类库的维护成本是很高的,而且,我刚才简单论证过了,编程工具化的过程基本是无法避免的。无论是从组织要求上来说,还是从技术要求上来说,都是一样的。</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">抽象度高的代码,显然更容易让人理解,从而也容易维护。</span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;">说白了,就是因为人类本质上善于发现和认识,这也是人类的一个很基本的特征。所谓的知识往往就是人类识别出来的这些模式与认识的一种集合和积累,有的完善,有的不完善。在哲学上来说,我记得认识还有两次飞跃。<span style="border: 0px; color: #333333; line-height: 21px; margin: 0px; padding: 0px; text-indent: 29.46666717529297px;"><span style="border: 0px; line-height: 22px; margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px;"><b>从感性认识到理性认识的飞跃,从理性认识到实践的飞跃。</b>而开发工作其实就是在第二次飞跃上工作,也就是说理论在指导实践。</span></span></span></span><br />
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><span style="border: 0px; color: #333333; line-height: 21px; margin: 0px; padding: 0px; text-indent: 29.46666717529297px;"><span style="border: 0px; line-height: 22px; margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px;"><br /></span></span></span>
<span style="border: 0px; color: #333333; line-height: 21px; margin: 0px; padding: 0px; text-indent: 29.46666717529297px;"><span style="border: 0px; line-height: 22px; margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px;">总之语言的发展必然会不断的提高其抽象程度,和机器有关的细节会越来越少。另外也应该看到,这个过程不可能是一两个人或者几个公司能完成的,需要整个社会的共同努力。</span></span></span></span></div>
Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-68299927209461090292014-03-24T23:12:00.000-07:002014-03-24T23:20:34.822-07:00clojure调用javaFX知其然,不知其所以然,大概我就是这种人。不多说直接上代码:<br />
<br />
<!-- HTML generated using hilite.me --><br />
<div style="background: #111111; border-width: .1em .1em .1em .8em; border: solid gray; overflow: auto; padding: .2em .6em; width: auto;">
<table><tbody>
<tr><td><pre style="line-height: 125%; margin: 0;"> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23</pre>
</td><td><pre style="line-height: 125%; margin: 0;"><span style="color: white;">(</span><span style="color: #fb660a; font-weight: bold;">ns </span><span style="color: #fb660a;">myproject.core</span>
<span style="color: white;">(</span><span style="color: #ff0086; font-weight: bold;">javafx.embed.swing.JFXPanel.</span><span style="color: white;">)</span>
<span style="color: white;">(</span><span style="color: #0086d2;">:import</span> <span style="color: white;">[</span><span style="color: #fb660a;">javafx.application</span> <span style="color: #fb660a;">Application</span><span style="color: white;">]</span>
<span style="color: white;">[</span><span style="color: #fb660a;">javafx.event</span> <span style="color: #fb660a;">ActionEvent</span> <span style="color: #fb660a;">EventHandler</span><span style="color: white;">]</span>
<span style="color: white;">[</span><span style="color: #fb660a;">javafx.scene</span> <span style="color: #fb660a;">Scene</span><span style="color: white;">]</span>
<span style="color: white;">[</span><span style="color: #fb660a;">javafx.scene.layout</span> <span style="color: #fb660a;">VBox</span> <span style="color: #fb660a;">StackPane</span><span style="color: white;">]</span>
<span style="color: white;">[</span><span style="color: #fb660a;">javafx.stage</span> <span style="color: #fb660a;">Stage</span><span style="color: white;">]</span>
<span style="color: white;">[</span><span style="color: #fb660a;">javafx.scene.control</span> <span style="color: #fb660a;">Button</span><span style="color: white;">])</span>
<span style="color: white;">(</span><span style="color: #0086d2;">:gen-class</span> <span style="color: #0086d2;">:extends</span> <span style="color: #fb660a;">javafx.application.Application</span><span style="color: white;">)</span>
<span style="color: white;">)</span>
<span style="color: white;">(</span><span style="color: #fb660a; font-weight: bold;">defn </span><span style="color: #fb660a;">-start</span> <span style="color: white;">[</span><span style="color: #fb660a;">this</span> <span style="color: #fb660a;">stage</span><span style="color: white;">]</span>
<span style="color: white;">(</span><span style="color: #fb660a; font-weight: bold;">def </span><span style="color: #fb660a;">pane</span> <span style="color: white;">(</span><span style="color: #ff0086; font-weight: bold;">StackPane.</span><span style="color: white;">))</span>
<span style="color: white;">(</span><span style="color: #fb660a; font-weight: bold;">def </span><span style="color: #fb660a;">btn</span> <span style="color: white;">(</span><span style="color: #ff0086; font-weight: bold;">Button.</span> <span style="color: #0086d2;">"xxxx"</span><span style="color: white;">))</span>
<span style="color: white;">(</span><span style="color: #ff0086; font-weight: bold;">.setOnAction</span> <span style="color: #fb660a;">btn</span> <span style="color: white;">(proxy [</span><span style="color: #fb660a;">EventHandler</span><span style="color: white;">]</span> <span style="color: white;">[]</span> <span style="color: white;">(</span><span style="color: #ff0086; font-weight: bold;">handle</span> <span style="color: white;">[</span><span style="color: #fb660a;">event</span><span style="color: white;">]</span> <span style="color: white;">(println </span><span style="color: #0086d2;">"click"</span> <span style="color: #fb660a;">event</span><span style="color: white;">))))</span>
<span style="color: white;">(.. </span><span style="color: #fb660a;">pane</span> <span style="color: white;">(</span><span style="color: #ff0086; font-weight: bold;">getChildren</span><span style="color: white;">)</span> <span style="color: white;">(</span><span style="color: #ff0086; font-weight: bold;">add</span> <span style="color: #fb660a;">btn</span><span style="color: white;">))</span>
<span style="color: white;">(</span><span style="color: #fb660a; font-weight: bold;">def </span><span style="color: #fb660a;">scene</span> <span style="color: white;">(</span><span style="color: #ff0086; font-weight: bold;">Scene.</span> <span style="color: #fb660a;">pane</span> <span style="color: #0086f7; font-weight: bold;">300</span> <span style="color: #0086f7; font-weight: bold;">200</span><span style="color: white;">))</span>
<span style="color: white;">(doto </span><span style="color: #fb660a;">stage</span> <span style="color: white;">(</span><span style="color: #ff0086; font-weight: bold;">.setScene</span> <span style="color: #fb660a;">scene</span><span style="color: white;">)</span> <span style="color: white;">(</span><span style="color: #ff0086; font-weight: bold;">.setTitle</span> <span style="color: #0086d2;">"zxxxxz"</span><span style="color: white;">)</span> <span style="color: white;">(</span><span style="color: #ff0086; font-weight: bold;">.show</span><span style="color: white;">))</span>
<span style="color: white;">)</span>
<span style="color: white;">(</span><span style="color: #fb660a; font-weight: bold;">defn </span><span style="color: #fb660a;">-stop</span> <span style="color: white;">[</span><span style="color: #fb660a;">app</span><span style="color: white;">]</span>
<span style="color: white;">(println </span><span style="color: #0086d2;">"Exiting now"</span><span style="color: white;">))</span>
<span style="color: white;">(</span><span style="color: #ff0086; font-weight: bold;">Application/launch</span> <span style="color: #fb660a;">myproject.core</span> <span style="color: white;">(into-array </span><span style="color: #fb660a;">String</span> <span style="color: white;">[]))</span>
</pre>
</td></tr>
</tbody></table>
</div>
<br />
注意命名空间里面的:<span style="line-height: 16.25px;">(</span><span style="color: #0066bb; font-weight: bold; line-height: 16.25px;">javafx.embed.swing.JFXPanel.</span><span style="line-height: 16.25px;">);这句话非常重要,如果没有你会得到一个运行错误,说什么Toolkit如何如何。加上就好了。至于原因,over stack网站上似乎有解释,但是我是一个不求甚解的人,所以其实就是基于某些原因,普拉普拉普拉。</span><br />
<span style="line-height: 16.25px;"><br /></span>
<span style="line-height: 16.25px;">注意如果你使用的是intellij,注意配置:</span><br />
<span style="line-height: 16.25px;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzf3f8L2E9yGR7OtFDKKpd6gRVDTrJ524RaEgxU7zOI06Ac-5YM0_S7QjNy44wOE7HENe4HpmK846zIPMjc8bJsBgGSwpS0qoy3JFLcU7v0wKDNEkHClwdEpCrMqCIEhW7pwT65KtJKcu4/s1600/%E6%88%AA%E5%9B%BE01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzf3f8L2E9yGR7OtFDKKpd6gRVDTrJ524RaEgxU7zOI06Ac-5YM0_S7QjNy44wOE7HENe4HpmK846zIPMjc8bJsBgGSwpS0qoy3JFLcU7v0wKDNEkHClwdEpCrMqCIEhW7pwT65KtJKcu4/s1600/%E6%88%AA%E5%9B%BE01.jpg" height="230" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<span style="line-height: 16.25px;"><br /></span>Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-31685748415139084142014-02-27T18:10:00.004-08:002014-02-27T18:11:15.049-08:00Angular 组件在angular里面,指令其实和组件的意思是完全不同的,但是多数人并没有很好的区分它们。并把指令提升到了完全和组件相当的高度去了,这大大加剧了指令的编写难度。事实是指令和组件完全是两个概念。<br />
<br />
Angular的核心思想应该是以数据为中心的,但是方法是否应该是数据的一部分,这个问题还是值得商榷的。就算从比较纯的函数观点来看的话,完全无副作用的函数似乎也不应个视为与数据等同。Angular解决方法与数据间隔阂的方法其实就是通过事件完成的,说的更直白一点其实就是scope中的$watch方法。这个方法让我们得知了数据的变化,可用从容的对数据进行处理,并把视角从处理数据的方法上转回到数据本身上来。<br />
<br />
但是如果从数据的视角(也就是angular的视角)来看的话,组件就十分的复杂。因为组件会牵扯复杂的DOM变化,和相应的数据变化,这些数据变化可能十分的剧烈,而似乎这些数据的变化也可能并不需要知会angular所感知的数据模型部分(也就是scope)。因为组件从来都不是以数据为中心的,恰恰相反,组件往往就是来操作数据的,比如说增查删改。数据在组件这里往往都是从属的对象无法被视为中心枢纽。所以组件的视角和angular的视角总是矛盾的。这也是往往在使用指令来卡法组件时让我们感到不利索的原因。此外,指令的嵌套也会使数据模型之间的关系变得复杂。因为指令往往也会有一个scope以及和它相关的作用域。这些原因导致使用指令的组件不但设计实现困难,且使用起来也很不方便。归根结底就是因为指令并不是实现组件的好方式,特别是复杂的组件。<br />
<br />
个人认为,一个比较好的做法是把页面的组件干脆封装成独立的JS对象,把对scope的数据操作彻底的封装成相应的事件。这样似乎能够好一点。这个对象自己决定在何时传递数据。<br />
<br />
不过我一向不认为纯粹的就好,恰恰相反,我认为简单,直接,有效的才是好的。繁复的做法一定要有原因,如果仅仅是为了契合某种说不清道不明的哲学,我认为是完全不值得的。最后审视一下我们的项目,我觉得require js的作用远远大于angular js。事实上,我倒觉得,angular并不是一个好的系统框架,而是应该作为某个前台系统框架的一部分,这样应该是比较好的。不过这个系统得多复杂呀。我的经验告诉我,复杂的设计注定不能长久。Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-73710814395912336382014-02-25T20:15:00.000-08:002014-02-25T20:18:29.533-08:00过渡设计<div class="MsoPlainText">
过渡设计其实是一个很有趣的主题,因为设计是一种人为的主观行为,并不太容易受到制约。而且设计也很难界定,大体上当你打开你的开发工具,并在键盘上敲下第一个字母的时候,设计的内容已经开始在你的头脑中展开了。但其实在软件领域里面,提到的设计大约都是指的架构设计,架构设计是没有什么所谓过渡设计这么一说的,因为架构设计和业务场景关联的十分紧密(适用一切的架构是不存在的),否则就是失败的,而且这一点也十分的容易发现,并不需要软件方面的专家。<span lang="EN-US"><o:p></o:p></span></div>
<div class="MsoPlainText">
<br /></div>
<div class="MsoPlainText">
而我们所说的过渡设计其实存在于实现的设计中。是的,实现的设计,这个设计在软件工程中似乎并没有太大的地位,但也并非不被重视。主要是这个阶段的设计比较难做,同时也很难管理和控制。个人觉得,在多数的公司中,都没有明确的提出实现设计,并将其列为软件质量的一个重要指标。<span lang="EN-US"><o:p></o:p></span></div>
<div class="MsoPlainText">
<br /></div>
<div class="MsoPlainText">
但其实实现设计中的过度设计也并不难发现,首先要明确一点,不能因为可能过度设计就不去设计了。并从而否定面向对象思想或者面向方面的开发方式。毕竟我们总是需要一种可以思考的方式并且需要能够和别人沟通和交流。因为实现的过程不可能是孤立的,任何软件都几乎不可能一个人完成。除非你是特殊材料制成的,我们一般管这种人叫天才。不过这种人太少见了,不必考虑他们对于实现的影响。<span lang="EN-US"><o:p></o:p></span></div>
<div class="MsoPlainText">
<br /></div>
<div class="MsoPlainText">
首先,设计是为了应对变化。也就是说,我们通过各种手段去进行所谓的设计,其目的就是为了让我们的代码有潜在的被改动或者被扩展的这种可能性。比如我们引入了某个接口,这样我们就有了替换实现的可能性。接口在设计中其实就是为了隔离实现的。另外我也可以使用多态性通过改变子类的行为的方式来扩展我们的业务。没有人可以保证业务是永远不变化的,其实业务或者业务的实现方式或多或少都会随着时间而改变,而且时间越长,这种变化就可能会越剧烈。因此支持变化往往是很有必要的。<span lang="EN-US"><o:p></o:p></span></div>
<div class="MsoPlainText">
<br /></div>
<div class="MsoPlainText">
其二,设计总是为了更好的和业务契合,也就是固化某些核心的逻辑。换一种说法就是在创造某一种<span lang="EN-US">DSL</span>语言,这让我想起了格林斯潘第十定律。这也是非常重要的,核心业务往往就是某种产品或者某家公司赖以生存的根本。因此通过一些手段固化这些业务是十分重要的。而且核心业务往往很久都不会发生变化。比如<span lang="EN-US">QQ</span>的聊天功能,<span lang="EN-US">office</span>的编辑功能,游戏的价值观等。所以设计总是需要为业务来提供便利,越复杂的业务,这个需要就越发的明显。<span lang="EN-US"><o:p></o:p></span></div>
<div class="MsoPlainText">
<br /></div>
<div class="MsoPlainText">
第三,设计是为了更容易的扩大开发的规模。通过适当的抽象和合理的封装以及分层,把系统的核心和外延分离,以便于能够通过增加人手来提高开发的效率,同时也要避免初级程序员的破坏性。这也是为什么很多的系统喜欢使用<span lang="EN-US">spring</span>来开发的原因。使用<span lang="EN-US">spring</span>的系统从这个意义上来说,应该不是非常重要的系统。<span lang="EN-US"><o:p></o:p></span></div>
<div class="MsoPlainText">
<br /></div>
<div class="MsoPlainText">
最后,设计往往应该能够更好的支持测试。开发者往往都不怎么喜欢测试<span lang="EN-US">,</span>一般来说他可能更相信自己的直觉。当然,直觉有的时候准确的可怕,但有的时候却错的离谱。所以用多种手段来保证开发的正确性是十分必要的。而测试往往具有很多的层次,对于实现的设计来说,测试更多的指的是单元测试。为了能过更好的支持单元测试,往往需要在设计上进行一些让步。越核心的功能,单元测试就越重要。特别是类库的设计,必须要考虑各种各样的情况,如果没有单元测试,根本无法保证类库的健壮性。<span lang="EN-US"><o:p></o:p></span></div>
<div class="MsoPlainText">
<br /></div>
<div class="MsoPlainText">
除此之外的设计大多数都是过渡的设计,比如我们为何使用依赖注入技术?因为我们有很多的依赖关系需要管理,而且在不同的层次上希望能够降低耦合性。<span lang="EN-US">IOC</span>并不会带来代码阅读或者维护上的便利,因此如果你的系统是一个层次分明,功能确定的系统,<span lang="EN-US">IOC</span>其实就是一种过渡设计。所以我发现大多数应用了<span lang="EN-US">spring</span>框架的系统往往都是过度设计了的。因为其实你的系统完全不需要那种千篇一律的层次划分和解耦方式。<span lang="EN-US"><o:p></o:p></span></div>
<div class="MsoPlainText">
<br /></div>
<div class="MsoPlainText">
过渡设计还有一个有趣的特征,那就是一旦有了过渡的设计,为了让这个设计看起来合情合理,那么往后的设计就会有越来越过渡的趋势,直到被废弃。这时你会发现所谓框架的代码量比你业务的代码量要大得多。我把这种情况称为过度设计漩涡,一旦卷入,就无法脱身,并且随着代码的增加,设计的填补,设计会越来越过渡。</div>
<br />
<div class="MsoPlainText">
使用<span lang="EN-US">spring</span>和<span lang="EN-US">hibernate</span>这样的框架来解决问题,似乎已经成了<span lang="EN-US">java</span>开发的一种趋势。但其实这些框架掌握起来并不容易,而且一旦使用,往往都会陷入过渡设计的漩涡。严重影响系统的可读性和运行性能。而且你一旦学会了<span lang="EN-US">spring</span>或者<span lang="EN-US">hibernate</span>的思考方式就更为的可怕,因为他们总是把问题搞的很复杂。复杂的框架以及其运作的方式会把你的业务搞得杂乱无比,你甚至可能还需要去学习一种框架专用的<span lang="EN-US">DSL</span>。我觉得这种行为其实就是舍本逐末。<span lang="EN-US"><o:p></o:p></span></div>
Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-91480106787236616732009-07-28T22:33:00.001-07:002009-07-28T22:33:18.850-07:00jdk 字体设置<div class="Section1"><p style="margin-left: 0pt; margin-right: 0pt;"><span style="font-family: 'AR PL UMing CN';"><font size="3">Ubuntu </font></span><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">下</font></span><span style="font-family: 'AR PL UMing CN';"><font size="3">jdk</font></span><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">字体设置</font></span></p><p style="margin-left: 0pt; margin-right: 0pt;"><span style="font-family: 'AR PL UMing CN';"><font size="3"> </font></span></p><p style="margin-left: 0pt; margin-right: 0pt;"><span style="font-family: 'AR PL UMing CN';"><font size="3"> </font></span><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">在</font></span><span style="font-family: 'AR PL UMing CN';"><font size="3">ubuntu</font></span><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">下面安装</font></span><span style="font-family: 'AR PL UMing CN';"><font size="3">jdk</font></span><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">的时候,会发现字体很差。其实解决的方法非常的简单:</font></span></p><p style="margin-left: 0pt; margin-right: 0pt;"><br></p><p style="margin-left: 0pt; margin-right: 0pt;"><span style="font-family: 'AR PL UMing CN';"><font size="3"> </font></span></p><p style="margin-left: 0pt; margin-right: 0pt;"><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">打开终端:</font></span> <br></p><p style="margin-left: 0pt; margin-right: 0pt;"><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">输入:</font></span><span style="font-family: 'AR PL UMing CN';"><font size="3">sudo gedit </font></span><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">以管理员方式进入</font></span><span style="font-family: 'AR PL UMing CN';"><font size="3">gedit</font></span><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">。</font></span></p><p style="margin-left: 0pt; margin-right: 0pt;"><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">打开</font></span><span style="font-family: 'AR PL UMing CN';"><font size="3">jre</font></span><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">下面的</font></span><span style="font-family: 'AR PL UMing CN';"><font size="3">fontconfig.properties</font></span></p><p style="margin-left: 0pt; margin-right: 0pt;"><span style="font-family: 'AR PL UMing CN';"><font size="3"> </font></span></p><p style="margin-left: 0pt; margin-right: 0pt;"><br><img src="http://docs.google.com/File?id=dfnmqw7p_83cvrh7bdt_b" alt="" border="0" width="642" height="494"><br></p><p style="margin-left: 0pt; margin-right: 0pt;"><br><img src="http://docs.google.com/File?id=dfnmqw7p_84hf5gnkd5_b" alt="" border="0" width="642" height="521"><br></p><p style="margin-left: 0pt; margin-right: 0pt;"><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">注意选中部分,把</font></span><span style="font-family: 'AR PL UMing CN';"><font size="3">uming.ttf</font></span><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">改成</font></span><span style="font-family: 'AR PL UMing CN';"><font size="3">uming.ttc</font></span><span style="font-family: 'Bitstream Vera Sans1';"><font size="3">就可以了。我这个是改过的。</font></span></p></div><br>Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-85476978488885216752009-05-11T18:47:00.000-07:002009-05-11T18:51:26.223-07:00没有激情最近心情很不好。不知道是为了什么。大概是因为自己的能力问题吧。很多想干的事情干不了。很多想避免的问题,无法避免吧。如果说错误。我觉得自己是真的有错误。如果说心态,我觉得自己的心态也的确不好。没有士气,没有激情。Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-18297093278767581832009-02-11T19:59:00.000-08:002009-05-11T18:43:23.910-07:002009-02-12 感悟-告别浮躁<br /> <br /> 生活多现在的我来说有一丝丝的平淡。我今年已经年过30了,内心有很多的愧疚。现在看来,茫茫不知自己的未来在何方。于是又有了一丝丝的遗憾。Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-1469917903546780862008-11-02T01:35:00.000-07:002009-05-11T18:43:23.914-07:00linux下java swing问题的解决<br />在linux做java开发的朋友都知道swing在linux下有些很令人头疼的问题。<br /><br />第一个问题就是scim输入法和swing的冲突问题导致键盘失效,尤其是开了compiz之后。<br /><br />对于这个问题网上有很多处理的方法,例如添加环境变量AWT_TOOLKIT=MToolkit,这个方法还是不能解决swing程序中键盘失效的问题。<br /><br />国外论坛上找到一个很好的解决方法就是:<br /><br />sudo cp ~/.scim/config /root/.scim/<br /><br />之后我在netbeans里面从来没有发生过键盘失效的问题<br /><br />第二个麻烦就是在Ubuntu使用Java来编写Swing应用程序时一个比较大的问题就是不能使用SystemLookAndFeel。<br /><br />例如运行jconsole的时候会报如下错:<br /><br />Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException<br /> at com.sun.java.swing.plaf.gtk.GTKLookAndFeel.initSystemColorDefaults(GTKLookAndFeel.java:1267)<br /> at com.sun.java.swing.plaf.gtk.GTKLookAndFeel.loadStyles(GTKLookAndFeel.java:1509)<br />……<br /><br />有的人给出不完美的解决方案,就是把语言环境改成英文:<br /><br />export LANG=en<br /><br />这样swing应用程序就可以正常运行了,但这样对于使用中文的用户来说就很不方便,界面变成了英文。实际上出现这个问题是因为swing的默认laf采用systemlaf,而ubuntu里却没有定义这个laf<br /><br />好的解决方法是在程序启动时传递JVM运行参数 -Dswing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel<br /><br />或者在/etc/environment 文件在最后增加上:<br /><br />_JAVA_OPTIONS="-Dswing.systemlaf=javax.swing.plaf.metal.MetalLookAndFeel"Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-69625183043864607042008-10-31T20:56:00.000-07:002009-05-11T18:43:23.918-07:002008年11月1日 晴<br /><br /> 我开始在linux上写日记了。我觉得linux比windows强的太多了。如果你试一下你就知道。原来在windows下工作居然是一种比较愚蠢的选择。呵呵。其实也不一定。<br /><br /> Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-59702658017859231892007-09-19T20:04:00.000-07:002009-05-11T18:43:23.922-07:00 <p class="MsoNormal"><span style="font-family: 宋体;">抽象类与接口</span></p> <p class="MsoNormal"><span lang="EN-US"><p> </p></span></p> <p class="MsoNormal"><span style="font-family: 宋体;"> 在</span><span lang="EN-US">java</span><span style="font-family: 宋体;">里面,在什么情况下你会选择抽象类而不是接口?通常情况下,你能否解释抽象类的含义并说明什么时候使用他们?当你开始设计一个独立的系统的时候,当你准备深入面向对象编程的时候你一定会问自己这些问题。这个问题,乍一看是一个写程序的细节问题,但其实这是一个设计的问题。接口与抽象类的运用能够使你的程序变得更加的抽象,从而更加的灵活,更能够适应变化的需求。我想,这一点至关重要。</span></p><p class="MsoNormal"><br></p><p class="MsoNormal"><span style="font-family: 宋体;"> 从语法的角度来看,抽象类和接口的差别好像仅仅是有没有具体方法的问题,当让这也是一个事实。这种微小的差别使得我们在使用他们的时候差生了疑问。我们会觉得尽然有抽象类为什么还需要接口,如果我把抽象类中的所有方法都定义为抽象的那不是和接口是一样的了么?是的,如果仅从语法的层面来看的却是这样。但事实上他们的用途是完全不同的。</span></p><p class="MsoNormal"><span style="font-family: 宋体;"> <br></span></p><p class="MsoNormal"><span style="font-family: 宋体;"> 抽象类被设计出来是要用于被继承。当我们设计任何一个抽象类的时候我们都要明白这一点,这个抽象类是被用来继承的。它必然是一个完成某种功能的树的一个根节点。我们可以看一下java中的util里的AbstractList这个抽象类。如下:</span></p> <pre><a href="http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/html/zh_CN/api/java/lang/Object.html" title="java.lang 中的类">java.lang.Object</a><br> <img src="http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/html/zh_CN/api/resources/inherit.gif" alt="继承者 "><a href="http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/html/zh_CN/api/java/util/AbstractCollection.html" title="java.util 中的类">java.util.AbstractCollection</a><E><br> <img src="http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/html/zh_CN/api/resources/inherit.gif" alt="继承者 "><b>java.util.AbstractList<E></b> </pre> <dl><dt><b>直接已知子类:</b> </dt><dd><a href="http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/html/zh_CN/api/java/util/AbstractSequentialList.html" title="java.util 中的类">AbstractSequentialList</a>, <a href="http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/html/zh_CN/api/java/util/ArrayList.html" title="java.util 中的类">ArrayList</a>, <a href="http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/html/zh_CN/api/java/util/Vector.html" title="java.util 中的类">Vector</a></dd><dt>我们从来没有直接使用过这个AbstractList。但是我们常用它的子类,比如说Vector。乍一看好像util里面这个抽象类毫无用处,但事实上,如果我们需要自己实现一个特殊的List而有不想封装或者不能封装ArrayList或者Vector的话我们就可以从这继承,来写自己的List。</dt></dl> 抽象类必然是一个功能体系的根,它实在有太多的好处。最根本的一条是它能够提供一些规约,用来约束由他派生出来的子类。比如一些共用的资源,共用的算法什么的。例如,假设你所在的公司开发了一套鸭子模拟游戏,它可以模拟各种不同的鸭子,在水上游泳,同时还能发出“嘎嘎”的叫声。我们就可以这样来设计,一个抽象的Duck基类,有发出“嘎嘎”叫声的Quack方法和在水里游泳的Swim方法,同时它还有一个抽象的 Display方法,每一个Duck子类(如MallardDuck、RedheadDuck)都将之重写,以便实现自己与众不同的外观。如下图: <p align="center"><img src="http://www.cnblogs.com/images/cnblogs_com/chengbo/61446/o_Original.JPG" height="230" width="238"></p> <p>你们公司有很多竞争对手,他们可不是吃素的,在日益增大的市场压力下,你们老板做出了一个决定,要改进这个游戏,让游戏里的鸭子飞起来,成功的话,一定可以打败所有的人。哦,这个艰巨的任务就交给你了。接到任务,你马上就开始了。这还不容易?在Duck基类里加一个Fly方法,这样所有的Duck子类都可以获得这个方法,所有的鸭子都可以飞了。太简单了,这就是抽象类的威力呀。</p> <p align="center"><img style="width: 238px; height: 230px;" src="http://www.cnblogs.com/images/cnblogs_com/chengbo/61446/o_OriginalWithFly.JPG" height="230" width="238"></p>所以,抽象类就应该这么用。它生来就是要被继承的。如果不需要继承也就同样不需要抽象类。当然我们遇到的问题不可能如此的简单,往往具体的问题需要具体的分析才能真正的解决。而这个解决也同样不可能是完美的。这里我又想提一提Martin Fowler的《The New Methodology》这篇文章,里面谈到了很多。因为我们的软件不可能都像<a name="NE6">NASA的航天飞机的软件开发项目那样拥有不变而且确定的需求和在这个基础上完美的设计的。所以对我们系统的合理抽象可以说是至关重要的。就如同上面的鸭子项目一样,合理的抽象使我们面对变化而从容不迫。试想如果我们没有这个抽象会怎么样?一个类一个类的去改代码?那我们面对的就是一片森林了。项目因此就有可能陷入泥潭。<br><br> 那么我们再来说说接口,接口有什么用处呢?其实接口也是为了应对变化而出现的。不过这个变化和上面的不同,接口应对的是可以预知的变化。也就是说,在我们设计系统的时候,我们知道这个地方一定会有变化,我们就可以采用接口的方式把这个变化保留下来。当然接口的目的是要和其他的对象进行配合的,如果你预料到的这个变化和系统的其他部分没有什么关系的话,那我认为你没有必要考虑它了。举个例子:java.io中的</a>FilenameFilter极为典型。我们只需要实现boolean <b>accept</b>(<a href="http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/html/zh_CN/api/java/io/File.html" title="java.io 中的类">File</a> dir, <a href="http://download.java.net/jdk/jdk-api-localizations/jdk-api-zh-cn/publish/1.6.0/html/zh_CN/api/java/lang/String.html" title="java.lang 中的类">String</a> name)方法,系统就可以根据我们的要求来进行过滤了。这里我还想提一个典型的错误接口设计,那就是常数接口,吧一堆常数放到接口里面去,需要的时候就让自己的对象来实现。这是一种晕头的设计。我的建议是不妨另写一个类就起名叫Constents好了,把所有的常数放到它里面。<br><br> 其实抽象类和接口在jdk里面是在是非常的多。很多类包的设计都是含有若干接口若干抽象类的。可以知道,实际的系统往往是比较复杂的,如何设计其实取决于我们如何理解的系统,理解的是否正确。另外我们的设计也要充分合理的考虑到变化,不要去搞一锤子买卖。在软件设计中这个很不现实。毕竟人们对一个系统的认识不可能一步到位的。当然要应对变化,仅仅是抽象还是不够的,但这毕竟是最基本的。<br><p class="MsoNormal"></p>Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-52659677077609875812007-09-19T19:50:00.000-07:002009-05-11T18:43:23.926-07:00困惑<br /><br /> 昨天在查看自己原来写的程序的时候发现自己似乎模型建立的不够多。很多功能似乎还是由不同的方法相互配合来完成的。而不是对象之间的协作。这种情况让我觉得似乎很不愉快。我想这是一个对象划分粒度的问题。<br /><br />面向对象要求封装,其实程序对于算法的依赖似乎就没有终结过。封装解决的是重用的问题,而不是算法的问题。通过对象的认识和分析,似乎我们找到了解决问题的简单方法,但其实没有。没有简单的方法,而利用模型来分析问题只是一种普遍的解决问题的方法,不一定局限与程序的设计上面。而恰恰程序设计方面所用的模型就很不直观。比如UML。UML解决建模问题,不仅仅针对与程序设计。而我个人认为,用UML来描述程序是很不直观的。特别是算法,用UML模型来描述算法,还不如用自然语言写在纸上或者用数学的描述方法来的更直观。<br /><br />所以模型是出现在程序之外的。可以在任何地方,但最终要在你的脑里。<br />我们现在写的很多程序,其实用不太到很多的算法,大多数的情况都是将数据移动一下,或者做一些判断在移动一下。这些实在是太简单,用不到太多的数学或者物理知识。但是如果我们要写一个虚拟现实的仿真程序,恐怕就没有那么简单了。<br /> Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-17135688149387912472007-05-30T23:28:00.000-07:002009-02-11T20:01:15.893-08:00为客户实施报表不幸<br /><br />辛辛苦苦的为客户设计和编写了一套报表工具,却还要十分可怜的为客户实施。虽然也可以检测自己的程序,但是要知道,写程序的一般是不愿意给自己做测试的。唉。实施是个无聊之极的活。但是还得干。Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-24360761292795050942007-05-18T23:14:00.000-07:002007-05-21T18:12:48.550-07:00 <p class="western" style="margin-bottom: 0in;"><font size="6"><span style="font-weight: bold;"> NetBeans难以搞定的字体</span></font></p><p class="western" style="margin-bottom: 0in;"> <img name="graphics1" src="http://docs.google.com/File?id=dfnmqw7p_17g88sqgfv" align="bottom" border="0" height="30" width="186"> </p> <br>netbeans 的字体是一个令人伤心的问题。实际上netbeans的字体完全依赖于jdk的。而jdk又依赖于系统。由于我的系统字体有一些问题。主要是不知为何变得及其的不美观。所以只好去修改jdk的配置。总之是一个令人晕而又晕的问题。<br><br>jdk的字体依赖于jre。在jre的lib下。有字体的设置文件。修改设置文件即可。记得要去掉properties后面的src。<br><br>另外希望修改输出字体的人,有一个简单的办法,就是直接删除自己系统中的18030字体。<br><p class="western" style="margin-bottom: 0in;"><font size="6"><span style="font-weight: bold;"> </span></font></p><p class="western" style="margin-bottom: 0in;"> </p> <p class="western" style="margin-bottom: 0in;"> </p> <p class="western" style="margin-bottom: 0in;"> </p> <p class="western" style="margin-bottom: 0in;"> </p><p class="western" style="margin-bottom: 0in;"> </p>Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com2tag:blogger.com,1999:blog-1154884446667282815.post-52967764096227633902007-05-10T20:42:00.000-07:002007-05-21T18:08:59.379-07:00<div> <h1> Java泛型编程 </h1> </div> <a class="bluekey" href="http://www.yesky.com/key/4410/4410.html" target="_blank">JDK1.5</a> 令我们期待很久,可是当他发布的时候却更换版本号为5.0。这说明Java已经有大幅度的变化。本文将讲解JDK5.0支持的新功能-----Java的<a class="bluekey" href="http://www.yesky.com/key/171/85171.html" target="_blank">泛型</a>.<br> <br> 1、Java泛型<br> <br> 其实Java的泛型就是创建一个用类型作为参数的类。就象我们写类的方法一样,方法是这样的<a class="bluekey" href="http://www.yesky.com/key/3316/113316.html" target="_blank">method</a>(<a class="bluekey" href="http://www.yesky.com/key/2462/102462.html" target="_blank">String</a> str1,String str2 ),方法中参数str1、str2的值是可变的。而泛型也是一样的,这样写<a class="bluekey" href="http://www.yesky.com/key/3741/213741.html" target="_blank">class</a> Java_Generics<K,V>,这里边的K和V就象方法中的参数str1和str2,也是可变。下面看看例子:<br> <br> <table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td> //<a class="bluekey" href="http://www.yesky.com/key/994/20994.html" target="_blank">code</a> <a class="bluekey" href="http://www.yesky.com/key/89/20089.html" target="_blank">list</a> 1<br> <a class="bluekey" href="http://www.yesky.com/key/1897/116897.html" target="_blank">import</a> Java.util.Hashtable;<br> class TestGen0<K,V>{<br> <a class="bluekey" href="http://www.yesky.com/key/438/35438.html" target="_blank">public</a> Hashtable<K,V> h=new Hashtable<K,V>();<br> public <a class="bluekey" href="http://www.yesky.com/key/3728/98728.html" target="_blank">void</a> put(K k, V v) {<br> h.put(k,v);<br> }<br> public V get(K k) {<br> <a class="bluekey" href="http://www.yesky.com/key/148/105148.html" target="_blank">return</a> h.get(k);<br> }<br> public <a class="bluekey" href="http://www.yesky.com/key/2524/102524.html" target="_blank">static</a> void main(String args[]){<br> TestGen0<String,String> t=new TestGen0<String,String>();<br> t.put("key", "<a class="bluekey" href="http://www.yesky.com/key/3906/33906.html" target="_blank">value</a>");<br> String s=t.get("key");<br> System.out.println(s);<br> }<br> } </td> </tr> </tbody> </table> <br> 正确输出:value<br> <br> 这只是个例子(Java中集合框架都泛型化了,这里费了2遍事.),不过看看是不是创建一个用类型作为参数的类,参数是K,V,传入的“值”是String类型。这个类他没有特定的待处理型别,以前我们<a class="bluekey" href="http://www.yesky.com/key/1586/86586.html" target="_blank">定义</a>好了一个类,在输入输入参数有所固定,是什么型别的有要求,但是现在编写程序,完全可以不制定参数的类型,具体用的时候来确定,增加了程序的通用性,像是一个<a class="bluekey" href="http://www.yesky.com/key/3739/3739.html" target="_blank">模板</a>。<br> <br> 呵呵,类似C++的模板(类似)。<br> <br> 1.1. 泛型通配符<br> <br> 下面我们先看看这些程序:<br> <br> <table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td> //Code list 2<br> void TestGen0Medthod1(List l) {<br> for (<a class="bluekey" href="http://www.yesky.com/key/3163/8163.html" target="_blank">Object</a> o : l)<br> System.out.println(o);<br> } </td> </tr> </tbody> </table> <br> 看看这个方法有没有异议,这个方法会通过编译的,假如你传入String,就是这样List<String>。<br> <br> 接着我们调用它,问题就出现了,我们将一个List<String>当作List传给了方法,JVM会给我们一个警告,说这个破坏了<a class="bluekey" href="http://www.yesky.com/key/4687/74687.html" target="_blank">类型安全</a>,因为从List中返回的都是Object类型的,而让我们再看看下面的方法。<br> <br> <table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td> //Code list 3<br> void TestGen0Medthod1(List<String> l) {<br> for (Object o : l)<br> System.out.println(o);<br> } </td> </tr> </tbody> </table> <br> 因为这里的List<String>不是List<Object>的子类,不是String与Object的关系,就是说List<String>不隶属于list<Object>,他们不是继承关系,所以是不行的,这里的extends是表示限制的。<br> <br> 类型通配符是很神奇的,List<?>这个你能为他做什么呢?怎么都是“?”,它似乎不确定,他总不能返回一个?作为类型的数据吧,是啊他是不会返回一个“?”来问程序员的?JVM会做简单的思考的,看看代码吧,更直观些。<br> <br> <table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td> //code list 4<br> List<String> l1 = new ArrayList<String>();<br> <a class="bluekey" href="http://www.yesky.com/key/763/210763.html" target="_blank">li</a>.<a class="bluekey" href="http://www.yesky.com/key/4717/214717.html" target="_blank">add</a>(“String”);<br> List<?> l2 = l1;<br> System.out.println(l1.get(0)); </td> </tr> </tbody> </table> <br> 这段代码没问题的,l1.get(0)将返回一个Object。<br> <br> 1.2. 编写泛型类要注意:<br> <br> 1) 在定义一个泛型类的时候,在 “<>”之间定义形式类型参数,例如:“class TestGen<K,V>”,其中“K” , “V”不代表值,而是表示类型。<br> <br> 2) <a class="bluekey" href="http://www.yesky.com/key/1102/61102.html" target="_blank">实例</a>化泛型对象的时候,一定要在类名后面指定类型参数的值(类型),一共要有两次书写。例如:<br> <br> TestGen<String,String> t=new TestGen<String,String>();<br> <br> 3) 泛型中<K extends Object>,extends并不代表继承,它是类型范围限制。<br> <br>2、泛型与数据类型转换 <br><br> 2.1. 消除类型转换 <br><br> 上面的例子大家看到什么了,数据类型转换的代码不见了。在以前我们经常要书写以下代码,如: <br><br> <table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>//code list 5 <br>import Java.util.Hashtable; <br>class Test { <br> public static void main(String[] args) { <br> Hashtable h = new Hashtable(); <br> h.put("key", "value"); <br> String s = (String)h.get("key"); <br> System.out.println(s); <br> } <br>} </td></tr></tbody></table><br> 这个我们做了类型转换,是不是感觉很烦的,并且强制类型转换会带来潜在的危险,系统可能会抛一个ClassCastException异常信息。在JDK5.0中我们完全可以这么做,如: <br><br> <table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>//code list 6 <br>import Java.util.Hashtable; <br>class Test { <br> public static void main(String[] args) { <br> Hashtable<String,Integer> h = new Hashtable<String,Integer> (); <br> h.put("key", new Integer(123)); <br> int s = h.get("key").intValue(); <br> System.out.println(s); <br> } <br>}</td></tr></tbody></table><br> 这里我们使用泛化版本的HashMap,这样就不用我们来编写类型转换的代码了,类型转换的过程交给编译器来处理,是不是很方便,而且很安全。上面是 String映射到String,也可以将Integer映射为String,只要写成HashTable<Integer,String> h=new HashTable<Integer,String>();h.get(new Integer(0))返回value。果然很方便。 <br><br> 2.2 自动解包装与自动包装的功能 <br><br> 从上面有没有看到有点别扭啊,h.get(new Integer(123))这里的new Integer(123);好烦的,在JDK5.0之前我们只能忍着了,现在这种问题已经解决了,请看下面这个方法。我们传入一个int这一基本型别,然 后再将i的值直接添加到List中,其实List是不能储存基本型别的,List中应该存储对象,这里编译器将int包装成Integer,然后添加到 List中去。接着我们用List.get(0);来检索数据,并返回对象再将对象解包装成int。恩,JDK5.0给我们带来更多方便与安全。 <br><br> <table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>//Code list 7 <br>public void autoBoxingUnboxing(int i) { <br> ArrayList<Integer> L= new ArrayList<Integer>(); <br> L.add(i); <br> int a = L.get(0); <br> System.out.println("The value of i is " + a); <br>} </td></tr></tbody></table><br> 2.3 限制泛型中类型参数的范围 <br><br> 也许你已经发现在code list 1中的TestGen<K,V>这个泛型类,其中K,V可以是任意的型别。也许你有时候呢想限定一下K和V当然范围,怎么做呢?看看如下的代码: <br><br> <table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>//Code list 8 <br>class TestGen2<K extents String,V extends Number> <br>{ <br> private V v=null; <br> private K k=null; <br> public void setV(V v){ <br> this.v=v; <br> } <br> public V getV(){ <br> return this.v; <br> } <br> public void setK(K k){ <br> this.k=k; <br> } <br> public V getK(){ <br> return this.k; <br> } <br> public static void main(String[] args) <br> { <br> TestGen2<String,Integer> t2=new TestGen2<String,Integer>(); <br> t2.setK(new String("String")); <br> t2.setV(new Integer(123)); <br> System.out.println(t2.getK()); <br> System.out.println(t2.getV()); <br> } <br>} </td></tr></tbody></table><br> 上边K的范围是<=String ,V的范围是<=Number,注意是“<=”,对于K可以是String的,V当然也可以是Number,也可以是Integer,Float, Double,Byte等。看看下图也许能直观些请看上图A是上图类中的基类,A1,A2分别是A的子类,A2有2个子类分别是A2_1,A2_2。 <br><br> 然后我们定义一个受限的泛型类class MyGen<E extends A2>,这个泛型的范围就是上图中兰色部分。 <br><br> 这个是单一的限制,你也可以对型别多重限制,如下: <br><br> <table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>class C<T extends Comparable<? super T> & Serializable></td></tr></tbody></table><br> 我们来分析以下这句,T extends Comparable这个是对上限的限制,Comparable< super T>这个是下限的限制,Serializable是第2个上限。一个指定的类型参数可以具有一个或多个上限。具有多重限制的类型参数可以用于访问它的每个 限制的方法和域。 <br><br> 2.4. 多态方法 <br><br> <table align="center" bgcolor="#dadacf" border="1" bordercolor="#ffcc66" width="90%"> <tbody> <tr> <td>//Code list 9 <br>class TestGen { <br> <T extends Object> public static List<T> make(T first) { <br> return new List<T>(first); <br> } <br>}</td></tr></tbody></table><br><br>Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-25042314832681600082007-05-08T19:08:00.000-07:002007-05-08T19:19:18.568-07:00<font face="宋体, SimSun" size="2"><span lang="zh-CN"><b>面向对象设计散谈</b></span></font><ol> <li> <h2 class="western"> <font face="黑体, SimHei" size="2"><span lang="zh-CN">初衷</span></font> </h2> </li></ol> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">最早开始接触面向对象的设计应该是在今年</span></font><font size="2">6</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">月份皖北项目中。在这之前我做的程序可以说完全谈不上设计,更谈不上面向对象。大多是一些</span></font><font size="2">jsp</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">页面,将数据从一个地方存到另一个地方而已。皖北的情况有所不同,当时用户对业务有需求,不是能够用</span></font><font size="2">jsp</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">页面或者以某种方式移动数据所能解决的。用户的要求可以被理解为建立一个树状的模型,模型中的每一个上级节点的值是它所对应的下级节点的值的合计。为了实现这个需求,开始了第一次面向对象设计的实践。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">面向对象的程序设计的核心原则是“开—闭”原则。开闭原则讲的是系统应该对扩充开对修改闭。这很好理解,就如同我们盖楼房,大家都盖</span></font><font size="2">3</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">层。如果我的设计考虑到了日后的扩充问题,我按</span></font><font size="2">5</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">层的标准设计。可想而知,如果日后房子不够了要增加层数,我就直接在</span></font><font size="2">3</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">层上面加几层就可以了。而其他的人可能要把楼拆了重盖。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">面向对象设计的其他原则有:里氏代换,依赖倒转等。而“开-闭”原则则是这些原则的核心,其他的一系列的原则好像都是为了实现开闭而提出的。包括很多,比如在设计的时候要使对象尽可能的内聚,同时减少耦合;要适当的抽象,复用的部分被提取到抽象类中;要尽可能的针对接口编程,或者说针对变化编程。而且封装的意义也已经扩大了,封装不仅仅指数据的隐藏而是任何形式的隐藏,事实上封装的是变化,也就是说系统变化的部分将会被封装。这说起来很简单,而实际上要求我们改变我们分析问题的思路和看待问题的视角,而所作的一切都是为了和开闭原则靠拢,最终的目的是设计出灵活的健壮的易于理解并且高效的系统。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">设计模式的提出,很大程度上也是为了实现这个目标。提到模式我想起了我放假回家时打麻将的经历,牌桌上的朋友其实也不比我聪明,学历也没我高,可是我就是打不过他们,他们对于麻将的技巧十分的娴熟,甚至可以通过手中的牌和打出的牌来推测各家手中的情况。同时他们也有很多术语,什么“夹三条”,“边二万”等等。失败的原因在于,我一年几乎只打一次麻将,而他们几乎天天都在牌桌上。他们对于麻将的认识和我相比是有很大的区别的,他们了解很多“模式”不需要计算,直接从手中的牌就能看出怎么打,而我却需要很多计算,才能决定如何出牌,最终失败成必然。人天生就具有认识模式的能力,模式是一种针对特定系统的高级的抽象,而对于模式的理解与运用,只有通过实践才能最终纯熟。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">既然提到了模式,我还想谈谈上帝模式。其实也许程序设计的最高境界就是这个上帝模式。在我们的系统中,有一个全能的上帝,它可以完成系统所需要的所有任务。其他的程序只需要向他“祈祷”(发送一个请求)就可以得到所需要的结果。当然,世界上没有全能的上帝,程序里面也没有,我所知道的系统,没有一个是这样设计的,也无法这样设计。事实上,软件设计模拟的是人类的意识,特别是人类的认识活动,分析活动。系统必然会被分解,形成很多概念,或者说是实体,也就是对象。我们总会从中去寻找我们所熟悉的东西,然后通过类比,分析,归纳等方式最终认识一个系统。认识的过程是反复的渐进的,程序设计也一样,这就是为什么要提出重构的原因。</span></font> </p> <p class="western" style="margin-bottom: 0in;"> <font size="2"><br></font> </p> <ol start="2"> <li> <h2 class="western"><font size="2"> ETL</font><font face="黑体, SimHei" size="2"><span lang="zh-CN">中间表导入程序</span></font> </h2> <ol> <li> <h3 class="western"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">概述</span></font> </h3> </li></ol> </li></ol> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">我们主要要讲的是这个简单的</span></font><font size="2">etl</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">中间表导入程序。这是淮北项目数据分析系统的一部分。这个程序的目的是从一张定义好的数据库中的表里面讲数据按照某一个规则到如到相关的事实表和维表中去。涉及到的主要问题有:</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <ol> <li> <p class="western" style="margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">事务操作。</span></font> </p> </li><li> <p class="western" style="margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">同步的增量问题。</span></font> </p> </li><li> <p class="western" style="margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">实现不同的插入数据库方法,需要适当的抽象。</span></font> </p> </li><li> <p class="western" style="margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">日志。</span></font> </p> </li><li> <p class="western" style="margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">以恰当的方式制定规则。</span></font> </p> </li></ol> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">这些问题是设计时要考虑的。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">下图是系统最高抽象的一个类图:</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;" align="center"> <font size="2"><img name="graphics1" src="http://docs.google.com/File?id=dfnmqw7p_10d6hcvgd9" align="bottom" border="0" height="303" width="531"></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;" align="center"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">图</span></font><font size="2">1 </font></p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">系统设计整体分为三个部分,分别是:</span></font> </p> <ol> <li> <p class="western" style="margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">数据抽取部分</span></font> </p> </li></ol> <p class="western" style="margin-left: 0.54in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">数据抽取部分的功能是将数据用源数据库抽取出来,当然这里源数据库中的数据是按照我们的要求存放的,也就是说是一种清洗过的数据。通过数据的抽取,生成系统的元数据(</span></font><font size="2">MetaData</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">)。这一部分对应的类就是</span></font><font size="2">Generater</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">。</span></font> </p> <p class="western" style="margin-bottom: 0in;"> <font size="2"><br></font> </p> <ol start="2"> <li> <p class="western" style="margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">数据包装过滤部分</span></font> </p> </li></ol> <p class="western" style="margin-left: 0.54in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">系统的数据核心是</span></font><font size="2">MetaData</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">(元数据),图一中的</span></font><font size="2">Container</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">接口其实是一个数据容器,它和它里面包装的数据一起实现了系统的元数据。</span></font> </p> <p class="western" style="margin-left: 0.54in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <ol start="3"> <li> <p class="western" style="margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">数据操作部分</span></font> </p> </li></ol> <p class="western" style="margin-left: 0.54in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">系统的操作核心是类</span></font><font size="2">MetaTransformer</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">(元数据转换器),它其实是一个非常简单的类,他所描述的对象的功能也十分的简单,它的作用仅仅是把数据和操作连接起来。</span></font><font size="2">SourceType</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">(源类型)是对数据源类型的一种抽象操作。针对不同的数据源类型,产生不同的操作。这种类型的区分,实际上是由操作人员指定的。对程序来说,它将按照一个固定的规则来产生</span></font><font size="2">SourceType</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">的实现者。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">下面我们对上面几个类的相互依赖做一个分析。上面这个类图是用</span></font><font size="2">eclipse</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">的一个免费插件</span></font><font size="2">euml2</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">分析出来的,这个插件尤其擅长分析依赖关系。在图一里面,除了</span></font><font size="2">MetaTransformer</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">这个类以外,都是单向的依赖关系。类之间没有出现循环依赖。</span></font><font size="2">MetaTransformer</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">之所以和很多类有依赖关系,是因为它本身就是承担连接数据和操作的责任,必须把数据与操作连接起来,所以它必须和数据部分以及操作部分关联。没有循环依赖,其实是一个很重要的设计细则,这样也十分有利与单元测试。</span></font> </p> <ol> <ol start="2"> <li> <h3 class="western"><font size="2"> MetaData </font><font face="宋体, SimSun" size="2"><span lang="zh-CN">(元数据)</span></font> </h3> </li></ol> </ol> <p class="western" style="margin-bottom: 0in;" align="center"> <font size="2"><img name="graphics2" src="http://docs.google.com/File?id=dfnmqw7p_11mfqxzrd9" align="bottom" border="0" height="259" width="507"></font> </p> <p class="western" style="margin-bottom: 0in;" align="center"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">图</span></font><font size="2">2 </font></p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">元数据中保存了操作时所需要的主要数据。这样设计的目的是将数据提取和数据插入两部分的功能分开。同时让他们相互独立。在设计的时候有一个原则就是要尽可能的使程序的耦合性降低内聚性增高。其实就是讲要将程序中能够独立出来的功能尽可能的独立出来,这样做也是满足开闭原则的必要条件,如果你不这样做,程序耦合度极高,牵一发而动全身是不可能满足开闭原则的。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">元数据是整个系统的一个核心,所有的操作都会围绕着它来进行。从设计上来看这个元数据类,好像就是《重构》里面提到的一种叫“纯稚的数据类”的坏味道。但我却不得不这样做,否则我的数据就会被打散放在数据库里了。所以我就是需要这么一个纯稚的数据类,这样也方便我操作数据。</span></font><font size="2">MetaData</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">和它的容器</span></font><font size="2">Container</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">一起构成了系统逻辑上的数据部分。这里有几点要注意,</span></font><font size="2">MetaData</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">要设计的尽量简洁,内容越少越好,最好只有变化的数据和它的一个标识。而且它应该采用单例模式,保证它是唯一的,在系统的运行期间只有一个实例存在。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">另外它有可能会非常的巨大,如果这样可能会对系统的健壮性有影响。因此在构建的时候应该有一个限制,目前这一部分功能没有实现。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">这里面还要提到一下这个</span></font><font size="2">Container</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">的抽象,</span></font><font size="2">Container</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">抽象的目的主要是考虑到性能的问题。目前使用的数据容器是用</span></font><font size="2">Vector</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">来实现的,众所周知,</span></font><font size="2">Vector</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">的效率比较低下,但是使用起来顺手,如果考虑到性能的要求的话,这个数据容器还可以考虑用其他的方式来实现。当然这种抽象也应该通过一种配置由工厂方法来生成子类。但是这个也没有实现,所以这个抽象是不完整的。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">另外还要说明的一点,就是</span></font><font size="2">MetaData</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">这个对象是可以序列化出来的。借助</span></font><font size="2">jdk</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">的功能,这个对象可以序列化成一个</span></font><font size="2">xml</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">文件。这个功能没有严格的设计,实现的方法十分简单就是使用</span></font><font size="2">jdk</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">里面的</span></font><font size="2">java.beans.XMLDecoder</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">和 </span></font><font size="2">java.beans.XMLEncoder</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">这两个类,其中一个是编码,一个是解码。通过他们可以把对象生成一个</span></font><font size="2">xml</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">文档。</span></font> </p> <ol> <ol start="3"> <li> <h3 class="western"><font size="2"> Generater </font><font face="宋体, SimSun" size="2"><span lang="zh-CN">(生成器)</span></font> </h3> </li></ol> </ol> <p class="western" style="margin-bottom: 0in;" align="center"> <font size="2"><img name="graphics3" src="http://docs.google.com/File?id=dfnmqw7p_12kf7hvwc8" align="bottom" border="0" height="363" width="439"></font> </p> <p class="western" style="margin-bottom: 0in;" align="center"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">图</span></font><font size="2">3 </font></p> <p class="western" style="margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">生成器的作用是将数据从一个源按照指定的规则抽取出来。如果纯粹是针对数据库操作的,其实也没有抽象的必要,这样设计其实是考虑如果需要从其他的数据源抽取的时候可以直接增加一个子类而不必改程序其他的部分。当然要实现这个目的至少还要配备一个工厂方法,以一种方式(通常是配置或者用户界面的指定)来决定到底是什么数据源。这个工厂方法没有实现,因为觉得出现这种需求的情况可能性比较小。所以其实这个抽象是聋子的耳朵——纯粹的摆设而已,没有什么实际的意义。</span></font> </p> <p class="western" style="margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">生成器里面有一个比较重要的操作就是要实现增量查询。我采用的方法是将源表中的时间戳序列化出来,成一个</span></font><font size="2">xml</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">文档。这样做的坏处是较为复杂,好处是有了一个将源表中需要的数据导出的方法。另外仅操作源和目的无关,有助于减少系统之间不必要的耦合性。这里面还有一些设计的细节,比如不同的数据库对日期的操作是不同的,这里需要区分数据库,区分的方法采用</span></font><font size="2">webber.core</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">里面的方法。就是通过分析配置文件配置项来产生多态。这里不细说了。</span></font> </p> <ol> <ol start="4"> <li> <h3 class="western"><font size="2"> MetaTransformer </font><font face="宋体, SimSun" size="2"><span lang="zh-CN">(元数据转换器)</span></font> </h3> </li></ol> </ol> <p class="western" style="margin-bottom: 0in;" align="center"> <font size="2"><img name="graphics4" src="http://docs.google.com/File?id=dfnmqw7p_13gh6hbdcc" align="bottom" border="0" height="316" width="584"></font> </p> <p class="western" style="margin-bottom: 0in;" align="center"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">图</span></font><font size="2">4 </font></p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">数据转换的核心就是</span></font><font size="2">SourceType</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">这个类型。它被设计为一个接口。因为我虽然知道源数据的类型,但是不能保证源数据如同我们想象的那么单纯,它有可能会比较复杂和特殊。所以我做了一个接口,这样可以保证</span></font><font size="2">SourceType</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">类型在使用的时候系统其他部分不会受</span></font><font size="2">SourceType</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">内部变化的影响。如果我们需要为</span></font><font size="2">SourceType</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">增加一种功能,可以写一个实现这个接口的类就可以了,而系统的其他部分则不会受到影响。当然,由于</span></font><font size="2">SourceType</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">的工厂方法负责根据条件产生它的子类,所以这个工厂方法也会受到影响,但总的来说,变化是可以控制的。不会扩散到系统的其他部分。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">具体看一下这个抽象层次的设计。有一个抽象类</span></font><font size="2">SourceTypeDim</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">用来描述维的操作。因为根据需求源数据的存放有三种可能:它是事实(</span></font><font size="2">SourceTypeDimBase</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">)、他是维度(</span></font><font size="2">SourceTypeDimNone</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">)、他是具有父子关系语意的维度(</span></font><font size="2">SourceTypeDimClass</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">)。注意,这里使用了面向对象设计原则里面的依赖倒转原则,就是说复用的部分放在了抽象类里面。也就是说,元数据存放的三种可能所对应的三种操作其公用的部分被放在了抽象类里面。这样做的好处是减少冗余的代码,坏处是提高了抽象和具体的耦合性。所以这里面就有一个抽象层次划分的问题。我的设计明显少一个层次。应该设计为两个平行的抽象类,一个代表没有语意的维度描述,一个代表有语意的维度描述。但是由于有语意的描述只有一种情况,所以就暂时没有这么做。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">具体什么时候实例化什么子类是由一个简单工厂方法</span></font><font size="2">SourceTypeDimFactory</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">(参看图一)来决定的。它会读取配置文件,根据配置文件里面的描述来决定实例化那一个子类。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN"><b>工厂方法</b>——以上老是提到工厂方法。工厂方法是设计模式中的一种对象构建型模式,就是为生成子类所准备的。工厂方法的好处是把子类的产生变成一种规则,以后我们只要通过这种规则来构建子类,就不用担心其他的问题了。</span></font> </p> <p class="western" style="margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">例如:</span></font> </p> <p class="western" style="margin-bottom: 0in;"> <font size="2"><img name="graphics5" src="http://docs.google.com/File?id=dfnmqw7p_1489mqbgr9" align="bottom" border="0" height="173" width="576"></font> </p> <p class="western" style="margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">这是我用的方法,为</span></font><font size="2">SourceType</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">这个类型实例化子类。我是通过制定了一个类名的规则来实例化子类的。这是一种偷懒的很不好的方法。比较好的方法应该是通过配置文件,采用注册的机制,安全的产生子类。我这样做是因为这个继承关系十分的简单,也就是说</span></font><font size="2">SourceType</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">这个类型的产品十分单一,特别的简单,所以工厂也相对简单了。</span></font> </p> <ol> <ol start="5"> <li> <h3 class="western"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">系统的其他组成</span></font> </h3> </li></ol> </ol> <p class="western" style="margin-left: 0.29in; text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">系统的其他组成主要有:</span></font><font size="2">XML</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">描述文件、系统配置文件(未实现)、日志系统、系统全局常量、工具箱。</span></font> </p> <p class="western" style="margin-left: 0.29in; text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="margin-left: 0.29in; text-indent: 0.29in; margin-bottom: 0in;"><font size="2"> XML</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">描述文件,用来描述数据源的特征,包括提取的</span></font><font size="2">sql</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">语句,以及字段的含义。</span></font> </p> <p class="western" style="margin-left: 0.29in; text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="margin-left: 0.29in; text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">系统配置文件,用来实现系统的一些配置,比如</span></font><font size="2">Container</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">使用哪个子类,日志是否需要在后台黑窗中显示等。</span></font> </p> <p class="western" style="margin-left: 0.29in; text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="margin-left: 0.29in; text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">日志系统,使用</span></font><font size="2">jdk</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">提供的日志类,为系统增加日志。</span></font> </p> <p class="western" style="margin-left: 0.29in; text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="margin-left: 0.29in; text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">系统全局常量,作用和配置文件一样,由于没有实现配置文件,就用它替代了配置文件。</span></font> </p> <p class="western" style="margin-left: 0.29in; text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="margin-left: 0.29in; text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">工具箱,包含了一些需要的工具。比如一些转换,计算等等。</span></font> </p> <ol start="3"> <li> <h2 class="western"> <font face="黑体, SimHei" size="2"><span lang="zh-CN">小结 </span></font> </h2> </li></ol> <p class="western" style="margin-left: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">在这篇文档里面,我提出了我对于面向对象程序设计的一些想法,这些想法很多都是幼稚的,不成熟的。虽然我也读了很多关于设计方面的书籍,但是我觉得程序的设计始终都是一种需要实践的艺术,动手比什么都重要。设计的核心其实还是人本身。一个系统设计的好还是坏,关键在于设计者对于系统的理解程度,没有理解就淡不上分析更谈不上设计。</span></font> </p> <p class="western" style="margin-left: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="margin-left: 0.29in; text-indent: 0.29in; margin-bottom: 0in;"> <font face="宋体, SimSun" size="2"><span lang="zh-CN">正如我前面所谈到的人的认识过程是一个渐进的过程,所以重构在设计里面占一个极大的分量。上述的程序实际就是经过多次重构才最终成型的,而且目前也有很多的不足。因为这是一个客观的情况,所以我们在设计的时候切忌对象间的耦合度过高。耦合度越低越利于重构。同时我们也不要妄想一下子设计出一个完美的系统,毕竟人也不是上帝。此外还要学会利用别人已经完成的功能,在我的程序里面</span></font><font size="2">XML</font><font face="宋体, SimSun" size="2"><span lang="zh-CN">解析,日志生成都是使用了别人的成果。不要想着大包大揽,毕竟站在巨人的肩膀上才更容易成功。</span></font> </p> <p class="western" style="text-indent: 0.29in; margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="margin-bottom: 0in;"> <font size="2"><br></font> </p> <p class="western" style="margin-bottom: 0in;" align="center"> <font size="2"><br></font> </p>Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-45621646209319243072007-05-07T18:49:00.000-07:002009-02-11T20:05:59.851-08:00哭泣的美女与剧痛的嗓子<br /><br />昨天晚上老婆又痛哭流涕了。原因是我有的时候非常狠心。原来我对她的伤害她不曾忘记,她对于我的不满在不断的升级。生活就是要不断的谅解,人不能总生活在过去的阴影里面。谁没有犯过错误?这个世界上没有完美无缺的人,因此我们也不能要求完美无缺。我就懂得这一点,我从来不要求什么完美无缺的。不断撕扯过去的伤口,那么人永远也不能恢复健康。健康的人才是有用的人。<br /><br />其实这也没有什么,我有的时候觉得自己很对不住我的老婆。主要原因就是我不够强势。<br /><br />其实我老婆这个人是一个普普通通的人我喜欢。她很敏感,容易受到伤害。<br /><br />原谅别人是一种美德。不能原谅的话就要离开。如同能活着就活着,不能的话就去死。<br /><br />嗓子剧痛无比,晚上反反复复的做这一个同样的梦。为什么让我这么痛苦?我从来不曾伤害别人。当然我知道这个不是理由。不爱自己就是一种罪过。<br /><br />男人不能没有女人,如同女人不能没有男人一样。这是一个什么道理呢?不知道。我也不懂。就觉得这是一个规律。<br />Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-39753563942882870952007-04-18T19:05:00.000-07:002007-05-08T19:19:18.586-07:002007年4月18日-现实与梦幻<br><br>我时常迷惑在现实与梦幻之间。原因说来也简单,就是现实不能为我带来快感。而梦幻似乎可以,至少我能够将自己想像成一个伟大的了不起的人物。然而这一切又有什么意义呢?古时候有一个黄粱美梦的故事,这个故事的主角在梦中完成了他的另一个人生,不知道当他醒来的时候,他是会有什么感想呢?人一定q要有所追求。当我在我的梦境中流连忘返的时候,我知道自己没有追求,不知道自己想要干什么,做什么。前一段时间我去了相山上的那个正在翻修的庙宇,在庙的里面,刚一进庙门的时候,墙上就有一些所谓的劝世歌和醒世诀无非都是一些告诉我们通常我们所追求的都是空的无聊的话。不过说句实话,我的的确确没有什么追求。难道我想死么?我也不知道。我好困惑。<br><br>我是一个需要快乐的人,没有快乐我觉得自己活着没有什么意义了。然而,快乐在哪里呢?<br><br>当我坐在这里思考的时候,我觉得自己感觉非常的不好,有一种孤独的痛苦在折磨着我。<br><br><br> Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-9568963763325479582007-04-16T18:37:00.000-07:002009-02-11T20:02:22.672-08:00控欲<br /><br />人要控制自己的欲望,要有所追求<br /><br />很多话说起来容易,但是做起来比较难,有的时候甚至做也不知道如何去做,这恐怕是一件非常遗憾的事情。就如这篇文章的开头一样,说着容易而且很有道理,但是去做却很难。当一个人没有什么特定的追求的时候,我想他可以简单一些,追求名利。追求利是最朴素的追求,因为人要生存,生存依赖于物质,利就是物质。所以追求名利是人的本能,也是社会进步的基本<br /><br />你可能不知道你要追求什么,其实这没有关系,好好的过好每一天,做好自己的本职工作,不抱怨,不牢骚。这是基本。然后就是追求。这是从无到有的过程,首先什么也没有,然后渐渐什么都有了。因为人首先要了解自己,要体悟生活。要了解这个世界。人生存在世界上,鉴于认识有意识的,所以实际上你所关注的不可能仅仅是当代现在发生的事情。我这样说,是因为人要了解自己是很困难的。人生在一个社会环境中,这个环境很复杂,而且时间的延伸增加了这种复杂性。算了,不说了,也许你已经了解我的意思了。呵呵。<br /><br />人无论高下都有追求,只是追求的境界有所不同,这个境界其实是对个人而言的。也没有好坏高下之分。Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-46853737633066095042007-04-12T18:53:00.000-07:002009-02-11T20:03:14.537-08:00至乐无乐,至誉无誉<br /><br />无的思想是一种奇高的境界。正如孙子所说:“善战者,不战而屈人之兵。”;而善战者无赫赫之功,因为他能够防患于未然,在问题还没有发生的时候,就把问题解决了。这些心灵的修养之道来自于古代,战国时期,距今已有2000多年了。能不感慨么?<br /><br />无为之为<br /><br />无并非真正的无,是精神的无,而不是物质的无。人不可能离开物质,但是人的精神是独立的。人的精神其实是物质世界的反映,人的一切都不可能离开物质。我们所说的道,其实也是物质世界的规律,所谓真理,指的也是物质世界的真理。不管你怎么想,你是不可能离开这个物质世界的。你的精神可以和物质对抗,但是你的身体不行。人的精神也依托于物质存在。而物质是什么的?物质是没有意识的。它依规律而行,没有自己的意识。天地不仁以万物为刍狗。相对于物质世界,精神就是无,是不存在的。是我们自创的规律。呵呵,说不清楚。我都不知道自己在说些什么,但这些就是自己的一些感悟。很难确切的描述出来。借用庄子中的一句话:“若夫不刻意而高,无仁义而修,无功名而治,无江海而闲,不导引而寿,无不忘也,无不有也,淡然无极而众美从之。此天地之道,圣人之德也。”这种行为很符合自然之道。所以每个人都要找到自己的道,每个人存在的意义都是不同的,这个需要你自己去寻找。<br /><br />道常无为,而无不为<br /><br />这是老子说的。我特别想问,天地是否也有追求。天地是没有追求的,因为天地是没有意识的。物质世界依法而动,它是没有意识的。而人不同,人可以有追求,因为人有意识,人不可能无为而无不为。<br /><br />事实上我觉得道家的思想其实是很唯物的。它说的无,不是什么都不干,而是要求你顺应自然,依规律办事。做事情要符合客观规律,这样才能把事情干好。<br /><br />逍遥而游,无为而为<br /><br />君子误国 :公但知小人能误国,不知君子之尤能误国也。小人误国犹可解救,若君子而误国,则未之何矣。何也?彼盖自以为君子而本心无愧也。故其胆益壮而志益决,孰能止之。Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0tag:blogger.com,1999:blog-1154884446667282815.post-23484173686727072682007-04-09T02:13:00.000-07:002009-02-11T20:04:21.656-08:00好吧 ,其实我想说这仅仅是我的一个测试。<br /><br />自我以及欲望<br /><br />我和我的欲望<br /><br />多数情况下,我似乎希望了解欲望的缘由,其实大多的时候,欲望没有缘由,仅仅是一种心理和潜意识的需求而已。目前我接受这方面的知识是非常的稀少的。由于所知甚少所以难以明了什么。我到底希望的到什么,而我又能够得到什么呢?<br /><br />每个人都有自己的欲望,我不知道别人怎么样,仅仅就我自己而言,我觉得我自己还是比较正常的人。我对金钱有欲望,对性有欲望,大多数时候性的欲望还要大于金钱的欲望,因为性的欲望比较容易得到满足,而且还能带给人快感,这种快感不是金钱能够代替的。<br /><br />其实,任何时候,虚妄的东西都不会是好的。我们应该着眼于实际,看看现实世界中有没有能够让自己得到满足的东西?满足什么?自己的虚荣心。说道虚荣,其实每个人都有虚荣心。没有虚荣的人其实是不存在的。有关系么?其实没关系。虚荣也好,也许正好是我们所需要的。<br /><br />有的时候我们看历史,读小说,都是为了得到某种体验,或者说是一种虚幻的快感,当然这种快感也不一定是虚幻的。古人说:“书中自有黄金屋,书中自有人如玉。”我 觉得这种描述好像是在说小说,读小说有意义么?没有,读小说完全是为了一种娱乐呀。人需要娱乐么?我觉得不一定需要,但是人不能总生活在压力下面。固然人需要有所追求,但是有的时候也需要放松。<br /><br />我只是想说,其实对于我们的欲望我们要量力而为,不能放纵,不能纵欲。同时应该利用自己的虚荣去获得让自己进步的力量。自古以来人们常常提到要修心养性,但是如何做到?一直以来也没有一个什么固定的好的方法可以使用。不过我也不知道。所以也没法说。<br /><br />前一段时间看小说,一个牛人写的:徐公子胜××;有文化,虽然是网络娱乐文学但是写的比一般的yy强得多了。我觉得写书就应该有那样的水平。小说也不应定都不好吧。这个书中在谈道和如何修炼。神通我当然是不信的。就算有一般人也不可能很容易的得到,还是安心工作赚钱来的实际一些。但是修炼如果是一种内心的感受我觉得很多时候还是比较有道理的。所谓修行就是一个过程,认识真的过程。什么叫真?可以解释为真理。真理就是恒古不变的道理尽可以是唯物的,也可以是唯心的,没有强求一定是什么。修炼追求的当然不是什么神通,神通怎么会有呢?提高自己的能力还是比较实际的。比如说理解能力和计算能力。而其实这些也不是那么好得到的,也同样需要自己去努力。因此一个有所追求的人还有什么时间去娱乐自己呢?没有时间。当你把大把的时间奢侈浪费掉之后,也许你会后悔。<br /><br />这仅仅是一些散记,我想我其实也没有什么太理论化的东西而自己所理解的哲学的体系,比如说认识论和辩证法以及唯物论都是前人的思想就算自己理解了也不能够算作是自己的创造吧。<br /><br />一切从实际出发我看到了什么?仅仅是时间的流逝么?Gavinhttp://www.blogger.com/profile/07306653054082844241noreply@blogger.com0