精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

這5個事項讓你設(shè)計出良好開發(fā)接口

AGk5_ZLG_zhiyua ? 來源:未知 ? 作者:劉勇 ? 2017-11-20 09:31 ? 次閱讀

>>>>1.5.2 建立抽象

抽象化的目的是使調(diào)用者無需知道模塊的內(nèi)部細節(jié),只需要知道模塊或函數(shù)的名字,因此將其稱為黑盒化。調(diào)用者只需要知道黑盒子的輸入和輸出,而過程的細節(jié)是隱藏的。由于建立了一個由黑盒子組成的系統(tǒng),因此復(fù)雜的結(jié)構(gòu)就被黑盒子隱藏起來了,則理解系統(tǒng)的整體結(jié)構(gòu)就變得更容易了。

從概念的視角來看,建立抽象關(guān)注的不是如何實現(xiàn),而是函數(shù)要做什么,過早地關(guān)注實現(xiàn)細節(jié),將實現(xiàn)細節(jié)隱藏起來,進而幫助我們構(gòu)建更易于修改的軟件。因此,我們首先應(yīng)該選擇一個具有描述性的符合需求的名字,雖然可以選擇的名字有swapByte、swapWord和swap,但swap更簡潔更貼切。其次,可以用一句話概念性地描述swap的數(shù)據(jù)抽象——swap是實現(xiàn)兩個數(shù)據(jù)交換的函數(shù)。

顯然,調(diào)用者僅需一般性地在概念層次上與實現(xiàn)者交流,因為調(diào)用者的意圖是如何使用swap()實現(xiàn)兩個數(shù)據(jù)的交換,所以無需準確地知道實現(xiàn)的細節(jié)。而具體如何完成數(shù)據(jù)的交換,這是在實現(xiàn)層次進行的。由此可見,將模塊的目的與實現(xiàn)分離的抽象揭示了問題的本質(zhì),并沒有提供解決方案。只說明需要做什么,并不會指出如何實現(xiàn)某個模塊。只要概念不變,調(diào)用者與實現(xiàn)細節(jié)的變化就徹底隔離了。當某個模塊完成編碼后,只要說明該模塊的目的和參數(shù)就可以使用它,無需知道具體的實現(xiàn)。

函數(shù)抽象對團隊項目非常重要,因為在團隊中必須使用其他成員編寫的模塊。比如,編程語言本身自帶的庫函數(shù),由于已經(jīng)被預(yù)編譯,因此無法訪問它的源代碼。同時庫函數(shù)不一定是用C編寫的,因此只要知道其調(diào)用規(guī)范,就可以在程序中毫無顧忌地使用這個函數(shù)。實際上,在使用scanf()函數(shù)的過程中,我們考慮過scanf()是如何實現(xiàn)的嗎?無關(guān)緊要。盡管不同系統(tǒng)實現(xiàn)scanf()的方法可能不一樣,但其中的不同對于程序員來說是透明的。

>>>>1.5.3 建立接口

接口是由公開訪問的方法和數(shù)據(jù)組成的,接口描述了與模塊交互的唯一途徑。最小化的接口只包含對于接口的任務(wù)非常重要的參數(shù),最小化的接口便于學(xué)習(xí)如何與之交互,且只需要理解少量的參數(shù),同時易于擴展和維護,因此設(shè)計良好的接口是一項重要的技能。

>>>1. 函數(shù)調(diào)用

(1)傳值調(diào)用

如何調(diào)用swap()函數(shù)呢?實參將值從主調(diào)函數(shù)傳遞給被調(diào)函數(shù),也許其調(diào)用形式是下面這樣的:

swap(a, b);

從黑盒視角來看,形參和其它局部變量都是函數(shù)私有的,聲明在不同函數(shù)中的同名變量是完全不同的變量,而且函數(shù)無法直接訪問其它函數(shù)中的變量,這種限制訪問保護了數(shù)據(jù)的完整性,黑盒發(fā)生了什么對主調(diào)函數(shù)是不可見的。

一個變量的有效范圍稱作它的作用域,變量的作用域指可以通過變量名稱引用變量的區(qū)域,在函數(shù)內(nèi)部聲明的變量只在該函數(shù)內(nèi)部有效。當主調(diào)函數(shù)調(diào)用子函數(shù)時,主函數(shù)內(nèi)聲明的變量在子函數(shù)內(nèi)無效,子函數(shù)內(nèi)聲明的變量也只在該子函數(shù)內(nèi)部有效。

由于傳遞給函數(shù)的是變量的替身,因此改變函數(shù)參數(shù)對原始變量沒有影響。當變量傳遞給函數(shù)時,變量的值被復(fù)制給函數(shù)參數(shù)。由此可見,通過“傳值調(diào)用”方式交換a、b的值,無法改變主調(diào)函數(shù)相應(yīng)變量的值。

(2)傳址調(diào)用

如果希望通過被調(diào)函數(shù)將更多的值傳回主調(diào)函數(shù)而改變主調(diào)函數(shù)中的變量,則使用“傳址調(diào)用”——將&a、&b作為實參傳遞給形參。其調(diào)用形式如下:

swap(&a, &b);

利用指針作為函數(shù)參數(shù)傳遞數(shù)據(jù)的本質(zhì),就是在主調(diào)函數(shù)和被調(diào)函數(shù)中,通過不同的指針指向同一內(nèi)存地址訪問相同的內(nèi)存區(qū)域,即它們背后共享相同的內(nèi)存,從而實現(xiàn)數(shù)據(jù)的傳遞和交換。

>>>2.函數(shù)原型

函數(shù)原型是C語言的一個強有力的工具,它讓編譯器捕獲在使用函數(shù)時可能出現(xiàn)的許多錯誤或疏漏。如果編譯器沒有發(fā)現(xiàn)這些問題,就很難察覺出來。函數(shù)原型包括函數(shù)返回值的類型、函數(shù)名和形參列表(參數(shù)的數(shù)量和每個參數(shù)的類型),有了這些信息,編譯器就可以檢查函數(shù)調(diào)用與函數(shù)原型是否匹配?比如,參數(shù)的數(shù)量是否正確?參數(shù)的類型是否匹配?如果類型不匹配,編譯器會將實參的類型轉(zhuǎn)換成形參的類型。

(1)函數(shù)形參

通過程序清單 1.15可以看出,其相同的處理部分是2個int類值的交換代碼,因此可以將數(shù)據(jù)交換代碼移到swap()函數(shù)的實現(xiàn)中,其可變的數(shù)據(jù)由外部傳進來的參數(shù)應(yīng)對。由于&a是指向int類型變量a的指針,&b是指向int類型變量b的指針,因此必須將p1、p2形參聲明為指向int *類型的指針變量,即必須將存儲int類型值變量的地址作為實參賦給指針形參,實參與形參才能匹配。其函數(shù)原型進化如下:

swap(int *p1, int *p2);

(2)返回值的類型

聲明函數(shù)時必須聲明函數(shù)的類型,帶返回值的函數(shù)類型應(yīng)該與其返回值類型相同,而沒有返回值的函數(shù)應(yīng)該聲明為void。類型聲明是函數(shù)定義的一部分,函數(shù)類型指的是返回值的類型,不是函數(shù)參數(shù)的類型。

雖然可以使用return返回值,但return只能返回一個值給主調(diào)函數(shù)。比如,如果返回值為整數(shù),則函數(shù)返回值的類型為int。當返回值為int類型時,如果返回值為負數(shù),則表示失敗;如果返回值為非負數(shù),則表示成功。當返回值為bool類型時,如果返回值為false,則表示失敗,如果返回值為true,則表示成功。當返回值為指針類型時,如果返回值為NULL,則表示失敗,否則返回一個有效的指針。

如果利用指針作為參數(shù)傳遞給函數(shù),不僅可以向函數(shù)傳入數(shù)據(jù),而且還可以從函數(shù)返回多個值。因為函數(shù)的調(diào)用者和函數(shù)都可以使用指向同一內(nèi)存地址的指針,即使用同一塊內(nèi)存,所以使用指針作為函數(shù)參數(shù)時就是對同一數(shù)據(jù)進行讀寫操作。這樣不僅可以傳入數(shù)據(jù),還可以通過在函數(shù)內(nèi)部修改這些數(shù)據(jù),將函數(shù)的結(jié)果傳出給調(diào)用者。

當函數(shù)的實參是指針變量時,有時希望函數(shù)能通過指針指向別處的方式改變此變量,則需要使用指向指針的指針作為形參。

由于swap()無返回值,因此swap()返回值的類型為void,其函數(shù)原型如下:

void swap(int *p1, int *p2);

其被解釋為swap是返回void的函數(shù)(參數(shù)是int *p1,int *p2)。

這是一個不斷迭代優(yōu)化的過程,用戶只需要知道“函數(shù)名、傳入函數(shù)的參數(shù)和函數(shù)返回值的類型”,就知道如何有效地調(diào)用相應(yīng)的函數(shù)。

>>>3.依賴倒置原則

在面向過程編程中,通常的做法是高層模塊調(diào)用低層模塊,其目的之一就是要定義子程序?qū)哟谓Y(jié)構(gòu)。當高層模塊依賴于低層模塊時,對低層模塊的改動會直接影響高層模塊,從而迫使它們依次做出修改。如果高層模塊獨立于低層模塊,則高層模塊更容易重用,這就是分層架構(gòu)設(shè)計的核心原則,即依賴倒置原則(Dependence Inversion Principle,DIP):

● 高層模塊不應(yīng)該依賴低層模塊,兩者都應(yīng)該依賴于抽象接口;

● 抽象接口不應(yīng)該依賴于細節(jié),細節(jié)應(yīng)該依賴抽象接口。

當在分層架構(gòu)中使用依賴倒置原則時,將會發(fā)現(xiàn)“不再存在分層”的概念了。無論是高層還是低層,它們都依賴于抽象接口,好像將整個分層架構(gòu)推平一樣。

其實從“Hello World”程序開始,我們就已經(jīng)在使用stdio.h包含的“抽象接口”了,即以后凡是用#include文件的擴展名叫.h(頭文件)。如果源代碼中要用到stdio標準輸入輸出函數(shù)時,那么就要包含這個頭文件,比如,“scanf("%d",&i);”函數(shù),其目的是告訴編譯器要使用stdio庫。庫是一種工具的集合,這些工具是由其它程序員編寫的,用于實現(xiàn)特定的功能。盡管實現(xiàn)者無需關(guān)心用戶將如何使用庫,且不會直接開放源代碼給用戶使用,但必須給用戶提供調(diào)用函數(shù)所需要的信息。顯然只要將頭文件開放給用戶,即可讓用戶了解接口的所有細節(jié),詳見程序清單 1.16。

程序清單1.16swap數(shù)據(jù)交換接口(swap.h)

1 #ifndef _SWAP_H

2 #define _SWAP_H

3 //前置條件:實參必須是int類型變量的地址

4 //后置條件:p1、p2作為輸出參數(shù),改變主調(diào)函數(shù)中相應(yīng)的變量

5 void swap(int *p1, int *p2);

6 //調(diào)用形式:swap(&a, &b)

7 #endif

其中,每個頭文件都指出了一個用戶可見的外部函數(shù)接口,主要包括函數(shù)名、所需的參數(shù)、參數(shù)的類型和返回結(jié)果的類型。其中,swap是庫的名字,程序清單 1.16(1~2)與(8)是幫助編譯器記錄它所讀取的接口,當寫一個接口時,必須包含#ifndef、#define和#ednif。#include行部分僅當接口本身需要其它庫時才使用,它由標準的#include行組成。程序清單 1.16(6)接口項表示庫輸出的函數(shù)的原型、常量和類型等。不管你是否理解,這些行是接口的模板文件,這就是信息隱藏。

>>>4.前/后置條件

處理信息隱藏還涉及到另一個技術(shù),那就是使用前置條件和后置條件描述函數(shù)的行為。在編寫一個完整的函數(shù)定義時,需要描述該函數(shù)是如何執(zhí)行計算的。但在使用函數(shù)時,只需考慮該函數(shù)能做什么,無需知道是如何完成的。當不知道函數(shù)是如何實現(xiàn)時,就是在使用一種名為過程抽象的信息隱藏形式,它抽象掉的是函數(shù)如何工作的細節(jié)。計算機科學(xué)家使用“過程”表示任意指令集,因此使用術(shù)語過程抽象。過程抽象是一種強大的工具,使得我們一次只考慮一個而不是所有的函數(shù),從而使問題求解簡單化。

為了使描述更準確,則需要遵循固定的格式,它包含兩部分信息:函數(shù)的前置條件和后置條件。前置條件就是調(diào)用該函數(shù)必須成立的條件,當函數(shù)被調(diào)用時,該語句給出要求為真的條件。除非前置條件為真,否則無法保證函數(shù)能正確執(zhí)行。在調(diào)用swap()函數(shù)時,實參必須是int類型變量的地址,這是調(diào)用者的職責。通常在函數(shù)開始處檢查是否滿足?如果不滿足,說明調(diào)用代碼有問題,拋出一個異常。

后置條件就是該操作完成后必須成立的條件,當函數(shù)調(diào)用時,如果函數(shù)是正確的,而且前置條件為真,那么該函數(shù)調(diào)用將可以執(zhí)行完成。當函數(shù)調(diào)用完成后,后置條件為真。如果不滿足后置條件,則說明業(yè)務(wù)邏輯有問題。

當滿足調(diào)用swap()函數(shù)的前置條件時,必須同時確保其結(jié)束時滿足它的后置條件,其后置條件是被調(diào)函數(shù)將返回值傳回主調(diào)函數(shù),改變主調(diào)函數(shù)中變量的值。

前后置條件不只是概括地描述函數(shù)的行為,聲明這些條件應(yīng)該是設(shè)計任何函數(shù)的第一步。在開始考慮某個函數(shù)的算法和代碼之前,應(yīng)該寫出該函數(shù)的原型,其中包括函數(shù)的返回類型、名稱和參數(shù)列表,最后緊跟一個分號。直接來自于用戶的輸入不能作為前置條件,通常前/后置條件都可以轉(zhuǎn)化為assert語句。編寫函數(shù)原型時,應(yīng)該以注釋的形式描述該函數(shù)的前置條件和后置條件。

事實上,前置條件和后置條件在使用函數(shù)的程序員和編寫函數(shù)的程序員之間形成了一個契約,也就是為什么需要這個函數(shù)?接口通過前置條件和后置條件以契約的形式表達需求,承諾在滿足前置條件時開始,按照程序的流程運行,系統(tǒng)就能到達后置條件。

雖然注釋是一種很好的溝通形式,但在代碼可以傳遞意圖的地方不要寫注釋。因為代碼解釋做了什么,再注釋也沒有什么用處,相反注釋要說明為什么會這樣寫代碼?

>>>5. 開閉原則

接口僅需指明用戶調(diào)用程序可能調(diào)用的標識符,應(yīng)盡可能地將算法以及一些與具體的實現(xiàn)細節(jié)無關(guān)的信息隱藏起來,這樣用戶在調(diào)用程序時也就不必依賴特定的實現(xiàn)細節(jié)了。當接口一旦發(fā)布后,也就不能改變了,因為改變接口勢必引起用戶程序的改變。如果此前定義的接口滿足不了需求,怎么辦?只能擴展新的接口,但不能修改或廢除原有的接口,這就是“對修改關(guān)閉,對擴展開放”的開閉原則(Open-Closed Princple,OCP)。顯然,依賴倒置原則更加精確的定義就是面向接口的編程,它是實現(xiàn)開閉原則的重要途徑。如果DIP依賴倒置原則沒有實現(xiàn),就別想實現(xiàn)對擴展開放,對修改關(guān)閉。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5072

    文章

    19026

    瀏覽量

    303523
  • 接口
    +關(guān)注

    關(guān)注

    33

    文章

    8526

    瀏覽量

    150862

原文標題:周立功:設(shè)計良好的程序接口需注意的5個事項

文章出處:【微信號:ZLG_zhiyuan,微信公眾號:ZLG致遠電子】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    好習(xí)慣的PCB設(shè)計更優(yōu)

    取舍,兼顧性能,成本,工藝等各個方面,又要注意到板子布局的合理整齊,并沒有看上去的那么簡單,需要更多的智慧。好的工作習(xí)慣,會受益匪淺,使的設(shè)計更合理,生產(chǎn)更容易,性能更好。下面給大家列出以下六
    發(fā)表于 05-16 15:25

    嵌入式linux開發(fā)要點,輕松入門

    嵌入式linux開發(fā)要點,是華清遠見精華版的,可以輕松入門,快快下載看看
    發(fā)表于 05-18 14:52

    好習(xí)慣的PCB設(shè)計更優(yōu)

    受益匪淺,使的設(shè)計更合理,生產(chǎn)更容易,性能更好。下面給大家列出以下六受益匪淺的好習(xí)慣。  (一) 細節(jié)決定成敗  PCB設(shè)計是一
    發(fā)表于 06-15 11:51

    電路設(shè)計技巧真的掌握了嗎?

    按照的需要表述電路的方框圖對電路的成功設(shè)計至關(guān)重要。在你開始工作之前,方框圖為提供了一大綱,它還為將要查看和檢查電路的任何人提供了極好的參考資料。圖1:單張大幅原理圖2.各個擊
    發(fā)表于 01-16 10:43

    快速開發(fā)快應(yīng)用應(yīng)該了解的5神器

    想快速開發(fā)快應(yīng)用?需要知道5大神器
    發(fā)表于 02-13 10:10

    學(xué)會6步驟,輕松成為FPGA設(shè)計高手

    的物理特性非常了解,而且要懂得是時序約束等設(shè)計方法,要看大量的原廠文檔,這部分成功了,那就對FPGA的物理接口掌握很深,就是一高手了。
    發(fā)表于 03-26 06:00

    好習(xí)慣的PCB設(shè)計更優(yōu)

    ,兼顧性能,成本,工藝等各個方面,又要注意到板子布局的合理整齊,并沒有看上去的那么簡單,需要更多的智慧。好的工作習(xí)慣,會受益匪淺,使的設(shè)計更合理,生產(chǎn)更容易,性能更好。下面給大家列出以下六
    發(fā)表于 07-11 10:59

    教你幾個AD小技巧,菜鳥變高手

    現(xiàn)在大多數(shù)人在選擇畫板軟件時選擇使用AD 因為其強大的兼容性,這里給你們分享一些技巧,你們成為別人眼中的高手。AD設(shè)計小技巧--快捷的操作,重要的注意事項變成嚴謹?shù)墓こ處烝D快捷
    發(fā)表于 07-19 08:00

    如何在程序中SPI接口的SPI_CLK輸出一5k的采樣脈沖?

    請教: 1. 如何在程序中SPI接口的SPI_CLK輸出一5k的采樣脈沖? 2. 每次采樣600000數(shù)據(jù),我把它存在SDRAM中,S
    發(fā)表于 07-26 07:38

    HK32F030M開發(fā)板使用說明及其注意事項

    測試HK32F030MJ4M6-SO8N剛拿到開發(fā)板無從下手,多謝航工程師耐心指導(dǎo)。下面是航老板說明,新板增加了HK32F030MJ4M6-SO8N封裝,航順 HK32F030M開發(fā)
    發(fā)表于 02-11 07:35

    香港成功研制“腦機接口”系統(tǒng)

    日前,香港中文大學(xué)成功研制“腦機接口”系統(tǒng),可將腦電波轉(zhuǎn)換成繁體中文字,全身癱瘓而無法說話的病人,有機會打開心窗。
    發(fā)表于 05-02 15:09 ?1276次閱讀

    如何使用Excel來提高的工作效率10Excel基本技巧事半功倍

    Excel可以說是MS Office系列中最神奇也最重要的軟件。別再傻傻地用鼠標點來點去啦!用10基本技巧來提高工作效率,做Excel事半功倍
    的頭像 發(fā)表于 08-26 10:03 ?1.2w次閱讀

    MIUI的10小設(shè)置都知道嗎

    其實在MIUI里,藏著很多個性化的選擇,接下來的10小設(shè)置,都知道嗎?
    的頭像 發(fā)表于 05-08 16:53 ?4282次閱讀

    儀器儀表出現(xiàn)維修故障,5檢測辦法,少走彎路!

    很多人對于儀器儀表出現(xiàn)故障方面還不是很清楚,下面安泰維修專業(yè)從事儀器儀表維修工程師帶大家了解一下關(guān)于儀器儀表出現(xiàn)故障5種檢測方法,少走彎路!有需要的朋友可以閱讀全文! 一:比照 詳細辦法是:
    的頭像 發(fā)表于 11-14 14:15 ?1369次閱讀
    儀器儀表出現(xiàn)維修故障,<b class='flag-5'>這</b><b class='flag-5'>5</b><b class='flag-5'>個</b>檢測辦法,<b class='flag-5'>讓</b><b class='flag-5'>你</b>少走彎路!

    pcb菲林是什么?5作用你知道嗎

    pcb菲林是什么?5作用你知道嗎
    的頭像 發(fā)表于 11-22 11:14 ?7840次閱讀