日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Effective Dart 文档注释在Flutter项目中的实践

發布時間:2023/12/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Effective Dart 文档注释在Flutter项目中的实践 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

什么是注釋?

在編程語言中,注釋就是對代碼的解釋和說明,其目的是讓人們能夠更加輕松地了解代碼。

也有一句話是這樣說的:程序員都討厭兩件事,1.別人不寫注釋 2.自己寫注釋

在開發者社區里,我不止一次的看到吐槽離職的前同事不寫注釋的例子,其實不光是他人的代碼,即使是自己寫的代碼,一段時間以后再去看,你也會發現:這寫的什么呀

作為開發者,我們大多都知道編寫注釋的重要性,但是卻往往抱著"能實現功能就可以了"這樣的心態去寫代碼,完全隨心所欲的去實現,結果當然就是留下一堆爛攤子,形成前文所述的惡性循環,所以在編寫代碼的同時,請牢記代碼首先是寫給人看的

編寫精煉的、準確的注釋 只需要幾秒鐘,但是以后可能節省其他人幾個小時 的時間來讀懂您的代碼。

寫好注釋

寫注釋簡單嗎?簡單。那么寫好注釋,簡單嗎?

答案就跟寫文章一樣,有的文章是記流水賬,有的則是發人深省,回味無窮。

注釋也是同樣,在《代碼精進之路》里總結了編寫注釋的三項原則:

  • 準確,錯誤的注釋比沒有注釋更糟糕。
  • 必要,多余的注釋浪費閱讀者的時間。
  • 清晰,混亂的注釋會把代碼搞得更亂。
  • 比如,當我們說編程語言時,一定不要省略“編程”這兩個字。否則,就可能被誤解為大家日常說話用的自然語言。這就是準確性的要求。

    bad:

    String language = "Java"; // the language 復制代碼

    better:

    String language = "Java"; // the programming language 復制代碼

    如果代碼已經能夠清晰、簡單地表達自己的語義和邏輯,這時候重復代碼語義的注釋就是多余的注釋。注釋的維護是耗費時間和精力的,所以,不要保留多余的、不必要的注釋。還有一句很精辟的話:Code tells you How, Comments tell you Why.

    bad:

    // the programming language String programmingLanguage = "Java"; 復制代碼

    better:

    String programmingLanguage = "Java"; 復制代碼

    如果注釋和代碼不能從視覺上清晰地分割,注釋就會破壞代碼的可讀性。

    bad:

    /* dump debug information if (hasDebug) {System.out.println("Programming language: Jave"); } */ String programmingLanguage = "Java"; 復制代碼

    better:

    // dump debug information // // if (hasDebug) { // System.out.println("Programming language: Jave"); // } String programmingLanguage = "Java"; 復制代碼

    《Effective Dart》中關于如何寫注釋,也推薦要清晰和準確,同時還有簡潔

    在運用Dart語言編寫Flutter應用的過程中,由于視圖層都是純Dart代碼,而且夾雜著許多的if..else..,需要根據條件顯示不同的widget,因此在做好widget拆分的同時,編寫良好的注釋勢在必行。

    Effective Dart 文檔注釋

    在學習并使用Flutter框架開發App的過程中,有些開發者并沒有怎么關注Dart語言,草草看了幾下語法之后就開始了Flutter之旅,還是按照以前的Java、Swift這樣的語法風格進行開發,這在以后可能會帶來不必要的麻煩,比如團隊成員里各個都不同的命名方式、注釋也各不相同等等。

    因此推薦先看一下 《Effective Dart》,主要內容包含代碼風格文檔注釋最佳實踐設計指南,能從中獲益良多。我們主要關心文檔注釋這一章節,這里我總結了以下兩點:

  • 使用///放棄/** ... */

  • 在《Effective Dart》解釋了相應原因

    由于歷史原因,dartdoc 支持兩種格式的文檔注釋: /// (“C# 格式”) 和 /** ... */ (“JavaDoc 格式”)。我們推薦使用 /// 是因為其更加簡潔。/** 和 */ 在多行注釋中間添加了開頭和結尾的兩行多余 內容。 /// 在一些情況下也更加易于閱讀,例如 當注釋文檔中包含有使用 * 標記的列表內容的時候。

    如果你現在還在使用 JavaDoc 風格格式,請考慮 使用新的格式。

    與此同時,要使用 /// 文檔注釋來注釋成員和類型。

    bad:

    // The number of characters in this chunk when unsplit. int get length => ... 復制代碼

    better:

    /// The number of characters in this chunk when unsplit. int get length => .. 復制代碼

    而//則主要用于方法體內的注釋

    greet(name) {// Assume we have a valid name.print('Hi, $name!'); } 復制代碼
  • 把第一個語句定義為一個段落并使用散文的方式來描述

  • 注釋文檔中的第一個段落應該是簡潔的、面向用戶的注釋。例如下面的示例, 通常不是一個完成的語句。

    bad:

    /// Starts a new block as a child of the current chunk. Nested blocks are /// handled using their own independent [LineWriter]. ChunkBuilder startBlock() { ... } 復制代碼

    better:

    /// Defines a flag. /// /// Throws an [ArgumentError] if there is already an option named [name] or /// there is already an option using abbreviation [abbr]. Returns the new flag. Flag addFlag(String name, String abbr) { ... } 復制代碼

    這就跟日常寫博客一樣,會先寫一個段落大意,然后圍繞著這點進行詳細描述,這樣更容易讓讀者理解核心思想,也更加節省時間。

    另外推薦使用散文的方式來描述參數、返回值以及異常信息。

    在其他語言中,比如JavaDoc使用各種標簽和額外的注釋來描述參數和 返回值。

    bad:

    /// Defines a flag with the given name and abbreviation. /// /// @param name The name of the flag. /// @param abbr The abbreviation for the flag. /// @returns The new flag. /// @throws ArgumentError If there is already an option with /// the given name or abbreviation. Flag addFlag(String name, String abbr) { ... } 復制代碼

    而 Dart 把參數、返回值等描述放到文檔注釋中,并使用方括號來引用 以及高亮這些參數和返回值。

    better:

    /// Defines a flag. /// /// Throws an [ArgumentError] if there is already an option named [name] or /// there is already an option using abbreviation [abbr]. Returns the new flag. Flag addFlag(String name, String abbr) { ... } 復制代碼

    我們主要注意這兩點,其它規范可以查看《文檔注釋》。

    在mvvm_flutter項目中的實踐

    mvvm_flutter是我在Flutter中運用MVVM架構的一個示例。

    mvvm_flutter : github.com/ditclear/mv…

    項目完成后只簡單的在幾個關鍵方法上添加了幾個JavaDoc格式的注釋,比如:

    /*** call the model layer 's method to login* doOnData : handle response when success* doOnError : handle error when failure* doOnListen : show loading when listen start* doOnDone : hide loading when complete*/Observable login() => _repo.login(username, password).doOnData((r) => response = r.toString()).doOnError((e, stacktrace) {if (e is DioError) {response = e.response.data.toString();}}).doOnListen(() => loading = true).doOnDone(() => loading = false); 復制代碼

    現在我們開始將其轉換為Dart語言推薦的注釋風格。如下所示:

    /// 登錄////// 調用 model層[GithubRepo] 的 login 方法進行登錄/// 傳入 [username] 和 [password] /// 成功:顯示返回的信息/// 失敗:處理錯誤,顯示錯誤信息/// 訂閱開始:loading = true/// 訂閱結束:loading = false/// 返回 [Observable] 給 View 層Observable login() => _repo.login(username, password).doOnData((r) => response = r.toString()).doOnError((e, stacktrace) {if (e is DioError) {response = e.response.data.toString();}}).doOnListen(() => loading = true).doOnDone(() => loading = false); 復制代碼

    相比之前的代碼,清晰干凈了蠻多,我們在注釋的第一行中描述了這個方法的功能,隨后以散文的方式對方法的調用、參數以及返回值進行了描述。

    這是ViewModel層的注釋,接下來我們來進行Model層的注釋。

    class GithubRepo {/// ...Observable login(String username, String password) {_sp.putString(KEY_TOKEN, "basic " + base64Encode(utf8.encode('$username:$password')));return _remote.login();} }復制代碼

    我們對login方法進行注釋,結果如下:

    /// 倉庫層 class GithubRepo {/// 登錄////// 將ViewModel層 傳遞過來的[username] 和 [password] 處理為 token 并用[_sp]進行緩存/// 調用 [_remote] 的 [login] 方法進行網絡訪問/// 返回 [Observable] 給ViewModel層Observable login(String username, String password) {_sp.putString(KEY_TOKEN, "basic " + base64Encode(utf8.encode('$username:$password')));return _remote.login();} }復制代碼

    這里方法比較簡單,但對于復雜的倉庫層的方法,可能包含著網絡、數據庫、MethodChannel、SharedPreferences等等交互,運用Dart推薦的注釋方式,可以更好的描述你的代碼邏輯。

    /// 獲取文章詳情////// 1.先通過 數據庫[_local] 查看本地是否有 id 為 [articleId]的文章/// 2.有緩存則到第4步,沒有緩存則到第3步/// 3.通過網絡層[_remote] 獲取服務端數據,成功后再進行緩存 ,到第4步/// 4.返回 [Observable] 給ViewModel層Observable getArticleDetail(int articleId) {return _local.getArticleById(articleId).onErrorResumeNext(_remote.getArticleById(articleId).doOnData((article) => _local.insertArticle(article)));} 復制代碼

    這樣,我們輕松的拆解了代碼邏輯,也能更容易的編寫出相應的測試用例,方便進行單元測試。

    而View層相比Model層和ViewModel層,需要額外注意的是其夾雜著邏輯判斷,需要根據條件顯示不同的Widget,我們在將復雜部分提取成方法的時候,也需要對其進行詳細的描述。

    /// 登錄按鈕內部的widget /// /// 當請求進行時 [value.loading] 為 true 時,顯示 [CircularProgressIndicator] /// 否則顯示普通的登錄文本 Widget buildLoginChild(HomeProvide value) {if (value.loading) {return const CircularProgressIndicator();} else {return const FittedBox(fit: BoxFit.scaleDown,child: const Text('Login With Github Account',maxLines: 1,textAlign: TextAlign.center,overflow: TextOverflow.fade,style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0, color: Colors.white),),);} } 復制代碼

    經過這番改進,當其他開發者閱讀您的代碼時,也能減少很多不必要的煩惱。

    寫在最后

    在運用《Effective Dart》中的注釋技巧進行文檔注釋時,會有一種在寫博客的感覺,因為寫博客的好處之一便是備忘,將來再復習的時候能夠更加快速的理解知識點,注釋也是這樣。

    我認為即使是再優秀的開發者,如果不寫注釋,時間長了,也會忘記,而且有幸見識過一個Java文件包含了30000+行代碼,還沒有注釋,到現在都沒有人愿意去接手這樣的項目,大家都是程序員,程序員何苦為難程序員呢。

    參考資料:

    Code Complete-自說明代碼

    代碼精進之路-寫好注釋,真的是小菜一碟?

    Effective Dart - 文檔注釋

    ==================== 分割線 ======================

    如果你想了解更多關于MVVM、Flutter、響應式編程方面的知識,歡迎關注我。

    你可以在以下地方找到我:

    簡書:www.jianshu.com/u/117f1cf0c…

    掘金:juejin.im/user/582d60…

    Github: github.com/ditclear

    轉載于:https://juejin.im/post/5caf37a1e51d456e5e035ef0

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的Effective Dart 文档注释在Flutter项目中的实践的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。