国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

LittleLiByte / 3579人閱讀

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

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

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

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

開發(fā)工具、測試工具、問題排查工具完善,成熟 ——
基本上沒有團(tuán)隊(duì)愿意在時間緊、任務(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ā) ——
代碼需要簡單易懂,起碼在接口、api層面是這樣

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

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

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

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

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

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

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

豐富的literal定義

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

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

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

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

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

java對這方面幾乎沒有任何支持,對于提高編碼效率來講,這是值得學(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ù)作為另一個函數(shù)的參數(shù)傳入,以便后者根據(jù)執(zhí)行情況判斷是否要調(diào)用前者
或者能夠?qū)⒁粋€函數(shù)作為另一個函數(shù)的返回值返回,以便后續(xù)再對其進(jìn)行調(diào)用
這種高階函數(shù)特性,就不要再說java的匿名內(nèi)部類“能夠”實(shí)現(xiàn)了, 如果認(rèn)為匿名內(nèi)部類已經(jīng)”夠用”了的話,其實(shí)就已經(jīng)與現(xiàn)在的話題“開發(fā)效率”相悖了

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

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

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

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

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

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

顯然,java是需要閉包的

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

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

試想一下這種api定義:

def eat(foo) {
    ...
}

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

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

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

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

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

要做到“卡得緊”,光有靜態(tài)類型系統(tǒng)還不夠,這個系統(tǒng)還需強(qiá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)類型了
但如果沒有上面那行注釋,你很可能會被System err.無數(shù)次
而這行注釋之所以是必需的,完全是因?yàn)槲艺也坏揭粋€比List更好的表達(dá)“香蕉或豬肉”的形式, 這種情形足以讓人開始想念haskell的either monad

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

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

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

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

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

我們在開發(fā)項(xiàng)目的時候,大量的編碼發(fā)生在“函數(shù)”或“方法”的內(nèi)部 —— 這就好比你在屋子里、在家里宅著一樣, 是不是應(yī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)在是我在寫這段代碼;
這段代碼寫完以后,我只會把Void visitAssert(AssertTree node, Void arg1)這個類型明確的方法簽名提供給你調(diào)用,我并不會給你看函數(shù)體里面的那坨東西,因此你知不知道上面這些真的沒關(guān)系

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

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

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

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

  

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

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

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

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

元編程能力

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

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

這是值得借鑒的

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

各種奇巧的語法糖

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

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

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

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

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

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

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

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

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

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

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

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/64295.html

相關(guān)文章

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

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

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

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

    antyiwei 評論0 收藏0
  • JVM 平臺上各種語言開發(fā)指南[z]

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

    phodal 評論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 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<