在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

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

3天內不再提示

這5個事項讓你設計出良好開發接口

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

>>>>1.5.2 建立抽象

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

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

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

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

>>>>1.5.3 建立接口

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

>>>1. 函數調用

(1)傳值調用

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

swap(a, b);

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

一個變量的有效范圍稱作它的作用域,變量的作用域指可以通過變量名稱引用變量的區域,在函數內部聲明的變量只在該函數內部有效。當主調函數調用子函數時,主函數內聲明的變量在子函數內無效,子函數內聲明的變量也只在該子函數內部有效。

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

(2)傳址調用

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

swap(&a, &b);

利用指針作為函數參數傳遞數據的本質,就是在主調函數和被調函數中,通過不同的指針指向同一內存地址訪問相同的內存區域,即它們背后共享相同的內存,從而實現數據的傳遞和交換。

>>>2.函數原型

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

(1)函數形參

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

swap(int *p1, int *p2);

(2)返回值的類型

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

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

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

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

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

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

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

這是一個不斷迭代優化的過程,用戶只需要知道“函數名、傳入函數的參數和函數返回值的類型”,就知道如何有效地調用相應的函數。

>>>3.依賴倒置原則

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

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

● 抽象接口不應該依賴于細節,細節應該依賴抽象接口。

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

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

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

1 #ifndef _SWAP_H

2 #define _SWAP_H

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

4 //后置條件:p1、p2作為輸出參數,改變主調函數中相應的變量

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

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

7 #endif

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

>>>4.前/后置條件

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

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

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

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

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

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

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

>>>5. 開閉原則

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

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5087

    文章

    19148

    瀏覽量

    306171
  • 接口
    +關注

    關注

    33

    文章

    8650

    瀏覽量

    151409

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

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

收藏 人收藏

    評論

    相關推薦

    好習慣的PCB設計更優

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

    嵌入式linux開發要點,輕松入門

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

    好習慣的PCB設計更優

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

    電路設計技巧真的掌握了嗎?

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

    快速開發快應用應該了解的5神器

    想快速開發快應用?需要知道5大神器
    發表于 02-13 10:10

    學會6步驟,輕松成為FPGA設計高手

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

    好習慣的PCB設計更優

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

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

    現在大多數人在選擇畫板軟件時選擇使用AD 因為其強大的兼容性,這里給你們分享一些技巧,你們成為別人眼中的高手。AD設計小技巧--快捷的操作,重要的注意事項變成嚴謹的工程師AD快捷
    發表于 07-19 08:00

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

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

    HK32F030M開發板使用說明及其注意事項

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

    香港成功研制“腦機接口”系統

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

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

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

    MIUI的10小設置都知道嗎

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

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

    很多人對于儀器儀表出現故障方面還不是很清楚,下面安泰維修專業從事儀器儀表維修工程師帶大家了解一下關于儀器儀表出現故障5種檢測方法,少走彎路!有需要的朋友可以閱讀全文! 一:比照 詳細辦法是:
    的頭像 發表于 11-14 14:15 ?1437次閱讀
    儀器儀表出現維修故障,<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作用你知道嗎
    的頭像 發表于 11-22 11:14 ?8488次閱讀
    主站蜘蛛池模板: 四虎在线永久视频观看| 香蕉久久精品| 六月丁香激情网| 黄色的视频网站| 55夜色66夜色国产精品站| 美女拍拍拍爽爽爽爽爽爽| 人与禽交免费网站视频| 欧美爽爽网| 婷婷精品视频| 天堂tv亚洲tv日本tv欧美人tv| 天天射综合| 日本人zzzwww色视频| 美女黄视频免费| 国产精品欧美一区二区三区| 日日夜夜噜| 你懂在线| 岛国最新资源网站| 五月停停| www.av毛片| 男女视频在线观看免费| 亚洲成人激情电影| 人人搞人人搞| 好吊操免费视频| 午夜在线观看福利| 永久免费在线观看视频| 天天干天天操天天摸| 成人黄色免费网站| 欧美亚洲h在线一区二区| 亚洲六月婷婷| 男人天堂网在线| aaaaaaaaa在线观看| 精品国产午夜久久久久九九| 91美女啪啪| 天堂中文资源网| 激情综合视频| 手机在线看片福利| 黄色在线网站视频| 五月开心六月伊人色婷婷| 久久极品| 人人玩人人添天天爽| 在线视频三区|