成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java與groovy混編 —— 一種兼顧接口清晰和實(shí)現(xiàn)敏捷的開發(fā)方式

LittleLiByte / 3601人閱讀

摘要:原文鏈接有大量平均水平左右的工人可被選擇參與進(jìn)來這意味著好招人有成熟的大量的程序庫(kù)可供選擇這意味著大多數(shù)項(xiàng)目都是既有程序庫(kù)的拼裝,標(biāo)準(zhǔn)化程度高而定制化場(chǎng)景少開發(fā)工具測(cè)試工具問題排查工具完善,成熟基本上沒有團(tuán)隊(duì)愿意在時(shí)間緊任務(wù)重的項(xiàng)目情況

原文鏈接:http://pfmiles.github.io/blog/java-groovy-mixed/

有大量平均水平左右的“工人”可被選擇、參與進(jìn)來 —— 這意味著好招人

有成熟的、大量的程序庫(kù)可供選擇 ——
這意味著大多數(shù)項(xiàng)目都是既有程序庫(kù)的拼裝,標(biāo)準(zhǔn)化程度高而定制化場(chǎng)景少

開發(fā)工具、測(cè)試工具、問題排查工具完善,成熟 ——
基本上沒有團(tuán)隊(duì)愿意在時(shí)間緊、任務(wù)重的項(xiàng)目情況下去做沒有把握的、基礎(chǔ)開發(fā)工具類的技術(shù)試探

有面向?qū)ο筇匦? 適合大型項(xiàng)目開發(fā) ——
無數(shù)大型項(xiàng)目已向世人述說,“面向?qū)ο蟆笔情_發(fā)大型軟件的優(yōu)秀代碼組織結(jié)構(gòu)

能適應(yīng)大型團(tuán)隊(duì)、多人協(xié)作開發(fā) ——
代碼需要簡(jiǎn)單易懂,起碼在接口、api層面是這樣

—— 這是我所理解的“工業(yè)化開發(fā)編程語(yǔ)言”的概念

很顯然, java就是種典型的“工業(yè)語(yǔ)言”, 非常流行,很多企業(yè)靠它賺錢,很實(shí)際;
但java也是常年被人黑,光是對(duì)其開發(fā)效率的詬病就已經(jīng)足夠多,不過java始終屹立不倒;

這樣的局面其實(shí)無所謂高興還是擔(dān)憂,理性的程序員有很多種,其中一種是向“錢”看的 —— 我寫java代碼,就是因?yàn)楣ぷ餍枰?,能幫助我的組織搞定業(yè)務(wù),做出項(xiàng)目,這很好;
當(dāng)有人說java語(yǔ)言不好的時(shí)候,理性的程序員不會(huì)陷入宗教式的語(yǔ)言戰(zhàn)爭(zhēng)之中,他會(huì)思考這些人說的是否有道理;如果真的發(fā)現(xiàn)整個(gè)java平臺(tái)大勢(shì)已去,他會(huì)毫不猶豫地扭頭就走,不過直到目前為止,還沒有這種跡象出現(xiàn);

那么,從這些無數(shù)次的口水之爭(zhēng)中,我們能否從別人的“戰(zhàn)場(chǎng)”上發(fā)現(xiàn)一些有用的東西, 來改進(jìn)我們的開發(fā)方式,從而使得java這種已經(jīng)成為一個(gè)“平臺(tái)”的東西走得更遠(yuǎn),賺更多的錢呢?
答案是“有的”,感謝那些參與口水戰(zhàn)爭(zhēng)的、各種陣營(yíng)的年輕程序員們,有了你們,java speaker們才有了更多的思考;

我就只談一個(gè)最實(shí)際的問題:

java被吐槽的這些年, 就開發(fā)效率這一點(diǎn)而言,到底有哪些東西是值得借鑒的?

也就是說,到底是哪些主要特性直接導(dǎo)致了某些其它語(yǔ)言在語(yǔ)法上相對(duì)于java的優(yōu)越感?

豐富的literal定義

在groovy中定義map和list的慣用方式:

def list = [a, 2 ,3]
def map = [a:0, b:1]

而java呢?只能先new一個(gè)list或map,再一個(gè)個(gè)add或put進(jìn)去; 上面這種literal(字面量)形式的寫法便捷得多;

而javascript在這方面做得更絕, 我們都用過json,而json其實(shí)就是literal形式的object

極端情況下,一門編程語(yǔ)言里的所有數(shù)據(jù)類型,包括”內(nèi)建”的和用戶自定義的,統(tǒng)統(tǒng)可以寫成literal形式;
在這種情形下,其實(shí)這種語(yǔ)言連額外的對(duì)象序列化、反序列化機(jī)制都不需要了 —— 數(shù)據(jù)的序列化形式就是代碼本身, “代碼”和“數(shù)據(jù)”在形式上被統(tǒng)一了

java對(duì)這方面幾乎沒有任何支持,對(duì)于提高編碼效率來講,這是值得學(xué)習(xí)的一點(diǎn), 起碼“內(nèi)建”數(shù)據(jù)結(jié)構(gòu)需要literal寫法支持

first-class function & higher-order function & function literal(lambda)

無論是js, 還是python/ruby,或是groovy,都可以將函數(shù)作為另一個(gè)函數(shù)的參數(shù)傳入,以便后者根據(jù)執(zhí)行情況判斷是否要調(diào)用前者
或者能夠?qū)⒁粋€(gè)函數(shù)作為另一個(gè)函數(shù)的返回值返回,以便后續(xù)再對(duì)其進(jìn)行調(diào)用
這種高階函數(shù)特性,就不要再說java的匿名內(nèi)部類“能夠”實(shí)現(xiàn)了, 如果認(rèn)為匿名內(nèi)部類已經(jīng)”夠用”了的話,其實(shí)就已經(jīng)與現(xiàn)在的話題“開發(fā)效率”相悖了

高階函數(shù)顯然是一種值得借鑒的特性,它會(huì)讓你少寫很多很多無聊的“包裝”代碼;

還有就是匿名函數(shù)(lambda)了
我不喜歡lambda、lambda地稱呼這個(gè)東西,我更喜歡把它叫做“匿名函數(shù)”或者“函數(shù)字面量(literal)”, 因?yàn)樗鷶?shù)學(xué)上的lambda演算還是有本質(zhì)區(qū)別,叫”lambda”有誤導(dǎo)的危險(xiǎn)

函數(shù)字面量的意思就是說,你可以在任何地方,甚至另一個(gè)函數(shù)體的調(diào)用實(shí)參或內(nèi)部,隨時(shí)隨地地定義另一個(gè)新的函數(shù)
這種定義函數(shù)的形式,除了“這個(gè)函數(shù)我只想在這里用一次,所以沒必要給它起個(gè)名字”這種理由之外,還有一個(gè)更重要的理由就是“閉包”了

所謂閉包,其實(shí)也是一個(gè)函數(shù),但是在這個(gè)函數(shù)被定義時(shí),其內(nèi)部所出現(xiàn)的所有”自由變量(即未出現(xiàn)在該函數(shù)的參數(shù)列表中的變量)”已被當(dāng)前外層上下文給確定下來了(lexical), 這時(shí)候,這個(gè)函數(shù)擁有的東西不僅僅是一套代碼邏輯,還帶有被確定下來的、包含那些“自由變量”的一個(gè)上下文, 這樣這個(gè)函數(shù)就成為了一個(gè)閉包

那么閉包這種東西有什么好呢?其實(shí)如果懶散而鉆牛角尖地想,閉包的所有能力,是嚴(yán)格地小于等于一個(gè)普通的java對(duì)象的,也就是說,凡是可以用一個(gè)閉包實(shí)現(xiàn)的功能,就一定可以通過傳入一個(gè)對(duì)象來實(shí)現(xiàn),但反過來卻不行 —— 因?yàn)殚]包只有一套函數(shù)邏輯,而對(duì)象可以有很多套,其次很多語(yǔ)言實(shí)現(xiàn)的閉包其內(nèi)部上下文不可變但對(duì)象內(nèi)部屬性可變

既然這樣,java還要閉包這種東西來干嘛?其實(shí)這就又陷入了”匿名內(nèi)部類可以實(shí)現(xiàn)高階函數(shù)”的困境里了 —— 如果我在需要一個(gè)閉包的時(shí)候,都可以通過定義一個(gè)接口再傳入一個(gè)對(duì)象來實(shí)現(xiàn)的話,這根本就跟今天的話題“開發(fā)效率”背道而馳了

顯然,java是需要閉包的

強(qiáng)大而復(fù)雜的靜態(tài)類型系統(tǒng)

這和開發(fā)效率有關(guān)么?
編程語(yǔ)言不是越“動(dòng)態(tài)”,開發(fā)效率越高么?還需要強(qiáng)大而復(fù)雜的靜態(tài)類型系統(tǒng)么?

試想一下這種api定義:

def eat(foo) {
    ...
}

這里面你認(rèn)識(shí)的東西可能只有’吃’了, 你知道foo是什么么?你知道它想吃什么么?吃完后要不要產(chǎn)出點(diǎn)什么東西? —— 你什么都不知道
這種api極易調(diào)用出錯(cuò),這就好比我去買飯,問你想吃什么你說“隨便”,但買回肯德基你卻說你實(shí)際想吃的是麥當(dāng)勞一樣

可能你還會(huì)反駁說,不是還有文檔么?你把文檔寫好點(diǎn)不就行了么? —— 不要逼我再提“匿名內(nèi)部類”的例子,如果給每個(gè)函數(shù)寫上復(fù)雜詳盡的文檔是個(gè)好辦法,那就顯然 —— again, 與“開發(fā)效率”背道而馳了

那么,靜態(tài)類型系統(tǒng),這里顯然就該用上了

靜態(tài)類型系統(tǒng)在多人協(xié)作開發(fā)、甚至團(tuán)隊(duì)、組織間協(xié)作開發(fā)是非常有意義的;
擁有靜態(tài)類型系統(tǒng)的編程語(yǔ)言通常都有強(qiáng)大的、帶語(yǔ)法提示功能的IDE,這很正常,因?yàn)殪o態(tài)類型語(yǔ)言的語(yǔ)法提示功能好做;
只要把別人的庫(kù)拿過來,導(dǎo)入IDE,各種函數(shù)簽名只需掃一眼 —— 很多情況下根本不需要仔細(xì)看文檔 —— 就已經(jīng)知道這個(gè)函數(shù)是干嘛用的了, 合作效率成倍提升;

而且,作為”api”,作為“模塊邊界”,作為與其它程序員合作的“門面”, 函數(shù)簽名上能將參數(shù)和返回值類型“卡”得越緊越好 —— 這樣別人不用猜你這個(gè)函數(shù)需要傳入什么類型,甚至他在IDE里一“點(diǎn)”,這里就給自動(dòng)填上了 :)

要做到“卡得緊”,光有靜態(tài)類型系統(tǒng)還不夠,這個(gè)系統(tǒng)還需強(qiáng)大, 試想一下這個(gè)例子:

/**
 * 我只吃香蕉和豬肉,請(qǐng)勿投食其它物品
 */
public void eat(List list) {
    for(Object o: list) {
        if(o instanceof Banana){
            ... // eating banana
        } else if(o instanceof Pork) {
            ... // eating pork
        } else {
            throw new RuntimeException("System err.");
        }
    }
}


這段純java代碼已經(jīng)是“定義精確”的靜態(tài)類型了
但如果沒有上面那行注釋,你很可能會(huì)被System err.無數(shù)次
而這行注釋之所以是必需的,完全是因?yàn)槲艺也坏揭粋€(gè)比List更好的表達(dá)“香蕉或豬肉”的形式, 這種情形足以讓人開始想念haskell的either monad

在“強(qiáng)大而復(fù)雜的類型系統(tǒng)”這一點(diǎn)上,jvm平臺(tái)上令人矚目的當(dāng)屬scala了,可惜java沒有,這是值得借鑒的

不過這一點(diǎn)的“借鑒”還需java的compiler team發(fā)力,我等也只是說說(按照java保守的改進(jìn)速度,估計(jì)HM類型系統(tǒng)是指望不上了)

動(dòng)態(tài)類型系統(tǒng),duck-typing

剛說完靜態(tài)類型,現(xiàn)在又來說動(dòng)態(tài)類型系統(tǒng)合適么?

然而這與節(jié)操無關(guān),我想表達(dá)的是,只要是有助于“開發(fā)效率”的,都能夠借鑒,這是一個(gè)理性的java speaker的基本素質(zhì)

我們?cè)陂_發(fā)項(xiàng)目的時(shí)候,大量的編碼發(fā)生在“函數(shù)”或“方法”的內(nèi)部 —— 這就好比你在屋子里、在家里宅著一樣, 是不是應(yīng)該少一些拘束,多一些直截了當(dāng)?
在這種情形下,動(dòng)態(tài)類型系統(tǒng)要不要太爽? ——

Void visitAssert(AssertTree node, Void arg1) {
    def ahooks = this.hooks[VisitAssertHook.class]
    ahooks.each {it.beforeVisitCondition(node, errMsgs, this.ctx, resolveRowAndCol, setError)}
    scan((Tree)node.getCondition(), arg1);
    ahooks.each {it.afterVisitConditionAndBeforeDetail(node, errMsgs, this.ctx, resolveRowAndCol, setError)}
    scan((Tree)node.getDetail(), arg1);
    ahooks.each {it.afterVisitDetail(node, errMsgs, this.ctx, resolveRowAndCol, setError)}
    return null;
}

你知道ahooks是什么類型么?你不知道但我(我是編碼的人)知道
你知道ahooks身上有些什么方法可以調(diào)么?你同樣不知道但我知道

你不知道沒關(guān)系,只要我知道就行了,因?yàn)楝F(xiàn)在是我在寫這段代碼;
這段代碼寫完以后,我只會(huì)把Void visitAssert(AssertTree node, Void arg1)這個(gè)類型明確的方法簽名提供給你調(diào)用,我并不會(huì)給你看函數(shù)體里面的那坨東西,因此你知不知道上面這些真的沒關(guān)系

方法內(nèi)部滿是def, 不用書寫繁復(fù)的List>>>這種反人類反社會(huì)標(biāo)語(yǔ), 每個(gè)對(duì)象我知道它們身上能“點(diǎn)”出些什么來,我只管“點(diǎn)”,跑起來之后invokedynamic會(huì)為我搞定一切

動(dòng)態(tài)類型系統(tǒng) —— 這就是方法內(nèi)部實(shí)現(xiàn)應(yīng)該有的樣子
哪怕你的方法內(nèi)部實(shí)現(xiàn)就是一坨shi,你也希望這坨shi能盡可能小只一點(diǎn),這樣看起來更清爽是吧?

不要說我太分裂,我要笑你看不穿 —— 靜態(tài)類型和動(dòng)態(tài)類型既然都有好處,那么他們能放在一起么?
能的,這里就需要點(diǎn)明這篇文章的政治目的了: “java與groovy混編”
而且,目前來看,jvm平臺(tái)上,只有它二者的結(jié)合,才能完成動(dòng)態(tài)靜態(tài)混編的任務(wù)

曾經(jīng)我發(fā)出過這樣一段感嘆:

  

公共api、對(duì)外接口聲明、應(yīng)用程序邊界…這些對(duì)外的“臉面”部分代碼,如果擁有scala般強(qiáng)大的類型系統(tǒng)…就好了;而私有代碼、內(nèi)部實(shí)現(xiàn)、各種內(nèi)部算法、邏輯,如果擁有g(shù)roovy般的動(dòng)態(tài)、簡(jiǎn)單的類型系統(tǒng)…就好了;綜上,如果有門語(yǔ)言,在接口和實(shí)現(xiàn)層面分別持有上述特性,就好了

這種“理想”中的語(yǔ)言或許某天我有空了會(huì)考慮實(shí)現(xiàn)一個(gè)

而現(xiàn)在,雖說不是scala,但我終于想要在java和groovy身上來試驗(yàn)一把這種開發(fā)方式了
這里我坦白一下為什么沒用scala,原因很簡(jiǎn)單,我在技術(shù)選型方面是勢(shì)利的,scala還不被大多數(shù)平均水平的java開發(fā)人員(參見”工業(yè)化開發(fā)編程語(yǔ)言”定義第一條)接受,這直接導(dǎo)致項(xiàng)目的推進(jìn)會(huì)遇到困難
而相對(duì)來講,我暫且相信大多數(shù)java開發(fā)人員都還算愿意跨出groovy這一小步,當(dāng)然這還需要時(shí)間證明

好了,下面還剩下一點(diǎn)點(diǎn)無關(guān)痛癢的牢騷 ——

元編程能力

macro, eval, 編譯過程切入, 甚至method missing機(jī)制,這些都算“元編程”

元編程能力的強(qiáng)弱直接決定了使用這種語(yǔ)言創(chuàng)作“內(nèi)部DSL”的能力
java在元編程方面的能力,幾乎為0

這是值得借鑒的

與groovy的混編,順便也能把groovy的元編程也帶進(jìn)來

各種奇巧的語(yǔ)法糖

語(yǔ)法糖,關(guān)起門來吃最美味,這也是一種使得“方法內(nèi)部實(shí)現(xiàn)更敏捷”的附加手段
網(wǎng)上隨便下載一份groovy的cheat sheet, 都會(huì)列舉groovy的那些寫代碼方面的奇技淫巧
這些奇技淫巧,在各種腳本語(yǔ)言之間其實(shí)都大同小異, 因?yàn)樗麄儽緛砭褪浅瓉沓サ?br> 結(jié)合方法內(nèi)部的動(dòng)態(tài)類型環(huán)境,這一定會(huì)進(jìn)一步縮小方法內(nèi)部實(shí)現(xiàn)代碼的體積

java & groovy混編:一種最“勢(shì)利”的折衷

我不去討論什么語(yǔ)言才是The True Heir of Java, 那會(huì)使這篇文章變成一封戰(zhàn)書,我只關(guān)心如何更好地利用現(xiàn)有開發(fā)資源完成項(xiàng)目,高效地幫組織實(shí)現(xiàn)利益
所以說java和groovy的混編是一種最“勢(shì)利”的折衷,我不想強(qiáng)迫平均水平的開發(fā)人員去學(xué)習(xí)一種完全不同的語(yǔ)言,短期內(nèi)不會(huì)對(duì)項(xiàng)目有任何好處,真正想去學(xué)的人他自己會(huì)找時(shí)間去學(xué)
而groovy,說它是java++也不為過,因?yàn)閖ava代碼直接就可以被groovy編譯, groovy完全兼容java語(yǔ)法, 對(duì)一般java開發(fā)人員來說,這真是太親切了

這里我要提一下我對(duì)“java和groovy混編”的一個(gè)個(gè)人性質(zhì)的小嘗試 —— kan-java項(xiàng)目

kan-java這個(gè)小工具,凡是用戶在編碼使用過程中能“碰”到的類和接口,全部都由java定義, 這確保用戶拿到的東西都有精確的類型定義

凡是對(duì)上述接口的實(shí)現(xiàn),都以groovy代碼的形式存在

這貫徹了”接口靜態(tài)類型,內(nèi)部實(shí)現(xiàn)動(dòng)態(tài)類型”的宗旨, 或者說“凡是要提供給另外一個(gè)人看、調(diào)用的地方(接口或接口類),使用java,否則就用groovy”

當(dāng)然了,單元測(cè)試也完全由groovy代碼實(shí)現(xiàn)

將kan-java的jar包引入到項(xiàng)目中使用時(shí),就跟使用其它任何純java實(shí)現(xiàn)的jar包一樣 —— 接口清晰,參數(shù)類型明確,返回類型明確, 你不會(huì)也沒有必要知道開發(fā)人員在具體實(shí)現(xiàn)的時(shí)候,使用動(dòng)態(tài)語(yǔ)言爽過一把

對(duì)于java和groovy的混編,項(xiàng)目的pom.xml如何配置,除了可以參考kan-java的配置外,還可以參考這個(gè)gist: https://gist.github.com/pfmiles/2f2ab77f06d48384f113, 里面舉例了兩種配置方式,各有特色

具體的效果,還需要真正地去實(shí)際項(xiàng)目中體會(huì)
另外,kan-java也是一個(gè)有趣的工具,這個(gè)工具所實(shí)現(xiàn)的功能我也是從未見到j(luò)ava世界內(nèi)有其它地方討論過的,它可以輔助java做“內(nèi)部DSL”,有場(chǎng)景的可以一試

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/64295.html

相關(guān)文章

  • Java軟件架構(gòu)師需要掌握開源工具

    摘要:軟件架構(gòu)師需要掌握的開源工具的是當(dāng)前敏捷開發(fā)領(lǐng)域最重要的工具之一。主要用于持續(xù)自動(dòng)地構(gòu)建測(cè)試軟件項(xiàng)目,如與。監(jiān)控一些定時(shí)執(zhí)行的任務(wù)。是應(yīng)用程序最好的軟件測(cè)試框架之一。是一種自由和開放源碼的類操作系統(tǒng) Java軟件架構(gòu)師需要掌握的開源工具1. JIRAAtlassian的JIRA是當(dāng)前敏捷開發(fā)領(lǐng)域最重要的工具之一。它用于錯(cuò)誤...

    genefy 評(píng)論0 收藏0
  • 慕課網(wǎng)_《新一代構(gòu)建工具gradle》學(xué)習(xí)總結(jié)

    摘要:時(shí)間年月日星期二說明本文部分內(nèi)容均來自慕課網(wǎng)。項(xiàng)目一個(gè)項(xiàng)目代表一個(gè)正在構(gòu)建的組件比如一個(gè)文件,當(dāng)構(gòu)建啟動(dòng)后,會(huì)基于實(shí)例化一個(gè)類,并且能夠通過變量使其隱式可用。任務(wù)動(dòng)作定義了一個(gè)最小的工作單元。 時(shí)間:2017年05月16日星期二說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學(xué)示例源碼:無個(gè)人學(xué)習(xí)源碼:https://github.com/zccod...

    antyiwei 評(píng)論0 收藏0
  • JVM 平臺(tái)上各種語(yǔ)言開發(fā)指南[z]

    摘要:我們的目標(biāo)是建立對(duì)每一種語(yǔ)言的認(rèn)識(shí),它們是如何進(jìn)化的,未來將走向何方。有點(diǎn)的味道是堅(jiān)持使用動(dòng)態(tài)類型,但唯一還收到合理?yè)肀玫木幊陶Z(yǔ)言,然而一些在企業(yè)的大型團(tuán)隊(duì)中工作的開發(fā)者擇認(rèn)為這會(huì)是的一個(gè)缺陷。 為什么我們需要如此多的JVM語(yǔ)言? 在2013年你可以有50中JVM語(yǔ)言的選擇來用于你的下一個(gè)項(xiàng)目。盡管你可以說出一大打的名字,你會(huì)準(zhǔn)備為你的下一個(gè)項(xiàng)目選擇一種新的JVM語(yǔ)言么? 如今借助來自...

    phodal 評(píng)論0 收藏0
  • Spring Framework 參考文檔(容器概述)

    摘要:容器概述接口表示容器,負(fù)責(zé)實(shí)例化配置和組裝。基于的元數(shù)據(jù)不是惟一允許的配置元數(shù)據(jù)形式,容器本身與實(shí)際編寫配置元數(shù)據(jù)的格式完全解耦,現(xiàn)在,許多開發(fā)人員為他們的應(yīng)用程序選擇基于的配置。 容器概述 org.springframework.context.ApplicationContext接口表示Spring IoC容器,負(fù)責(zé)實(shí)例化、配置和組裝bean。容器通過讀取配置元數(shù)據(jù)獲取關(guān)于要實(shí)例化...

    huashiou 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<