香蕉久久人人爽人人爽人人片av,色又黄又爽18禁免费视频,无码gogo大胆啪啪艺术,他扒开我奶罩揉吮我奶头,香蕉久久av一区二区三区

  1. 云裂變
  2. 營銷
  3. 網(wǎng)站運營
  4. [杭州網(wǎng)站制作]API設(shè)計新思維:用流暢接口構(gòu)造內(nèi)部DSL

[杭州網(wǎng)站制作]API設(shè)計新思維:用流暢接口構(gòu)造內(nèi)部DSL

作者: 日期:2021-06-18 人氣:409

API設(shè)計新思維:用流暢接口構(gòu)造內(nèi)部DSL

程序設(shè)計語言的抽象機制包含了兩個最基本的方面:一是語言關(guān)注的基本元素/語義;另一個是從基本元素/語義到復合元素/語義的構(gòu)造規(guī)則。在C、C++、Java、C#、Python等通用語言中,語言的基本元素/語義往往離問題域較遠,通過API庫的形式進行層層抽象是降低問題難度最常用的方法。比如,在C語言中最常見的方式是提供函數(shù)庫來封裝復雜邏輯,方便外部調(diào)用。(杭州網(wǎng)站制作)

不過普通的API設(shè)計方法存在一種天然的陷阱,那就是不管怎樣封裝,大過程雖然比小過程抽象層次更高,但本質(zhì)上還是過程,受到過程語義的制約。也就是說,通過基本元素/語義構(gòu)造更高級抽象元素/語義的時候,語言的構(gòu)造規(guī)則很大程度上限制了抽象的維度,我們很難跳出這個維度去,甚至可能根本意識不到這個限制。而SQL、HTML、CSS、make等DSL(領(lǐng)域特定語言)的抽象維度是為特定領(lǐng)域量身定做的,從這些抽象角度看問題往往最為簡單,所以DSL在解決其特定領(lǐng)域的問題時比通用程序設(shè)計語言更加方便。通常,SQL等非通用語言被稱為外部DSL(External DSL);在通用語言中,我們其實也可以在一定程度上突破語言構(gòu)造規(guī)則的抽象維度限制,定義內(nèi)部DSL(Internal DSL)。

本文將介紹一種被稱為流暢接口(Fluent Interface)的內(nèi)部DSL設(shè)計方法。Wikipedia上Fluent Interface的定義是:

?

A fluent interface (as first coined by Eric Evans and Martin Fowler) is an implementation of an object oriented API that aims to provide for more readable code. A fluent interface is normally implemented by using method chaining to relay the instruction context of a subsequent call (but a fluent interface entails more than just method chaining)。

下面將分4個部分來逐步說明流暢接口在構(gòu)造內(nèi)部DSL中的典型應(yīng)用。

1.基本語義抽象

如果要輸出0..4這5個數(shù),我們一般會首先想到類似這樣的代碼:

  1. ?//Java ?
  2. for?(int?i?=?0;?i?<?5;?++i)?{ ?
  3. system.out.println(i); ?
  4. }? ?
  5. ?

而Ruby雖然也支持類似的for循環(huán),但最簡單的是下面這樣的實現(xiàn):

  1. //Ruby ?
  2. .times?{|i|?puts?i}? ?

Ruby中一切皆對象,5是Fixnum類的實例,times是Fixnum的一個方法,它接受一個block參數(shù)。相比for循環(huán)實現(xiàn),Ruby 的times方式更簡潔,可讀性更強,但熟悉OOP的朋友可能會有疑問,times是否應(yīng)該作為整型類的方法呢?在OOP中,方法調(diào)用通常代表了向?qū)ο蟀l(fā)送消息,改變或查詢對象的狀態(tài),times方法顯然不是對整型對象狀態(tài)的查詢和修改。如果你是Ruby的設(shè)計者,你會把times方法放入Fixnum類嗎?如果答案是否定的,那么Ruby的這種設(shè)計本質(zhì)上代表了什么呢?實際上,這里的times雖然只是一個普通的類方法,但它的目的卻與普通意義上的類方法不同,它的語義實際上類似于for循環(huán)這樣的語言基本語義,可以被視為一種自定義的基本語義。times的語義從一定程度上跳出了類方法的框框,向問題域邁進了一步!

另一個例子來自Eric Evans的“用兩個時間點構(gòu)造一個時間段對象”,普通設(shè)計:

  1. 3?//Java ?
  2. TimePoint?fiveOClock,?sixOClock; ?
  3. TimeInterval?meetingTime?=?new?TimeInterval(fiveOClock,?sixOClock);? ?
  4. ?

另一種Evans的設(shè)計是這樣:

  1. 2?//Java ?
  2. TimeInterval?meetingTime?=?fiveOClock.until(sixOClock);? ?

按傳統(tǒng)OO設(shè)計,until方法本不應(yīng)出現(xiàn)在TimePoint類中,這里TimePoint類的until方法同樣代表了一種自定義的基本語義,使得表達時間域的問題更加自然。

雖然上面的兩個簡單例子和普通設(shè)計相比看不出太大的優(yōu)勢,但它卻為我們理解流暢接口打下了基礎(chǔ)。重要的是應(yīng)該體會到它們從一定程度上跳出了語言基本抽象機制的束縛,我們不應(yīng)該再用類職責劃分、迪米特法則(Law of Demeter)等OO設(shè)計原則來看待它們。

2.管道抽象

在Shell中,我們可以通過管道將一系列的小命令組合在一起實現(xiàn)復雜的功能。管道中流動的是單一類型的文本流,計算過程就是從輸入流到輸出流的變換過程,每個命令是對文本流的一次變換作用,通過管道將作用疊加起來。在Shell中,很多時候我們只需要一句話就能完成log統(tǒng)計這樣的中小規(guī)模問題。和其他抽象機制相比,管道的優(yōu)美在于無嵌套。比如下面這段C程序,由于嵌套層次較深,不容易一下子理解清楚:

  1. 2?//C ?
  2. min(max(min(max(a,b),c),d),e)? ?

而用管道來表達同樣的功能則清晰得多:

  1. ?
  2. 2?#!/bin/bash ?
  3. max?a?b?|?min?c?|?max?d?|?min?e? ?
  4. ?

我們很容易理解這段程序表達的意思是:先求a,b的最大值;再把結(jié)果和c取最小值;再把結(jié)果和d求最大值;再把結(jié)果和e求最小值。

jQuery的鏈式調(diào)用設(shè)計也具有管道的風格,方法鏈上流動的是同一類型的jQuery對象,每一步方法調(diào)用是對對象的一次作用,整個方法鏈將各個方法的作用疊加起來。

  1. 2?//Javascript ?
  2. $("li").filter(":event").css("background-color",?"red");? ?
  3. ?

3.層次結(jié)構(gòu)抽象

除了管道這種“線性”結(jié)構(gòu)外,流暢接口還可用于構(gòu)造層次結(jié)構(gòu)抽象。比如,用Javascript動態(tài)創(chuàng)建創(chuàng)建下面的HTML片段:

  1. ?id="’product_123’"?class="’product’">?
  2. [杭州網(wǎng)站制作]API設(shè)計新思維:用流暢接口構(gòu)造內(nèi)部DSL(圖1)?src="’preview_123.jpg’"?alt=""?/>?
    • ?
    • Name:?iPad2?32G
    • ?
    • Price:?3600
    • ?
    ?
? ?
  • ?
  • 若采用Javascript的DOM API:

    1. //Javascript ?
    2. var?div?=?document.createElement("div"); ?
    3. div.setAttribute(‘id’,?‘product_123’); ?
    4. div.setAttribute(‘class’,?‘product’); ?
    5. ?
    6. var?img?=?document.createElement("img"); ?
    7. img.setAttribute(‘src’,?‘preview_123.jpg’); ?
    8. div.appendChild(img); ?
    9. ?
    10. var?ul?=?document.createElement("ul"); ?
    11. var?li1?=?document.createElement("li"); ?
    12. var?txt1?=?document.createTextNode("Name:?iPad2?32G"); ?
    13. li1.appendChild(txt1); ?
    14. … ?
    15. div.appendChild(ul);? ?
    16. ?

    而下面流暢接口API則要有表現(xiàn)力得多:

    1. //Javascript ?
    2. var?obj?= ?
    3. $.div({id:’product_123’,?class:’product’}) ?
    4. .img({src:’preview_123.jpg’}) ?
    5. .ul() ?
    6. .li().text(‘Name:?iPad2?32G’)._li() ?
    7. .li().text(‘Price:?3600’)._li() ?
    8. ._ul() ?
    9. ._div();??

    和Javascript的標準DOM API相比,上面的API設(shè)計不再局限于孤立地看待某一個方法,而是考慮了它們在解決問題時的組合使用,所以代碼的表現(xiàn)形式特別貼近問題的本質(zhì)。這樣的代碼是自解釋的(self-explanatory)在可讀性方面要明顯勝于DOM API,這相當于定義了一種類似于HTML的內(nèi)部DSL,它擁有自己的語義和語法。需要特別注意的是,上面的層次結(jié)構(gòu)抽象和管道抽象有著本質(zhì)的不同,管道抽象的方法鏈上通常是同一對象的連續(xù)傳遞,而層次抽象中方法鏈上的對象卻在隨著層次的變化而變化。此為,我們可以把業(yè)務(wù)規(guī)則也表達在流暢接口中,比如上面的例子中,body()不能包含在div()返回的對象中,div().body()將拋出”body方法不存在”異常。(高端網(wǎng)站建設(shè))

    4.異步抽象

    流暢接口不僅可以構(gòu)造復雜的層次抽象,還可以用于構(gòu)造異步抽象。在基于回調(diào)機制的異步模式中,多個異步調(diào)用的同步和嵌套問題是使用異步的難點所在。有時一個稍復雜的調(diào)用和同步關(guān)系會導致代碼充滿了復雜的同步檢查和層層回調(diào),難以理解和維護。這個問題從本質(zhì)上講和上面HTML的例子一樣,是由于多數(shù)通用語言并未把異步作為基本元素/語義,許多異步實現(xiàn)模式是向語言的妥協(xié)。針對這個問題,我用Javascript編寫了一個基于流暢接口的異步DSL,示例代碼如下:

    1. //Javascript ?
    2. $.begin() ?
    3. .async(newTask("task1"),?"task1") ?
    4. .async(newTask("task2"),?"task2") ?
    5. .async(newTask("task3"),?"task3") ?
    6. .when() ?
    7. .each_done(function(name,?result)?{ ?
    8. console.log(name?+?":?"?+?result);}) ?
    9. .all_done(function(){?console.log("good,?all?completed");?}) ?
    10. .timeout(function(){ ?
    11. console.log("timeout!!"); ?
    12. $.begin() ?
    13. .async(newTask("task4"),?"task4") ?
    14. .when() ?
    15. .each_done(function(name,?result)?{ ?
    16. console.log(name?+?":?"?+?result);?}) ?
    17. .end();} ?
    18. ,?3000) ?
    19. .end();? ?

    上面的代碼只是一句Javascript調(diào)用,但從另一個角度看它卻像一段描述異步調(diào)用的DSL程序。它通過流暢接口定義了begin when end的語法結(jié)構(gòu),begin后面跟的是啟動異步調(diào)用的代碼;when后面是異步結(jié)果處理,可以選擇each_done, all_done, timeout中的一種或多種。而begin when end結(jié)構(gòu)本身是可以嵌套的,比如上面的代碼在timeout處理分支中就包含了另一個begin when end結(jié)構(gòu)。通過這個DSL,我們可以比基于回調(diào)的方式更好地表達異步調(diào)用的同步和嵌套關(guān)系。

    上面介紹了用流暢接口構(gòu)造的4種典型抽象,出此之外還有很多其他的抽象和應(yīng)用場合,比如:不少單元測試框架就通過流暢接口定義了單元測試的DSL。雖然上面的例子以Javascript等動態(tài)語言居多,但其實流暢接口所依賴的語法基礎(chǔ)并不苛刻,即使在Java這樣的靜態(tài)語言中,同樣可以輕松地使用。流暢接口不同于傳統(tǒng)的API設(shè)計,理解和使用流暢接口關(guān)鍵是要突破語言抽象機制帶來的定勢思維,根據(jù)問題域選取適當?shù)某橄缶S度,利用語言的基本語法構(gòu)造領(lǐng)域特定的語義和語法。

    內(nèi)容標簽:

    熱門文章

    ? ? 現(xiàn)在很多企業(yè)都著手于做重慶seo排名,因為SEO是獲取精準流量比較穩(wěn)定且長期發(fā)展好的方式之一,同時也能提升自身企業(yè)的品牌形象,因為SEO本身就是基于用戶體驗優(yōu)化而做的,因此做好SEO

    6830

    網(wǎng)絡(luò)營銷時代,軟文營銷已成為企業(yè)傳播品牌、促進訂單轉(zhuǎn)化的重要手段。不同于硬廣形式,軟文營銷的精華就在于“軟”字,即廣告綿里藏針,要在能提供給用戶有價值內(nèi)容的基礎(chǔ)上進行廣告

    ?文庫營銷指的是借助一些文庫平臺上傳文檔,通過知識分享來做品牌營銷,目前常見的文庫平臺有百度文庫、360圖書館、道客巴巴、豆丁文庫等。文庫營銷對文檔質(zhì)量要求較高,需要用戶自

    網(wǎng)站對于很多的企業(yè)來說,不僅僅是業(yè)務(wù)的渠道拓寬,也是多一個網(wǎng)站推廣的途徑和客戶渠道等,很多的企業(yè)雖然有自己的網(wǎng)站,但是重視程度不夠,很多的企業(yè)都只依靠網(wǎng)站就能夠養(yǎng)活一個公

    3298

    企業(yè)品牌推廣對于企業(yè)的生存來說是極其重要的,如果沒有一個好的推銷渠道的話,可能就會讓自己的商品賣不出去。在新聞中總是看到哪兒有什么產(chǎn)品賣不出去了,形成滯銷,讓個人或是企業(yè)

    3251

    一方面,不同客戶的建站需求不同;另一方面,網(wǎng)站建設(shè)人員的技術(shù)水平高低不一;同時,時效、地域因素也會對建站成本有所影響。所以網(wǎng)站建設(shè)的報價暫時沒有統(tǒng)一標準,建設(shè)費用更是從幾

    3073

    最先剖析要散播的目的客戶人群的陋習與話動范疇; 精心安排合乎網(wǎng)民愛好的論壇推廣時件或話動; 積淀論談有關(guān)社交圈子資源,會對進行論壇推廣出示挺大適用; 搞好數(shù)據(jù)分析,以知道論壇推廣的成功失敗之舉,加以改進。

    人們常常會遇上有些人做論壇推廣的當時,以便能短期內(nèi)內(nèi)看到作用,就在每個論談網(wǎng)站上注冊很多的id,花兩三天的時間就把各大論壇上貼的濃濃的全是軟廣,可是隔過段時間回來看,以前公布的全部貼子都被刪的干凈整潔,情況嚴重將會注冊的id也被封的干凈整潔,而針對這類人只有說成愛好者的論壇推廣技巧了。在進到這一議論以前,人們看一下自身是不是存有那樣的難

    在互聯(lián)網(wǎng)高速發(fā)展的今天,在眾多同行品牌的強勢競爭下,新品牌想要打開市場并不是一件容易的事兒。但不推廣就難以生存,那么我們應(yīng)該如何做好新品牌推廣,快速打開市場?云裂變徐國

    2975

    一個生產(chǎn)企業(yè)想要發(fā)展必須要創(chuàng)立自己的品牌,在人們購買東西講究牌子的今天,如果你所生產(chǎn)的產(chǎn)品連個牌子都沒有,恐怕會無人問津的。但是,有了品牌,對于小公司來說若是得到消費者的

    2945

    現(xiàn)在的推廣營銷方式與以前比起來可是多了不少,放在以前也就是還沒有網(wǎng)絡(luò)的時侯,商品商家和生產(chǎn)廠家想要把自己生產(chǎn)的和自己銷售的產(chǎn)品或是商品成功推銷出去那可就得想想辦法了。比如

    2944

    說起網(wǎng)絡(luò)營銷,讓人們想起了網(wǎng)上購物,比如在剛過去的520,就是一波網(wǎng)購的熱潮,各種打折促銷返利活動讓許多人心動,看花了眼。又比如每年的雙11、在雙12的網(wǎng)上促銷活動可謂是一年之內(nèi)

    2902

    很多企業(yè)在官網(wǎng)搭建完成之后,便放任不管,既不更新內(nèi)容、也不做任何的排名優(yōu)化,最后網(wǎng)站沒排名、沒流量、沒訪客;即使有排名、有流量導入,但是跳出率極高,依然產(chǎn)生不了任何效益。

    2884

    隨著網(wǎng)絡(luò)營銷、全網(wǎng)覆蓋等口號喊得越來越響,現(xiàn)在有不少的企業(yè)做網(wǎng)絡(luò)營銷都是被同行帶起來的,本質(zhì)上對網(wǎng)絡(luò)營銷推廣的作用都了解不多。那么網(wǎng)絡(luò)推廣好在哪?為什么一定要做好網(wǎng)絡(luò)推廣

    論壇推廣就是,企業(yè)利用論壇這種網(wǎng)絡(luò)交流的平臺,通過文字、圖片、視頻等方式發(fā)布企業(yè)的產(chǎn)品和服務(wù)的信息,從而讓目標客戶更加深刻地了解企業(yè)的產(chǎn)品和服務(wù)。最終達到企業(yè)宣傳企業(yè)的品牌、加深市場認知度的網(wǎng)絡(luò)營銷活動。1、電子公告板(BBS)是虛擬網(wǎng)絡(luò)小區(qū)的要素方法,小量的交流信息全是歷經(jīng)BBS進行的,vip歷經(jīng)貼到消息也許回應(yīng)消息抵達互相聯(lián)系的目地。一些簡

    受互聯(lián)網(wǎng)大趨勢影響,很多傳統(tǒng)企業(yè)紛紛著手布局網(wǎng)絡(luò)營銷,考慮到企業(yè)自身在營銷經(jīng)驗上有欠缺,不少老板會選擇找全網(wǎng)營銷外包公司合作,這個時候就會出現(xiàn)很多選擇難題。比如說找了10家

    2826

    隨著社會的發(fā)展和人們消費觀念的改變,現(xiàn)在人們的消費已經(jīng)從單純的商品能使用消費階段到了商品品牌消費階段了。在進行商品購買時總是看商品的品牌,就拿一些年輕人來說吧,對于耐克、

    2817

    百科營銷是一種以權(quán)威知識分享的形式對企業(yè)做有目的性的品牌宣傳,可以有效提高潛在客戶對企業(yè)品牌或產(chǎn)品服務(wù)的信任度及認可度,最終達到提升企業(yè)品牌知名度美譽度的雙重作用。那么百

    護膚品作為當下大受女性追捧的快消品,行業(yè)競爭激烈,且更新?lián)Q代尤其迅速。那么如何在如此變幻莫測的市場競爭中占領(lǐng)高地呢?這自然少不了大面積的營銷推廣(包括線上和線下),下面全

    一、前端seo代碼優(yōu)化注意事項1、提高頁面加載速度。CSS可以用來解決不使用背景圖片的問題,也可以嘗試壓縮背景圖片的大小,你可以在一張圖片上放置幾個圖標,使用CSSsprite,使用背景位置

    2695

    最新文章