2006年1月1日
#
Java 8之前,同一注解不能在相同的目標(biāo)元素上多次使用,例如,如下的注解在Java 8之前是不允許的:
public class SampleClass {
@Quality("Security")
@Quality("Performance")
@Quality("Readability")
public void foo(){
//
}
}
Java 8引入了Repeatable注解(@Repeatable)可以解決這一問(wèn)題,但光有可重復(fù)的注解定義還不夠,還需要它的容器注解,兩者一起來(lái)實(shí)現(xiàn)可重復(fù)注解的使用。實(shí)例如下:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
@Repeatable (Qualities.class)
public @interface Quality {
String value();
}
@Target(ElementType.METHOD)
public @interface Qualities {
Quality[] value();
}
其中,Quality是可重復(fù)注解,由@Repeatable注解標(biāo)明,它的容器注解是Qualities,用于存放所有可重復(fù)的Quality(存貯在Quality[]中);同時(shí)還要注意可重復(fù)注解和它的容器注解的目標(biāo)元素必須是一樣的(這也不言自明)。如此這般,我們最開(kāi)始的
SampleClass 在Java 8環(huán)境下就可以安全使用了。
以下單例實(shí)現(xiàn)思想來(lái)自《Java Design Patterns: A Programmer's Approach》.
該方法利用了Java缺省的Lazy類實(shí)例化機(jī)制克服了傳統(tǒng)單例模式實(shí)現(xiàn)中Lazy實(shí)例化方式的不足。
public class Singleton {
private Singleton(){}
public static Singleton getInstance(){
return Helper.instance;
}
static class Helper {
private static Singleton instance = new Singleton();
}
}
以下轉(zhuǎn)自StackOverflow(
http://stackoverflow.com/questions/5074063/maven-error-failure-to-transfer),親測(cè)可用。
This worked for me in Windows as well.
- Locate the {user}/.m2/repository (Using Juno /Win7 here)
- In the Search field in upper right of window, type ".lastupdated". Windows will look through all subfolders for these files in the directory. (I did not look through cache.)
- Remove them by Right-click > Delete (I kept all of the lastupdated.properties).
- Then go back into Eclipse, Right-click on the project and select Maven > Update Project. I selected to "Force Update of Snapshots/Releases". Click Ok and the dependencies finally resolved correctly.
當(dāng)我們寫(xiě)Groovy腳本代碼的時(shí)候,有時(shí)會(huì)發(fā)生編譯錯(cuò)誤,如下:
- Groovy:Invalid duplicate class definition of class XXX : The source XXXX\XXX.groovy contains at least two
definitions of the class XXX.
- The type XXX is already defined
原因在于Groovy會(huì)把.groovy代碼文件作為腳本或類定義來(lái)處理,例如如下代碼:
class Order {
def security
def value
private buy_sell(su, closure) {
security = su[0]
quantity = su[1]
closure()
}
def getTo() {
this
}
}
def methodMissing(String name, args) {
order.metaClass.getMetaProperty(name).setProperty(order, args)
}
def getNewOrder() {
order = new Order()
}
Integer.metaClass.getShares = { -> delegate }
Groovy會(huì)把上述代碼作為腳本處理,同時(shí)缺省用文件名來(lái)作為一個(gè)外圍類類包括整個(gè)腳本程序,此時(shí),如果該文件名恰好也是Order的話,那么就會(huì)出現(xiàn)重復(fù)的類定義錯(cuò)誤提示。
解決辦法是將腳本文件名取另外一個(gè)不同的名字。
已經(jīng)申請(qǐng)OCUP中級(jí)考試的學(xué)員可以在一年內(nèi)(截止到17年9月份)免費(fèi)申請(qǐng)OCUP2中級(jí)考試的資格(原有考試仍可以參加)。此外,2014年3月份之后參加了原有OCUP中級(jí)認(rèn)證考試的學(xué)員可以免費(fèi)申請(qǐng)OCUP2中級(jí)認(rèn)證考試。詳見(jiàn)OMG網(wǎng)站聲明(http://www.omg.org/ocup-2/exam-info.htm)。
搬家總是難免的,但舊家的東西不能帶走難免會(huì)留下些許遺憾,希望它們能永遠(yuǎn)留下來(lái).......
歡迎光臨我的新家:
http://blog.sciencenet.cn/?53016 (科學(xué)網(wǎng))
轉(zhuǎn)自網(wǎng)絡(luò)。
3歲,他去上幼兒園了,看著他小小的堅(jiān)強(qiáng)的背影,心中又喜悅又有點(diǎn)小小的心酸。離別了一整天,孩子看到你高興得奔跑過(guò)來(lái),撲在你的懷里。跟你說(shuō):媽媽,我想你了。那一刻,抱著孩子就像抱著了整個(gè)世界。
6歲,他上小學(xué)了,孩子終于走進(jìn)校門(mén),這是多么值得紀(jì)念的事情,孩子的人生從此翻開(kāi)了新的篇章,卻沒(méi)想到,這也是孩子離開(kāi)我們的第一步。他已經(jīng)對(duì)與你分開(kāi)一天習(xí)以為常了,而且他喜歡每天去學(xué)校,這是他更喜歡的生活。甚至,他有時(shí)還會(huì)說(shuō):媽媽,在家好無(wú)聊,沒(méi)有小朋友和我玩。
12歲,他上初中了,甚至有的開(kāi)始上寄宿學(xué)校,一個(gè)月或者幾個(gè)月回一次家,見(jiàn)上一次面。他們開(kāi)始不再依賴你,甚至,他們喜歡和你對(duì)著干。你想幫他們做點(diǎn)事情,他們說(shuō):媽媽,我自己來(lái)吧。突然覺(jué)得這句話讓我們覺(jué)得好失落,孩子是不是不再需要我們了?
18歲,他離開(kāi)你去上大學(xué),一年回來(lái)兩次。回來(lái)的好幾天前,家里的冰箱就裝不下了,為他準(zhǔn)備了各種各樣他喜歡吃的東西。可是一回來(lái)打個(gè)照面,他就忙著和同學(xué)朋友聚會(huì)去了。從此,你最怕聽(tīng)到的一句話是:媽媽,我不回家吃飯了,你們自己吃吧。
大學(xué)畢業(yè)后,孩子留在了遠(yuǎn)方工作,一年也難的回來(lái)一次了。好不容易回來(lái)一趟,幾天就走了。你最盼望的就是孩子的電話,希望,孩子對(duì)你說(shuō)一聲:媽媽,我很好,你保重身體。這樣就足夠了。
孩子結(jié)婚了,回家的時(shí)間有一半勻給了你的親家,孩子回來(lái)的更少了。你已經(jīng)習(xí)慣就老兩口在家了,但是,你最希望聽(tīng)到孩子對(duì)你說(shuō):媽媽,今年過(guò)年我回家過(guò)啊!
當(dāng)孩子又有了他們自己的孩子,你已經(jīng)不再是他們的家庭成員了,他們的一家三口(或一家n口)里,已經(jīng)不包括你們了。
而我們也慢慢的習(xí)慣了這樣的日子。只是習(xí)慣在閑來(lái)無(wú)事的時(shí)候,經(jīng)常翻翻相冊(cè),看看我們自己的一家三口,無(wú)論孩子身在何方,他卻永遠(yuǎn)是我們家庭中無(wú)可取代的一員。
是啊,其實(shí)當(dāng)孩子在身邊的日子,我們是多么幸福。可是有時(shí)我們卻還會(huì)抱怨。抱怨因?yàn)樗阕隽颂嗟臓奚1г顾砩侠闲褋?lái),讓你睡不好,抱怨他無(wú)理取鬧,抱怨他愛(ài)撒嬌長(zhǎng)不大,抱怨他生病,讓你操碎了心,抱怨為了培養(yǎng)他,花費(fèi)了太多的精力與金錢(qián)...可是,如果你想想,10多年后,就算你想要,也沒(méi)有機(jī)會(huì)了。孩子會(huì)不停的長(zhǎng)大,過(guò)了這個(gè)時(shí)期他就再?zèng)]有這個(gè)時(shí)期的習(xí)性。你是不是常常在他斷奶后懷念喂他吃奶的日子,可是那時(shí)你卻覺(jué)得好累好辛苦好厭倦。是不是常常看他以前吃手的照片覺(jué)得好可愛(ài),可是你曾經(jīng)卻為要不停的給他洗手而煩惱透了。是不是在他褪去童聲后,特別想念他曾經(jīng)奶聲奶氣的聲音,可是他以前撒嬌的時(shí)候你卻很不受用。是不是當(dāng)孩子去上學(xué)后你特別懷念他黏在你身邊的日子,可是以前你卻總在想他要什么時(shí)候才能去上學(xué)啊。。。
時(shí)間無(wú)法倒流,過(guò)去了就只能永遠(yuǎn)過(guò)去了。孩子能呆在身邊的日子是多么難得與寶貴。因?yàn)檫@一點(diǎn),我更加的珍惜與孩子相處的每一刻,也讓我無(wú)論遇到什么,都心存感恩。謝謝上天給我這么一個(gè)孩子,讓我分享與見(jiàn)證他成長(zhǎng)的每一刻。無(wú)論帶給我多少困難,煩惱,甚至挫敗,無(wú)論讓我失去多少睡眠,時(shí)間,金錢(qián),精力,我仍然豁達(dá),因?yàn)椋@都是上天的恩賜。
當(dāng)他在身邊的每一天,我都會(huì)讓他覺(jué)得幸福,也是讓我們都有一個(gè)美好的回憶。我不會(huì)給他太多壓力,束縛,更不會(huì)給他牽絆,阻擾,但是我會(huì)適時(shí)管教,也會(huì)做量力而行的投資,因?yàn)槲矣胸?zé)任與義務(wù)教會(huì)他生活的本領(lǐng),好讓他來(lái)日自由快樂(lè)的飛翔。同時(shí),我也會(huì)告訴他,就算所有的路都行不通時(shí),還有一條路你可以暢行,那就是回家的路。。。。。。。。
今日編輯一PDF文件(用的是Adobe Acrobat Pressional 7.0),刪除了幾頁(yè),然后保存,結(jié)果文件大小反而增加了;而刪除幾頁(yè)后另存,則文件大小減少。
你也試試看。
Robert L. Glass在《Negative Productivity and What to Do about It》(詳見(jiàn)IEEE Software, September/October 2008, p. 96)闡述了自己對(duì)那些影響項(xiàng)目進(jìn)度的人的親身感受和對(duì)此應(yīng)采取的解決方案。
作者以個(gè)體差異開(kāi)頭(作者指出,在軟件工程文獻(xiàn)中提到過(guò)非常大的個(gè)體差異:28:1 (for error identification) to 25:1 (for coding ability) to 11:1 (for timing efficiency) to 6:1 (for sizing efficiency)。但不幸的是,這些差異并沒(méi)有得到我們足夠的認(rèn)識(shí),作為實(shí)踐者,我們不知道如何鑒別出那些是別人28倍生產(chǎn)力的人,他們對(duì)于按時(shí)交付高質(zhì)量的軟件非常重要;作為研究者,在案例研究中也沒(méi)有對(duì)個(gè)人進(jìn)行足夠的區(qū)分,這將導(dǎo)致對(duì)結(jié)果的誤讀。),然后引出對(duì)項(xiàng)目進(jìn)展帶來(lái)負(fù)作用(影響項(xiàng)目進(jìn)度)的人''(someone who has negative productivity—that is, someone whose inclusion on a project actually makes the project less efficient.)'',接著以自己的親身經(jīng)歷的三個(gè)例子做了闡述:
1. Disfunctional labor relations. 項(xiàng)目(與軟件無(wú)關(guān))組被抽走一人,卻發(fā)現(xiàn)生產(chǎn)力提高了;這個(gè)案例讓作者意識(shí)到項(xiàng)目中存在讓人不易覺(jué)察的對(duì)項(xiàng)目生產(chǎn)力產(chǎn)生負(fù)影響的人;
2. Moral rebellion. 作者所帶領(lǐng)的項(xiàng)目組中存在一個(gè)對(duì)公司存在性不認(rèn)同的人,導(dǎo)致項(xiàng)目進(jìn)度滯后,使作者受到了軟件職業(yè)中最差的評(píng)價(jià);
3. Overly high standards. 作者所在的項(xiàng)目組由于一個(gè)對(duì)質(zhì)量要求非常嚴(yán)的QA,總是對(duì)提交的產(chǎn)品不滿意,結(jié)果導(dǎo)致產(chǎn)品遲遲不能交付。
對(duì)待這些人,作者給出了自己的解決方案:解雇他們。''(If someone on your project is deliberately delaying its progress, there’s probably only one reasonable solution. Fire them! If you don’t, your team will be sorry, your company will be sorry, and, quite likely, you’ll be sorry as well!)''
第九屆全國(guó)軟件與應(yīng)用學(xué)術(shù)會(huì)議(NASAC 2010)如期(11.4~11.7)在蘇州大學(xué)舉行,對(duì)于本次會(huì)議,有以下幾點(diǎn)感受:
1. 學(xué)術(shù)水平有待提高(投稿主體還是以碩士生為主,尚不能吸引國(guó)內(nèi)高水平文章);
2. 學(xué)術(shù)交流有待提高(本次會(huì)議的很多短文都未準(zhǔn)備Poster,演示和茶歇的環(huán)境很有限);
3. 會(huì)議招待有待提高(除了歡迎宴以外,就都是自助了,很單一,應(yīng)該多樣化一些);歡迎晚宴很一般,由于專委沒(méi)有參加,所以缺少了很多交互,沒(méi)有節(jié)目,沒(méi)有致辭,就是一味的吃
本次會(huì)議的收獲是認(rèn)識(shí)了一些同行,并與北大和復(fù)旦的相關(guān)研究人員就軟件復(fù)用和產(chǎn)品線相關(guān)實(shí)踐以及企業(yè)應(yīng)用實(shí)踐的相關(guān)問(wèn)題進(jìn)行了討論。還有就是吃到了正宗的陽(yáng)澄湖大閘蟹(一公一母)。
蘇州風(fēng)光很好,游覽了一些古街,小橋流水,無(wú)限柔美,但環(huán)境保護(hù)還有待加強(qiáng),經(jīng)常可以看到吸煙的把煙頭從湖水中扔,還有吐痰的......,要是蘇州在國(guó)外,一定會(huì)更美。
9.13至9.17日,第十四屆國(guó)際軟件產(chǎn)品線會(huì)議
(SPLC 2010)在韓國(guó)濟(jì)州島的
華美達(dá)酒店舉行。這是SPLC第二次來(lái)到亞洲(上次是2007年在日本。作為軟件工程知名會(huì)議,SPLC輪流在美洲、亞洲和歐洲舉行,是系統(tǒng)化軟件復(fù)用的專業(yè)會(huì)議)。
作為與工業(yè)界聯(lián)系比較緊密、體現(xiàn)軟件工業(yè)化的主流會(huì)議,SPLC 2010并未得到國(guó)內(nèi)的關(guān)注,這在一定程度上體現(xiàn)了國(guó)內(nèi)工業(yè)界的相對(duì)落后的局面(既沒(méi)有產(chǎn)品線的實(shí)踐,又缺乏對(duì)先進(jìn)軟件生產(chǎn)方式的跟蹤與研究)。
本次的參會(huì)者來(lái)自國(guó)內(nèi)的只有 5 人(包括我和導(dǎo)師,分別來(lái)自北京大學(xué)、上海交通大學(xué)、東北大學(xué)和公安部第一研究所)當(dāng)然也有一些海外華人(老師和在讀的博士(后))。會(huì)議論文集收錄了來(lái)自國(guó)內(nèi)的一篇短文、一篇Poster(我們的),以及一篇工業(yè)化論文。對(duì)我來(lái)講,最大的收獲在于開(kāi)闊了視野、了解了一些當(dāng)前最新進(jìn)展和認(rèn)識(shí)結(jié)交了一些新朋友,當(dāng)然,這也是我第一次出國(guó),雖然離家很近。
值得一提的是,來(lái)自公安部第一研究所的李東老師參加了
Software Product Line Fame of Hall競(jìng)評(píng)演講(本次會(huì)議唯一的一個(gè)),至于能否加入Fame of Hall要等下次會(huì)議(SPLC 2011,慕尼黑)才能知曉,不過(guò)李老師所展示的航空安檢系統(tǒng)產(chǎn)品線已經(jīng)得到了與會(huì)絕大多數(shù)人員(好像沒(méi)有發(fā)現(xiàn)幾個(gè)不贊成的,呵呵)的認(rèn)可,很可能成為國(guó)內(nèi)第一家啊,祝福。
去年10月份向《計(jì)算機(jī)工程》投了一篇稿件,審稿加修改共耗時(shí)2個(gè)月,然后被錄用,說(shuō)安排在今年11月左右發(fā)表,結(jié)果今年10月份就發(fā)表了,本來(lái)是件好事,但我注意到的一個(gè)重要問(wèn)題是文章中刊出的“收稿時(shí)間”竟然是今年的5月份,我很驚訝,于是給編輯部留言問(wèn)是怎么回事,但始終沒(méi)有人答復(fù)。
如此大的時(shí)間差別(去年10月份到今年5月份那可是7個(gè)月之久啊),難道是編輯“手誤”,手誤也應(yīng)該做個(gè)解釋啊,怎么就是不回留言呢。之前我也注意到一些發(fā)表的論文(10月份之前發(fā)表的)中刊出的“收稿時(shí)間”大概也在今年的2,3月份,當(dāng)時(shí)我還想怎么這么多在我之后收稿的卻在我之前發(fā)表呢,看來(lái)這也許是一種故意行為,“潛規(guī)則”!!!
難道出版社就為了顯示自己發(fā)表周期短欺騙廣大科研工作者嗎?先不說(shuō)這本身就是學(xué)術(shù)不端,重要的是它直接給投稿者帶來(lái)了巨大的風(fēng)險(xiǎn)——剽竊。試想一篇思想類似的文章如果是在去年10分之后投稿如果發(fā)表了(當(dāng)然前提是其它期刊刊出的收稿時(shí)間是真實(shí)的),那會(huì)是什么情況??不用說(shuō)別人肯定認(rèn)為是我剽竊,所以收稿時(shí)間應(yīng)該是絕對(duì)真實(shí)的,我想這也是這個(gè)信息在文章中出現(xiàn)的主要價(jià)值!!!!。另外的小問(wèn)題就是給投稿者的工作量/績(jī)效統(tǒng)計(jì)帶來(lái)不便,明明是去年的工作量怎么體現(xiàn)的是今年的時(shí)間,萬(wàn)一領(lǐng)導(dǎo)復(fù)查,怎么說(shuō)清楚呢。
結(jié)論,再也不向此刊投稿了。
轉(zhuǎn)自InfoQ:http://www.infoq.com/cn/news/2009/09/study-multitasking-performance
----------------------------------------------------------------------------------------------------------
斯坦福大學(xué)上個(gè)月在Proceedings of the National Academy of Sciences學(xué)報(bào)上發(fā)布了一個(gè)研究結(jié)果:“媒體行業(yè)中多工人員(multitasker)的認(rèn)知控制”,強(qiáng)調(diào)指出一個(gè)顯而易見(jiàn)的事實(shí):從效率的角度考慮同時(shí)從事多任務(wù),絕對(duì)會(huì)影響工作效率。該研究審視了IT領(lǐng)域中一個(gè)廣為人知、卻常常為人忽略的現(xiàn)象:不斷出現(xiàn)、正在發(fā)生的多任務(wù)工作方式。敏捷實(shí)施者們這樣寫(xiě):這下可算有理由讓團(tuán)隊(duì)只開(kāi)發(fā)一個(gè)產(chǎn)品了,而且只能有一個(gè)產(chǎn)品負(fù)責(zé)人——將時(shí)間花在多個(gè)任務(wù)之上絕對(duì)是效率低下的工作方式。
Wired雜志指出:雖然其他研究重點(diǎn)關(guān)注多任務(wù)工作方式的眼前效果(比如:辦公室里的工作人員經(jīng)常檢查郵件,這種情況下的工作效率),該研究提出了一個(gè)不同尋常的問(wèn)題:“要是人們總在使用多任務(wù)工作方式會(huì)怎么樣?”Stanford的研究者Clifford Nass、Anthony Wagner和Eyal Ophir調(diào)查了262名學(xué)生的媒體消費(fèi)習(xí)慣。19名使用多任務(wù)方式最多的學(xué)生和22名多任務(wù)方式最少的學(xué)生此后參加了兩個(gè)電腦測(cè)試,集中精力完成手上的測(cè)試。
他們使用了一些標(biāo)準(zhǔn)的心理測(cè)試指標(biāo),研究結(jié)果顯示出:經(jīng)常在多個(gè)信息流之間轉(zhuǎn)換的學(xué)生,他們會(huì)在e-mail、網(wǎng)頁(yè)、視頻、聊天和電話之間來(lái)回切換,他們?nèi)〉玫倪M(jìn)展遠(yuǎn)低于不怎么采取多任務(wù)方式的學(xué)生。更令研究人員驚訝的是:在任務(wù)切換能力的測(cè)試上,“重度媒體多任務(wù)人士”表現(xiàn)更差,“似乎他們過(guò)濾不相干任務(wù)的干擾的能力更差。”
該研究再次強(qiáng)調(diào)了認(rèn)知科學(xué)家反復(fù)提到的事情:同時(shí)處理多個(gè)信息流的輸入被認(rèn)為是人類認(rèn)知能力的問(wèn)題。
對(duì)于造成差異的原因——被定位使用多任務(wù)方式的人是不是先存在心智上的不健全,還是說(shuō)多任務(wù)方式造成了這種情況——“這是一個(gè)需要投入上百萬(wàn)美金才能回答的問(wèn)題,可是我們沒(méi)有一百萬(wàn)美金去取得答案。”Ness這么說(shuō)。
Wagner接下來(lái)打算用腦部造影方法來(lái)研究多任務(wù)方式的神經(jīng)學(xué)解釋,而Ness將會(huì)研究?jī)和巳涸诙嗳蝿?wù)習(xí)慣上的發(fā)展。
本文是對(duì):
Linda Wilbanks. IT Productivity = ??. IT Pro, November/December 2009, pp. 64, 63
的總結(jié)。
文章探討了什么事生產(chǎn)效率(或工作效率,但并沒(méi)有深入,只是個(gè)引子),以及如何提高(員工)的工作效率。
文章開(kāi)頭指出,“productivity”(生產(chǎn)力,此處譯為工作效率)通常被定義為生產(chǎn)效能(efficiency)、度量(metrics),以及在生產(chǎn)過(guò)程中單位輸入得到的產(chǎn)出的衡量。但對(duì)IT人員來(lái)說(shuō),什么是生產(chǎn)效能呢?作者給出了一個(gè)非正式的定義“一個(gè)有效率的人是指那些能夠在指定的時(shí)間內(nèi)以高質(zhì)量的方式完成指定工作的人。”這引出下一個(gè)問(wèn)題:我們?nèi)绾巫隹梢允箚T工更有效率?
作者援引Mr. Elgan在2009年4月5號(hào)的Computerworld那期中的一篇文章“Why Goofing Off at Work Boots Productivity"中的話說(shuō),
那些偷偷在Fackbook和Twitter上花少量時(shí)間的辦公室“懶鬼”(slacker)比那些全部時(shí)間都用來(lái)做工作的人能做更多的工作。墨爾本大學(xué)的研究人員在一項(xiàng)新的研究中證實(shí)了這種真實(shí)性。他們的研究發(fā)現(xiàn),一般來(lái)說(shuō),那些為了個(gè)人原因在工作時(shí)間內(nèi)使用Internet的人比不用的人效率高9%。

作者指出,盡管Mr. Elgan沒(méi)有指出這些研究者是如何衡量生產(chǎn)率的,但他給出了為什么那些在Internet上花費(fèi)時(shí)間的人更具有效率的一些原因:
- 潛意識(shí)仍然關(guān)注于工作中的問(wèn)題,解決方案通常會(huì)在隨后出現(xiàn);
- “游手好閑”(Goof off)的時(shí)間是一段清理個(gè)人思想、消除個(gè)人顧慮的時(shí)間。在這一小段時(shí)間后,你會(huì)回來(lái)全身心的投入到工作中;
- 從項(xiàng)目或任務(wù)中的短暫休息也可能是在受教育(或?qū)W習(xí)),例如讀一些與工作無(wú)關(guān)的東西。這些信息有可能在以后幫你解決另外的問(wèn)題。
作者接著列舉了一些管理者們?cè)诓还膭?lì)計(jì)算機(jī)游戲或網(wǎng)絡(luò)沖浪的情況下建議所采用的提高員工效率的方式:
- 給員工有意義的工作。
- 承認(rèn)/賞識(shí)員工所完成的工作。
- 給員工為了最好完成工作所需要的工具。
- 批準(zhǔn)員工休息。
- 給予員工尊重。
作者還舉了一個(gè)例子,說(shuō)有個(gè)復(fù)有創(chuàng)造力的同事把鍵盤(pán)上的F1~F12都附加了新功能:
F1 Accurately reflect what’s in the building’s vending machines.
- F2 Display the current traffic report for the area.
- F3 Make every piece of software on your machine work exactly as advertised.
- F4 Play your favorite music to lower your blood pressure.
- F5 Bring up your favorite picture of the beach or of the place you plan to retire.
- F6 Show a running clock on how many hours you have left until you retire.
- F7 Show you where your kids or pets are (but be careful, this might not relieve stress!).
- F8 Automatically delete all emails that were sent “Reply All.”
- F9 Delete all meetings for the day, sending emails of regret to all attendees.
- F10 Show what your 401K balance was two years ago instead of today’s value.
- F11 Automatically start dinner/ESPN/CNN/soap opera (programmable to suit individual preferences).
- F12 Advance time to five minutes before quitting time on Friday of the current week.
作者最后指出,作為管理者,需要關(guān)注如何現(xiàn)實(shí)的鼓勵(lì)員工發(fā)揮他們最大的效率,還需要決定如何來(lái)優(yōu)化工作環(huán)境。只要求生產(chǎn)效而沒(méi)有適當(dāng)?shù)墓芾碇С趾唾Y源將適得其反。作者認(rèn)為,不時(shí)地準(zhǔn)備一塊蛋糕(不管什么原因)可以鼓勵(lì)團(tuán)隊(duì)和溝通。
By the way:作者是美國(guó)能源部國(guó)家核安全管理局的CIO。
轉(zhuǎn)自:http://www.sciencenet.cn/m/user_content.aspx?id=275801
1個(gè)民工>2院院士
話說(shuō)我國(guó)一特大型國(guó)有企業(yè)B從A國(guó)引進(jìn)了一條香皂包裝生產(chǎn)線,結(jié)果發(fā)現(xiàn)這條生產(chǎn)線有個(gè)致命缺陷:常常會(huì)有盒子里沒(méi)裝入香皂。總不能把空盒子賣(mài)給顧客啊。沒(méi)辦法,B企業(yè)向國(guó)務(wù)院S部打報(bào)告,S部指定兩院和C9高校聯(lián)合設(shè)計(jì)一個(gè)方案來(lái)分揀空的香皂盒,于是組成了一個(gè)11人的科研團(tuán)隊(duì),計(jì)有:中科院院士1人、中國(guó)工程院院士1人、北京大學(xué)863首席科學(xué)家1人、清華大學(xué)973首席科學(xué)家1人、上海交通大學(xué)長(zhǎng)江學(xué)者1人、浙江大學(xué)國(guó)家重點(diǎn)實(shí)驗(yàn)室主任1人、復(fù)旦大學(xué)“國(guó)家杰青”1人、南京大學(xué)國(guó)貼專家1人、哈爾濱工業(yè)大學(xué)國(guó)家大科學(xué)工程主任1人、中國(guó)科技大學(xué)引智計(jì)劃1人,當(dāng)中有海龜、陸龜、土鱉,還有博士后、博士、碩士、本科生,綜合采用了機(jī)械、微電子、自動(dòng)化、x射線探測(cè)、微機(jī)編程等技術(shù),花了100萬(wàn)元,成功解決了問(wèn)題。每當(dāng)生產(chǎn)線上有空香皂盒通過(guò),兩旁的探測(cè)器會(huì)檢測(cè)到,并且驅(qū)動(dòng)一只機(jī)械手把空皂盒推走。
南方有個(gè)鄉(xiāng)鎮(zhèn)企業(yè)也買(mǎi)了同樣的生產(chǎn)線,四川老板發(fā)現(xiàn)這個(gè)問(wèn)題后大為發(fā)火,找了個(gè)湖南的小工來(lái)說(shuō):你他媽的今天給老子把這個(gè)搞定,不然明天你給老子滾蛋......小工很快想出了辦法:他在生產(chǎn)線旁邊放了臺(tái)風(fēng)扇猛吹,空皂盒自然會(huì)被吹走。
這個(gè)故事告訴我們:
1,知識(shí)不一定就是生產(chǎn)力,創(chuàng)造力和學(xué)歷、學(xué)識(shí)、學(xué)銜不直接相關(guān)。
2,能吹是多么的重要,院士也能吹出來(lái)。
3,民科是值得尊重的,應(yīng)該與官科享受同等待遇。
4,再次證明人民的智慧是無(wú)窮的,歷史是群眾創(chuàng)造的,是普通的勞動(dòng)人民創(chuàng)造的。
本文是對(duì)Steve Vinoski. Multilanguage Programming.
IEEE Internet Computing, Vol. 12, No. 3, MAY/JUNE 2008, pp. 83-85 的總結(jié)。
本文的主要觀點(diǎn)是:在軟件開(kāi)發(fā)中,要為特定的任務(wù)選擇最合適的開(kāi)發(fā)語(yǔ)言。
作者首先介紹了在軟件集成和軟件開(kāi)發(fā)中涉及的術(shù)語(yǔ)/技術(shù)浩如煙海,但是開(kāi)發(fā)者卻只堅(jiān)持某種技術(shù),而必須使用其它技術(shù)來(lái)解決問(wèn)題。這種現(xiàn)象在開(kāi)發(fā)語(yǔ)言領(lǐng)域也是一樣。開(kāi)發(fā)者總是使用自己喜歡的語(yǔ)言,而非解決問(wèn)題最優(yōu)的語(yǔ)言,會(huì)造成設(shè)計(jì)方案的不優(yōu)。
作者指出在日常開(kāi)發(fā)中了解和使用多種編程語(yǔ)言可以帶來(lái)顯著的好處,因?yàn)闆](méi)有任何一門(mén)語(yǔ)言適用于解決所有問(wèn)題。而語(yǔ)言的存在也主要是由于它適于解決某些特定方面的問(wèn)題(在解決某些問(wèn)題方面比其它語(yǔ)言好),因此,不斷有語(yǔ)言出現(xiàn)和消亡。在編程語(yǔ)言設(shè)計(jì)和開(kāi)發(fā)中涉及許多需要權(quán)衡的因素,因此,這為許多不同的方案和變體預(yù)留了空間。
作者指出,大部分單一語(yǔ)言開(kāi)發(fā)者傾向選擇用于通用目的的語(yǔ)言(像Java、C++等),而不是特定的編程語(yǔ)言。通用的編程語(yǔ)言可用于解決更廣范圍的問(wèn)題,但它們通常都是提供的折中的解決方案,不是太好,也不是太壞。當(dāng)然,一些單一語(yǔ)言開(kāi)發(fā)者盡力去挖掘語(yǔ)言的高級(jí)特性,來(lái)將語(yǔ)言的能力發(fā)揮到極致,但這些程序員仍然受制于這門(mén)語(yǔ)言實(shí)際的限度。
作者指出語(yǔ)言的選擇對(duì)開(kāi)發(fā)效率是一個(gè)重要因素,選擇正確的語(yǔ)言所帶來(lái)的開(kāi)發(fā)效率的提升是巨大和值得這么去做的。作者以對(duì)XML的處理為例闡述了此觀點(diǎn)。通用語(yǔ)言,例如Java在處理XML方面沒(méi)有專門(mén)設(shè)計(jì)上的支持,這使得開(kāi)發(fā)人員在使用通用語(yǔ)言處理XML方面忍受這種不匹配,來(lái)進(jìn)行拙笨的開(kāi)發(fā),造成非優(yōu)的解決方案。在這種情況下,為了提高效率,他們通常采用一些代碼生成技術(shù),把XML構(gòu)造塊影射為靜態(tài)編程語(yǔ)言的構(gòu)造塊(通常是類)來(lái)盡量緩解這種阻抗,即便如此,這種方式仍然是十分脆弱的。因?yàn)榘迅叨褥`活的XML構(gòu)造塊轉(zhuǎn)化為嚴(yán)格的靜態(tài)的數(shù)據(jù)類型很容易造成彼此版本的不匹配。XML文檔的任何改變都需要新的代碼生成、重新構(gòu)建、....這使得通過(guò)代碼生成獲得的一點(diǎn)點(diǎn)好處又被不斷維護(hù)帶來(lái)的成本所抵消。相比之下,Python、Perl、Erlang等語(yǔ)言都提供了XML處理模塊,甚至還帶版本化功能。更好的像ECMAscript for XML (E4X)和Scala,提供了對(duì)XML字面量的支持支持,開(kāi)發(fā)人員可以直接在語(yǔ)言語(yǔ)法中寫(xiě)XML。消除了阻抗,帶來(lái)了更簡(jiǎn)化的代碼和更清晰的功能。
作者指出,選擇適當(dāng)?shù)恼Z(yǔ)言所帶來(lái)的效率的提升還體現(xiàn)在對(duì)代碼的維護(hù)上。作者援引Fred Brooks在《人月神話》中引用的的研究發(fā)現(xiàn)說(shuō),所需開(kāi)發(fā)和維護(hù)的工作量與指令的數(shù)目(可以理解為代碼行)是指數(shù)關(guān)系,而且這與所采用的語(yǔ)言無(wú)關(guān)。假設(shè)這個(gè)指數(shù)值是1.5的話,那么如果代碼行是原來(lái)的3倍的話,那么就需要5倍的開(kāi)發(fā)和維護(hù)成本,如果代碼行變?yōu)樵瓉?lái)的5倍,就需要11倍的開(kāi)發(fā)和維護(hù)成本,如果代碼行變?yōu)樵瓉?lái)的10倍,那么就需要32倍的開(kāi)發(fā)和維護(hù)成本。選擇正確的語(yǔ)言,不僅可以減少代碼行,更快的提供解決方案和對(duì)需要的響應(yīng),這個(gè)過(guò)程可以變?yōu)榉e極的循環(huán),更少的代碼帶來(lái)更好的缺陷和更容易的增強(qiáng)(維護(hù)),這又使得用戶更高興,提供免費(fèi)的廣告宣傳和反饋,進(jìn)一步促進(jìn)軟件的發(fā)展。
作者指出,多語(yǔ)言編程的一個(gè)問(wèn)題就是如何使它們協(xié)同工作。這可以分為兩類。如果是用于分布式應(yīng)用集成(即不同的應(yīng)用用不同的語(yǔ)言),那么網(wǎng)絡(luò)本身就通過(guò)協(xié)議提供了一個(gè)中立的方案,可以通過(guò)網(wǎng)絡(luò)消息等。如果不是分布式應(yīng)用,當(dāng)前的主流開(kāi)發(fā)語(yǔ)言,比如微軟的CLT(公共語(yǔ)言運(yùn)行時(shí))所支持的語(yǔ)言越來(lái)越多,命令式的、動(dòng)態(tài)的、函數(shù)式的,或腳本的。類似的,JVM也從一個(gè)單語(yǔ)言平臺(tái)演化為一個(gè)可以支持許多語(yǔ)言的平臺(tái),包括JRuby、Scala、Groovy、JavaScript、E4X、Jython和其它的。而且,在JVM上,這些語(yǔ)言都容易學(xué),因?yàn)槎际腔谧止?jié)碼,這些語(yǔ)言可以與Java進(jìn)行互調(diào)。因此,JVM提供了一個(gè)非常好的方式來(lái)為應(yīng)用的不同部分選擇最適合的語(yǔ)言。
作者還指出目前阻礙多語(yǔ)言編程的因素主要有兩個(gè):一個(gè)管理因素;另一個(gè)開(kāi)發(fā)者認(rèn)為學(xué)習(xí)新語(yǔ)言難度很大。對(duì)于第一個(gè)因素,管理者通常認(rèn)為只采用一種語(yǔ)言易于管理,因?yàn)榇蠹叶加猛瑯拥恼Z(yǔ)言,可以容易的替換開(kāi)發(fā)人員,而且某個(gè)開(kāi)發(fā)人員寫(xiě)的代碼,大家也都能看懂,避免陷入只有少數(shù)人才能看懂和維護(hù)的局面。作者認(rèn)為這種管理者對(duì)軟件開(kāi)發(fā)和維護(hù)所涉及的成本沒(méi)有充分考慮。在一個(gè)JVM或CLR基礎(chǔ)之上,選擇合適的語(yǔ)言可以減少代碼規(guī)模和開(kāi)發(fā)維護(hù)的工作量,從而降低系統(tǒng)的總成本,而且,較小的系統(tǒng)需要更少的開(kāi)發(fā)者,這又是一個(gè)巨大的成本減少。對(duì)于第二個(gè)因素,相比通用語(yǔ)言來(lái)說(shuō),那個(gè)特定的語(yǔ)言,像Lisp、Python等都很簡(jiǎn)練,核心概念并不多,初學(xué)者可以很快發(fā)現(xiàn)它們更具有生產(chǎn)力,而且,以往語(yǔ)言的經(jīng)驗(yàn)可以幫助你學(xué)習(xí)新語(yǔ)言。如果你掌握的語(yǔ)言越多,你就能更容易的學(xué)習(xí)一門(mén)新語(yǔ)言,也能發(fā)現(xiàn)解決問(wèn)題的最好方式。
最后,作者以“畢竟,難道我們真的認(rèn)為我們已經(jīng)學(xué)到我們所需要的最后一門(mén)(終極)語(yǔ)言了碼?”結(jié)尾。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
歡迎您對(duì)自己所在的開(kāi)發(fā)組織對(duì)于多語(yǔ)言編程、融合的實(shí)踐和經(jīng)驗(yàn)發(fā)表看法,謝謝!
今天是部門(mén)年會(huì)活動(dòng)的日子,活動(dòng)項(xiàng)目:滑雪、年夜飯、卡啦OK
第一次學(xué)滑雪,是挺興奮的,11點(diǎn)鐘開(kāi)使滑,地點(diǎn)林海滑雪場(chǎng),剛開(kāi)始是50多米的小短坡, Easy,吃完午飯,開(kāi)始在200米的高坡滑,跟頭栽了不老少,也是長(zhǎng)了不少經(jīng)驗(yàn)。爽!,就是膝蓋太累了...
晚上又是一頓豐盛大餐....
1. 提供了磁盤(pán)分區(qū) - 空間方法
在File類中增加了以下方法:
public long getFreeSpace(): 返回一個(gè)分區(qū)剩余空間
public long getTotalSpace(): 返回一個(gè)分區(qū)總空間
public long getUsableSpace(): 返回一個(gè)分區(qū)已用空間
注意,以上File指代的虛擬路徑必須是盤(pán)符,否則返回0。
2. Splash Screen
Mustang對(duì)于Splash Screen的實(shí)現(xiàn)是一個(gè)用來(lái)顯示gif(可以是動(dòng)畫(huà)式的),PNG, jpg圖片的沒(méi)有修飾的窗口
使用方式:
在java命令行中加入 -splash 選項(xiàng),示例如下:
java -splash mypic.jpg HelloWorld如果你的類是以jar的方式來(lái)運(yùn)行,那么可以在jar文件的MANIFEST.MF文件中加入如下的一行:
SplashScreen-Image:mypic.jpg你也可以在命令行中寫(xiě):
java -splash:mypic.jpg -jar helloWorld.jar
這里用的圖片將替代MANIFESET.MF中定義的圖片(如果有的話)
為了實(shí)現(xiàn)自定義的Splash Screen界面,你可以使用如下的方法:
//使用SplashScreen的靜態(tài)方法獲得SplashScreen對(duì)象,然后自定義
SplashScreen ss = SplashScreen.getSplashScreen ();
if (ss != null)
{
// 自定義代碼。
}
在SpalshScreen中還提供了如下方法,具體使用請(qǐng)看JDK或訪問(wèn)sun網(wǎng)站
public Graphics getGraphics()
public URL getImageURL()
public Dimension getSize()
public void setImageURL(URL imageURL):
public void update()
值得注意的是:你必須使用 -spalsh選項(xiàng)或MANIFEST.MF的方式來(lái)調(diào)用SplashScreen,
否則修改是無(wú)效的。
昨晚,回到宿舍,正好趕上中央4套在播《名將之約》,這次邀請(qǐng)的名將是現(xiàn)任中國(guó)乒乓球隊(duì)總教練,劉國(guó)梁。
自己小時(shí)候就很喜歡乒乓球,到現(xiàn)在也是一樣,因此對(duì)于此類人物,自己是欽佩有加,更何況劉的輝煌戰(zhàn)績(jī),在國(guó)內(nèi)也是先有人出其右。本月十號(hào),就是他三十歲的生日,以近而立之年的他,已經(jīng)是中國(guó)乒乓球的總教練,讓人感覺(jué)前途不可限量,要登上這個(gè)高度是非常之不易。
今年,我也已經(jīng)27啦,時(shí)光飛逝,轉(zhuǎn)眼就會(huì)到30歲的那一天,作為程序員這個(gè)行當(dāng)中的一員,這個(gè)年齡雖然不是很大,但絕對(duì)不小,自己的明天在哪里?
30歲能達(dá)到什么高度?35,40呢?也許每一個(gè)IT人都會(huì)思考這個(gè)問(wèn)題,當(dāng)然也許有些牛人已經(jīng)是扶搖直上九萬(wàn)里,不必憂心此類問(wèn)題。
我們的公司很大,部門(mén)也很多,好幾千人的規(guī)模,項(xiàng)目經(jīng)理很多很多,而公司級(jí)的項(xiàng)目經(jīng)理,也就是資深項(xiàng)目經(jīng)理,再加上部門(mén)的領(lǐng)導(dǎo),什么技術(shù)總監(jiān),項(xiàng)目總監(jiān),部長(zhǎng),經(jīng)理......
人,只有踏踏實(shí)實(shí)的把他目前的工作做好,才能不斷提升自己,我從不懷疑這樣的真理。
今天又抖出這個(gè)老生常談的話題,一是有感而發(fā),再則警示自己:拋棄浮躁,潛心修行。
Oracle ADF(Application Developement Framework)是一套快速開(kāi)發(fā)企業(yè)級(jí)J2EE的MVC框架. Oracle在Model層和業(yè)務(wù)服務(wù)層上提供的缺省實(shí)現(xiàn)對(duì)開(kāi)發(fā)基于數(shù)據(jù)庫(kù)的應(yīng)用提供了極大的便利,尤其是它的ADF BC(Business components),這個(gè)微型的MVC框架提供了直接映射數(shù)據(jù)庫(kù)表的能力,結(jié)合View端的展現(xiàn)(Oracle 提供了桌面端Swing/JClient和Web端UIX的實(shí)現(xiàn)),開(kāi)發(fā)起來(lái)就如同用Borland的數(shù)據(jù)感知控件一樣。
Spring目前是J2EE社區(qū)一個(gè)比較火的框架,應(yīng)用的比較廣,那如何進(jìn)行二者的有機(jī)結(jié)合呢?
我們已經(jīng)習(xí)慣了Spring的IOC框架,方便的使用getBean()方法來(lái)獲得我們想要的對(duì)象,因此,如果能通過(guò)Spring來(lái)生成需要的對(duì)象,然后把這個(gè)對(duì)象注冊(cè)為Data Control(Oracle中數(shù)據(jù)感知組件),這樣就可以利用ADF BC的威力來(lái)快速構(gòu)建一個(gè)數(shù)據(jù)庫(kù)應(yīng)用。問(wèn)題的關(guān)鍵就在于ADF為每一個(gè)data control指定了一個(gè)工廠類屬性,而這個(gè)工廠類屬性的實(shí)例值需要我們用Spring來(lái)生成,就OK了。舉一個(gè)實(shí)際的例子:
在Spring中,我們定義了如下的接口:
package nl.amis.spring.hrm;
import java.util.List;
public interface HrmService {
public void setEmployeeDao(EmpDAO employeeDAO);
public List getAllEmployees();
public long getSalarySum();
}
配置文件為:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSourceDBDirect"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:orcl"/>
<property name="username" value="scott"/>
<property name="password" value="tiger"/>
</bean>
<bean id="employeeDAO" class="nl.amis.spring.jdbc.EmployeeJdbcDAO">
<property name="dataSource">
<ref local="dataSourceDBDirect"/>
</property>
</bean>
<bean id="hrmService" class="nl.amis.spring.hrm.HrmServiceImpl">
<property name="employeeDao">
<ref local="employeeDAO"/>
</property>
</bean>
</beans>
在Oracle JDeveloper開(kāi)發(fā)環(huán)境下,我們找到
nl.amis.spring.hrmServiceImp這個(gè)類,然后用菜單命令把它注冊(cè)為一個(gè)Data control組件。這個(gè)新生成的Data control缺省名字是:HrmServiceImplDataControl,查看它的屬性,有一個(gè)Factory class屬性,找到這個(gè)屬性所指的類,修改如下源碼:
Object bean = oracle.jbo.common.JBOClass.forName(beanClass).newInstance();上面的代碼就是生成HrmServiceImpl對(duì)象的代碼,把它改為:
ApplicationContext springCtx = new ClassPathXmlApplicationContext("SpringConfig.xml");
Object bean = springCtx.getBean("hrmService");這樣主要工作就OK啦,剩下的就是修改一下Data Control的配置文件(在注冊(cè)成為Data Control后生成的同名.xml文件),修改
<content>中的<AccessorAtribute>部分,把id改為:allEmployees; BeanClass 改為nl.amis.spring.hrm.Employee; IsCollection="true"; Type改為java.Util.List.
以上修改表明我們需要的是通過(guò)employeeDao獲得的Employee的集合,把這個(gè)結(jié)合作為結(jié)果集應(yīng)用到ADF BC中。
英文原文出自:
http://technology.amis.nl/blog/index.php?p=765
要調(diào)用的Web服務(wù)是求兩個(gè)整數(shù)和,并返回結(jié)果。
服務(wù)的WSDL文件內(nèi)容如下:
<?xml version="1.0" encoding="utf-8" ?>
<wsdl:definitions
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://tempuri.org/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
targetNamespace="http://tempuri.org/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified"
targetNamespace="http://tempuri.org/">
<s:element name="AddTwoIntegers">
<s:complexType>
<s:sequence>
<s:elementminOccurs="1" maxOccurs="1" name="IntegerOne" type="s:int" />
<s:elementminOccurs="1" maxOccurs="1" name="IntegerTwo" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
<s:element name="AddTwoIntegersResponse">
<s:complexType>
<s:sequence>
<s:elementminOccurs="1" maxOccurs="1" name="AddTwoIntegersResult" type="s:int" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="AddTwoIntegersSoapIn">
<wsdl:part name="parameters" element="tns:AddTwoIntegers" />
</wsdl:message>
<wsdl:message name="AddTwoIntegersSoapOut">
<wsdl:part name="parameters" element="tns:AddTwoIntegersResponse" />
</wsdl:message>
<wsdl:portType name="SimpleServiceSoap">
<wsdl:operation name="AddTwoIntegers">
<wsdl:input message="tns:AddTwoIntegersSoapIn" />
<wsdl:output message="tns:AddTwoIntegersSoapOut" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="SimpleServiceSoap" type="tns:SimpleServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
<wsdl:operation name="AddTwoIntegers">
<soap:operation soapAction="http://tempuri.org/AddTwoIntegers" style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="SimpleService">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/" />
<wsdl:port name="SimpleServiceSoap" binding="tns:SimpleServiceSoap">
<soap:address location="http://localhost/Develop.NET/Home.Develop.WebServices/SimpleService.asmx"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
javaScript代碼中利用了MS的HTTP代理對(duì)象XMLHTTP,在Mozilla's Web brower中相應(yīng)的組件是XMLHttpRequest,他們都提供了類似的方法來(lái)完成soap請(qǐng)求。下面的代碼用的是IE中的XMLHTTP對(duì)象。代碼假定調(diào)用過(guò)程中沒(méi)有Fault。
function fncAddTwoIntegers(a, b)
{
var oXmlHttp = new ActiveXObject("MSXML2.XMLHTTP");
oXmlHttp.open("POST", "http://localhost/Develop.NET/Home.Develop.WebServices/SimpleService.asmx'", false);
oXmlHttp.setRequestHeader("Content-Type", "text/xml");
oXmlHttp.setRequestHeader("SOAPAction", "http://tempuri.org/AddTwoIntegers");
oXmlHttp.send("
<soap:Envelopexmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
<soap:Body>
<AddTwoIntegersxmlns='http://tempuri.org/'>
<IntegerOne>" + a + "</IntegerOne>
<IntegerTwo>" + b + "</IntegerTwo>
</AddTwoIntegers>
</soap:Body>
</soap:Envelope>");
return oXmlHttp.responseXML.selectSingleNode("http://AddTwoIntegersResult").text;
}
原文英文出自:
http://builder.com.com/5100-6371_14-5887775.html?tag=nl.e601
Document方式是Web service缺省調(diào)用模式,和literal相組合,給我們調(diào)用Web service提供了極大的便利,省去了RPC調(diào)用方式的復(fù)雜類型序列化的問(wèn)題,所以,Doucment調(diào)用方式在BPEL領(lǐng)域應(yīng)用非常廣泛,下面介紹基于Axis利用Document方式來(lái)調(diào)用一個(gè)Web service.
1. Web service準(zhǔn)備:
Web service你可以任意實(shí)現(xiàn)一個(gè),我是利用Oracle BPEL,通過(guò)建立一個(gè)BPEL流程,然后把它發(fā)布為Web service(具體創(chuàng)建過(guò)程省略),這里重要的是Web service的WSDL文件,這是我們調(diào)用的門(mén)戶。
下面是我的Web service的WSDL文件內(nèi)容:
<definitions
name="HelloWorld"
targetNamespace="http://xmlns.oracle.com/HelloWorld"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:client="http://xmlns.oracle.com/HelloWorld"
>
<types>
<schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://xmlns.oracle.com/HelloWorld"
xmlns="http://www.w3.org/2001/XMLSchema">
<element name="HelloWorldProcessRequest">
<complexType>
<sequence>
<element name="input" type="string"/>
</sequence>
</complexType>
</element>
<element name="HelloWorldProcessResponse">
<complexType>
<sequence>
<element name="result" type="string"/>
</sequence>
</complexType>
</element>
</schema>
</types>
<message name="HelloWorldRequestMessage">
<part name="payload" element="client:HelloWorldProcessRequest"/>
</message>
<message name="HelloWorldResponseMessage">
<part name="payload" element="client:HelloWorldProcessResponse"/>
</message>
<portType name="HelloWorld">
<operation name="process">
<input message="client:HelloWorldRequestMessage"/>
<output message="client:HelloWorldResponseMessage"/>
</operation>
</portType>
<binding name="HelloWorldBinding" type="client:HelloWorld">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="process">
<soap:operation style="document" soapAction="process"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="HelloWorld">
<port name="HelloWorldPort" binding="client:HelloWorldBinding">
<soap:address location="http://robin:9700/orabpel/default/HelloWorld/1.0"/>
</port>
</service>
<plnk:partnerLinkType name="HelloWorld">
<plnk:role name="HelloWorldProvider">
<plnk:portType name="client:HelloWorld"/>
</plnk:role>
</plnk:partnerLinkType>
</definitions>
2. 編寫(xiě)調(diào)用類,代碼如下:
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.Vector;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.rpc.ServiceException;
import org.apache.axis.client.Call;
import org.apache.axis.constants.Style;
import org.apache.axis.message.SOAPBodyElement;
import org.apache.xml.serialize.DOMSerializerImpl;
import org.apache.xml.serialize.OutputFormat;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class BPELServiceTest {
//service的命名空間
static final String ns = "http://xmlns.oracle.com/HelloWorld";
public static void main(String args[]){
Call call = null;
try {
call = createCall();
Vector rtn = (Vector) call.invoke(createRequest());
parse(rtn);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FactoryConfigurationError e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* 創(chuàng)建Call對(duì)象,對(duì)設(shè)置相關(guān)屬性,注意:其中的屬性應(yīng)該是通過(guò)分析WSDL文件由程序動(dòng)態(tài)獲得來(lái)賦值,
* 這里全部簡(jiǎn)化為靜態(tài)賦值
*/
static Call createCall() throws MalformedURLException, ServiceException{
org.apache.axis.client.Service s = new org.apache.axis.client.Service();
Call call = (Call) s.createCall();
call.setTargetEndpointAddress(new URL("http://robin:9700/orabpel/default/HelloWorld/1.0"));
call.setSOAPActionURI("process");
call.setOperationName("process");
call.setProperty(Call.OPERATION_STYLE_PROPERTY, Style.DOCUMENT.getName());
call.setPortName(new QName(ns, "HelloWorldPort"));
call.setPortTypeName(new QName(ns, "HelloWorld"));
return call;
}
/*
*創(chuàng)建請(qǐng)求參數(shù),實(shí)際上就是構(gòu)建DOM片斷,根據(jù)Web service對(duì)輸入?yún)?shù)的要求來(lái)構(gòu)建,要多復(fù)雜,都可以實(shí)現(xiàn),
*這就是Docuemnt的好處,省去了復(fù)雜對(duì)象的序列化。
*/
static Object[] createRequest() throws ParserConfigurationException, FactoryConfigurationError{
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.newDocument();
Element root = doc.createElementNS(ns, "HelloWorldProcessRequest");
Element input = doc.createElementNS(ns, "input");
input.appendChild(doc.createTextNode("robin"));
root.appendChild(input);
doc.appendChild(root);
return new Object[]{new SOAPBodyElement(root)};
}
// 對(duì)返回結(jié)果進(jìn)行解析,并打印。
static void parse(Vector v) throws Exception{
Document doc = ((SOAPBodyElement) v.get(0)).getAsDocument();
Element root = doc.getDocumentElement();
OutputFormat of = new OutputFormat();
of.setIndent(4);
System.out.println(new DOMSerializerImpl().writeToString(root));
}
}
上述代碼運(yùn)行輸出結(jié)果為:
<?xml version="1.0"?>
<HelloWorldProcessResponse xmlns="http://xmlns.oracle.com/HelloWorld">
<result xmlns="http://xmlns.oracle.com/HelloWorld">robin</result>
</HelloWorldProcessResponse>
上面的代碼很簡(jiǎn)單,需要說(shuō)明的是:采用Document調(diào)用,實(shí)際上invoke方法的參數(shù)是一個(gè)元素類型為SOAPBodyElement的對(duì)象數(shù)組,而返回結(jié)果是一個(gè)元素類型的SOAPBodyElement的Vector對(duì)象。
這一小節(jié)介紹如何編寫(xiě)一個(gè)自定義的注解類型,以及如何應(yīng)用JDK5.0 java.lang.annotation包中提供的4種注解:
@Documented,@Retention,@Target,@Inherited
1. 編寫(xiě)自定義@Todo注解經(jīng)常我們?cè)趯?xiě)程序時(shí),有時(shí)候有些功能在當(dāng)前的版本中并不提供,或由于某些其它原因,有些方法沒(méi)有完成,而留待以后完成,我們?cè)趈avadoc中用@TODO來(lái)描述這一行為,下面用java注解來(lái)實(shí)現(xiàn)。
public @interface Todo { } // Todo.java如果你想讓這個(gè)注解類型能夠自省的話,給它加上@Todo注解,寫(xiě)法如下:
@Todo
public @interface Todo{ }下面我們給這個(gè)注解接受參數(shù)的能力,代碼如下:
@Todo("Just articleware")
public @interface Todo{
public enum Priority { LOW, MEDIUM, HIGH }
String value();
String[] owners() default "";
Priority priority() default Priority.MEDIUM;
}
注意:注解類性所能接受的參數(shù)類型有著嚴(yán)格的規(guī)則:
a. 參數(shù)類型只能是:primitive, String, Class, enum, annotation, 或者是數(shù)組;
b. 參數(shù)值不能為空,因此每一個(gè)參數(shù)值都要定義一個(gè)缺省值;
c. 名字為value的參數(shù)可以用簡(jiǎn)便的方法來(lái)設(shè)置;
d. 參數(shù)的寫(xiě)法如同寫(xiě)簡(jiǎn)單方法(看如上代碼),不允許加入?yún)?shù),不允許有throws子句等。
在上面的代碼中,我們?yōu)?#64;Todo定義了3個(gè)參數(shù), 分別是value, owners, priority. 注意:由于value的特殊性,它的的卻省值可以由上面代碼中的"Just articleware"來(lái)定義,當(dāng)然你也可以單獨(dú)寫(xiě)一個(gè)缺省值。
下面看一個(gè)應(yīng)用@Todo注解的例子:
@Todo(
value="Class scope",
priority=Unfinished.Priority.LOW
)
public class TodoDemo {
@Todo("Constructor scope")//通過(guò)快捷方式,設(shè)置value的值
public TodoDemo() { }
@Todo(owner="Jason", value="Method scope")
public void foo() { }
}
上面的代碼很簡(jiǎn)單,不多介紹。
下面我們想讓@Todo不能應(yīng)用在fields, parameters, 或者local variables(因?yàn)檫@對(duì)我們來(lái)說(shuō)沒(méi)有意義);它應(yīng)當(dāng)可以出現(xiàn)在javadoc中;在運(yùn)行是具有持久性。要實(shí)現(xiàn)這些特性,就需要annotation包的支持啦。
2. 應(yīng)用annotation包的支持1)@Documented
類和方法的annotation缺省情況下是不出現(xiàn)在javadoc中的,為了加入這個(gè)性質(zhì)我們用@Documented
應(yīng)用代碼如下(簡(jiǎn)單,不多介紹):
package com.robin;
import java.lang.annotation.*;
@Todo("Just articleware")
@Documented
public @interface Todo{ ...
2)@Retention
用來(lái)表明你的annotation的有效期,可以有三種選擇(如圖所示):

以下示例代碼應(yīng)用RUNTIME策略
package com.robin;
import java.lang.annotation.*;
@Todo("Just articleware")
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Todo{ ...
3) @Target
@Target注解表明某個(gè)注解應(yīng)用在哪些目標(biāo)上,可選擇如下范圍:
- ElementType.TYPE (class, interface, enum)
- ElementType.FIELD (instance variable)
- ElementType.METHOD ElementType.PARAMETER
- ElementType.CONSTRUCTOR
- ElementType.LOCAL_VARIABLE
- ElementType.ANNOTATION_TYPE (應(yīng)用于另一個(gè)注解上)
- ElementType.PACKAGE
按我們的功能要求,代碼如下:
package com.robin;
import java.lang.annotation.*;
@Todo("Just articleware")
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD,
ElementType.CONSTRUCTOR,ElementType.ANNOTATION_TYPE,
ElementType.PACKAGE})
public @interface Todo{ ...
4) @Inherited
@Inherited表明是否一個(gè)使用某個(gè)annotation的父類可以讓此annotation應(yīng)用于子類。
示例代碼如下:
package com.robin;
import java.lang.annotation.*;
@Todo("Just articleware")
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD,
ElementType.CONSTRUCTOR,ElementType.ANNOTATION_TYPE,
ElementType.PACKAGE})
@Inherited
public @interface Todo{
public enum Priority { LOW, MEDIUM, HIGH }
String value();
String[] owners() default "";
Priority priority() default Priority.MEDIUM;
}
注解(annotation)是J2SE 5.0的新內(nèi)容,它給我們提供了很好的編程支持,下面介紹一下其內(nèi)置的三種注解類型:
1. @Override@Override用在多態(tài)情況下,比如:
public abstract class Animal{
public void say(){
System.out.println("annimal is saying");
}
}
public class Cat extends Animal{
@Override
public void say(){
System.out.println("miao, miao");
}
}
通過(guò)@Override來(lái)告訴java編譯器,say方法是重載的父類的方法,這樣,當(dāng)父類的say方法簽名改名的話,比如增加了一些參數(shù),那么子類的Cat中的say方法編譯時(shí)就會(huì)報(bào)錯(cuò),說(shuō)沒(méi)有正確的重載父類方法,所以,@Override可以幫我們驗(yàn)證程序的正確性,這一點(diǎn),很有用。
2. @Deprecated
@Deprecated的意思和JavaDoc中的@deprecated注釋在本質(zhì)上是一樣的,使用如下:
public class DeprecatedExample {
@Deprecated
public static void badMethod() { }
}
public class DeprecatedUser {
public static void main(String[] args){
DeprecatedExample.badMethod();
}
}
上面的代碼如果用javac進(jìn)行編譯的話,會(huì)打印出如下信息:
Note: DeprecatedUser.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
1 error
如果你按提示重新加-Xlint進(jìn)行編譯,你就可以得到錯(cuò)誤的詳細(xì)信息:
% javac -Xlint:deprecation
DeprecatedUser.java:3: warning: [deprecation] badMethod() in DeprecatedExample
has been deprecated
DeprecatedExample.badMethod();
需要注意的是:和javadoc中的@deprecated相比,@Deprecated并沒(méi)有強(qiáng)大多少,因?yàn)樗恢С謪?shù),而@deprecated后面還可以跟字符串來(lái)給一些相關(guān)的信息,但@Deprecated做不到,但它提供了運(yùn)行時(shí)自省的功能,來(lái)提示錯(cuò)誤,所以建議@Deprecated和@deprecated同時(shí)使用。
3. @SuppressWarnings
顧名思義,就是抑制警告信息的出現(xiàn),使用如下:
public class DeprecatedExample2{
@Deprecated
public static void foo() { }
}
public class DeprecatedUser2 {
@SuppressWarnings(value={"deprecation"})
public static void main(String[] args) {
DeprecatedExample2.foo();
}
}
上述@SuppressWarnings(value={"deprecation"})的作用就是抑制編譯器報(bào)deprecation的錯(cuò)。
@SuppressWarnings(value={"deprecation"})只支持一個(gè)參數(shù),是數(shù)組類型,所以你可以不用加value, 寫(xiě)成:@SuppressWarnings({"deprecation"});當(dāng)想抑制多個(gè)類型的警告信息時(shí),可寫(xiě):@SuppressWarnings({"unchecked","fallthrough",deprecation"}).
注意:在JDK1.5.0 release中,@SuppressWarnings還沒(méi)有得到完全支持,會(huì)在以后支持,但Sun并沒(méi)有給出具體的時(shí)間。