發表文章

[Program Note] MVC Architectural Pattern簡介

圖片
MVC在軟體工程中是個常見的詞彙,它所代表的是一種 架構模式(architectural pattern) ,例如Repository、Layered、Client-Server、Pipe & Filter都是一些常見的架構模式,架構模式是一種概念,用於解釋與描述軟體架構的一些必要的膠合元素(cohesive elements)。 MVC模式通常用於開發使用者介面的應用程式,由資訊呈現給使用者與從使用者接受的方式,來區分資訊在軟體內部的表達方式;MVC架構的目的是在於實現動態程式設計,降低後續對程式的修改、擴充的難度,簡化程式的架構,並且提升程式的重用性。 在MVC架構中軟體系統分為三個部分,模型(model)、視圖(view)、控制器(controller);然而如同前面所說的, MVC是一個概念,並不是一個模型或者標準,這使得許多框架在實作自己的MVC架構時,對於三者所負責的功能或多或少有些許不同 (其中個議題引起相當大的迴響,模型與視圖之間到底會不會互動,有興趣可以參考— MVC是一個巨大誤會 );撇開三者間太細節的定義,大致上可以區分三者的功能為: 控制器(controller): 介於模型與視圖之間,負責處理整個應用程式的流程控制。 模型(model): 負責資料的處理,例如資料庫的存取、資料的驗證與稽核等。 視圖(view): 提供使用者視覺化的介面,接收使用者的輸入或回覆應用程式的結果。 上圖是我認為比較客觀的MVC架構的流程圖;視圖會接收來自使用者透過介面所給的輸入,視圖會將這些輸入資料給控制器,控制器會將資料轉交給合適的模型,模型將資料處理完後所得的資訊傳給控制器,控制器會把資訊給合適的視圖呈現給使用者。 最後仍然必須再次強調,MVC是一個概念而不是標準,不同的語言、不同的框架在實作MVC模式時都會有不一樣的地方;重點在於如何實現動態程式設計,提升應用程式的擴充性與重用性,並降低其複雜度。

[Program Note] MQTT QoS(Quality of Service)說明

圖片
MQTT的全名為Message Queuing Telemetry Transport,為IBM和Eurotech共同製定的通訊協定,MQTT是為物聯網所設計的M2M通訊協定,網路頻寬與硬體需求非常少,是極為輕便的通訊協定。MQTT通訊協定是基於TCP/IP連線,並提供自有的不同QoS(Quality of Service)層級的訊息傳遞,適用於網路連線不佳的環境、CPU較弱的嵌入式裝置。 MQTT的封包分為三個部分,分別為Fix Header, Variable Header, Payload,在PUBLISH與SUBSCRIBE封包中,QoS會在Fix Header中定義;對於MQTT封包的詳細內容可以參考MQTT官方文件第二章:MQTT Control Packet format。 QoS定義訊息傳送的品質,確保發布的訊息有被確實接收,MQTT定義的QoS分為0、1、2三個等級,在程式撰寫時會在Publisher發送訊息與Subscriber發起訂閱時指定各自的QoS等級: 0:At most once 訊息最多傳送一次,不會確認訊息傳送的結果,不會儲存訊息;如果Subscriber已中斷連線,或如果Broker故障,則該訊息就會會遺失。 在下圖中,Publisher並不能確認Broker是否有收到訊息,同樣的Broker也不能確定Subscriber是否有收到訊息。 1:At least once 一律會傳送訊息至少一次,如果傳送端未接收到確認通知,則會再次傳送訊息並設定DUP(duplicate)旗標,直到接收到確認通知為止。 如下圖,Publisher會在封包Header中加入packet identifier識別碼,訊息發送給Broker之後,Broker會回傳PUBACK(publish acknowledgment) 封包給Publisher,其中也有相同的packet identifier識別碼,讓Publisher確認訊息已經確實送達;同樣的方式也作用在Broker與Subscriber之間。 接收端在處理訊息之後,會從接收端中刪除訊息。如果接收端是Broker,則會將訊息發佈至其Subscriber。如果接收端是Subscriber,則會將訊息遞送至其應用程式。刪除訊息之後,接收端會傳送確認通知至傳送端。 ...

[Program Note] Asynchronous Programing與Callback Function

圖片
Asynchronous Programing 一開始要先清楚何謂同步與非同步,同步比較簡單,就像是我們去銀行辦事情,你填好單子交給行員,之後你必須在行員的櫃台一直等他完成作業,無論是開戶、領款、或者存款,這樣就是同步作業;你的程式送出request之後必須一直等待到response,才可以做其他事情。 而非同步作業時常與多執行緒作業畫上等號,實際上是不同的,多執行緒就像是有六十個人要在銀行開戶,所以銀行開了10個櫃台來處理這60個作業,但是每個櫃台實際上還是執行著上面說的同步作業。 而非同步作業是你今天要開戶,填好單子給行員之後,你可以去隔壁買飲料,點完飲料你可以去隔壁買衣服,店員幫你包裝衣服的時候你可以去7-11繳個電話費,然後飲料店叫到你的號碼了你回去拿飲料,服飾店員說你的衣服包好了你回去拿衣服,最後回到銀行剛好叫到你的號碼再去櫃檯拿你的存摺;對於程式而言, 你的程式送出request之後,到收到response之間,程式可以去做其他事情。 當瞭解同步與非同步作業之後,會延伸一個問題,你要對誰送出的request跟誰會送給你response?對於這個程式角色他必須有一個特性,它必須一直都存在,當你送出一個request之後,它會接收、處理,然後回覆給你一個response,當你再次送出一個request的時候,它也會重複同樣的程序,就像一個等待你的request的迴圈一樣;這樣的設計模式(Design Pattern)有個名字叫反應堆模式(Reactor Pattern),或者叫事件迴圈(Event Loop)、 Select迴圈(Select Loop) 。 下面這張圖就說明了反應堆迴圈的執行方式-等待事件、處理事件的無限迴圈;這個反應堆在程式執行期間會一直存在著,你給他一個request,就是一個event,它會處理完,給你response,然後繼續安靜的等待下一個request。 Callback Function 接著說明一下callback function,在一般的程式中,你寫了一個function,然後你在程式碼中呼叫這個function,我們可以稱為「call」一個function;如果你寫了一個function,然後把這個function的指給了某一個套件、框架、或者其他的程式,這個function在合適的時間,會由這些套...

[Twisted] Part 22: The End

圖片
本文由Dave的 Part 22: The End 翻譯而成,你可以由 Part 1 開始閱讀這個系列的文章,也可以在 這裡 找到整個系列的目錄。 All Done 呼!感謝你支持我。當我開始這個系列時,我沒有想過這會這麼長,或者花費這麼多時間來製作。但我很享受創造這個系列的過程,也希望你享受閱讀它的過程。 現在我已經完成了,我會研究生成PDF格式的可能性。但是不保證。 最後,我想就如何繼續你的Twisted學習提出一些建議。 Further Reading 首先,我建議閱讀Twsited的 線上文件 。雖然它受到很多中傷,但我認為這比經常受到讚賞好。 如果你想使用Twisted進行網路程式設計,那麼Jean-Paul Calderone有一個備受推崇的系列,叫做「 Twisted Web in 60 Seconds 」。不過,我懷疑它會花比60秒更長的時間去閱讀。 還有一本 Twisted的書 ,由於我沒有讀過所以我不能談論太多。 但我認為比上面更重要的是閱讀Twisted的原始碼。由於那些程式碼是由非常了解Twisted的人撰寫的,它是如何以「Twisted方式」做事情的優秀的範例來源。 Suggested Exercises 將你寫過的一個同步程式轉變為使用Twsited。 從頭開始轉寫一個新的Twisted程式。 從Twisted bug資料庫 選擇一個bug然後修復它。向Twisted開發人員提交更新。不要忘記閱讀關於投稿的 程序 。 The End, Really 祝你研究愉快! 圖47.結束

[Twisted] Part 21: Lazy is as Lazy Doesn’t: Twisted and Haskell

圖片
本文由Dave的 Part 21: Lazy is as Lazy Doesn’t: Twisted and Haskell 翻譯而成,你可以由 Part 1 開始閱讀這個系列的文章,也可以在 這裡 找到整個系列的目錄。 Introduction 上個章節中,我們比較了Twisted與 Erlang ,並將注意力集中在它們共同的一些想法上。最後我們也了解使用Erlang非常簡單,因為非同步I/O與回應式程式設計是Erlang runtime與程序模型的關鍵元件。 今天我們將來到離我們的主題更遠的地方來看看 Haskell ,另一種與Erlang(當然,還有Python)完全不同的函式型(functional)語言。這次將不會有太多相似之處,但我們仍然會發現一些非同步I/O隱藏在其中。 Functional with a Capital F 雖然Erlang也是一種函式型語言,它主要關注是可靠的並行性(concurrency)模型。另一方面,Haskell是徹徹底底的函式型,毫不掩飾的使用像 functors 與 monads 這些範疇論( category theory )的概念 不要擔心,我們不會深入範疇論的東西(說得好像我們可以一樣)。相反的,我們將專注於一個Haskell更傳統的函式型功能:懶惰。如同許多函式型語言(但不像Erlang),Haskell支援 惰性求值(lazy evaluation) 。 在惰性求值語言中,程式的內容並沒有很直接地描述如何計算需要計算的東西。實際執行計算的細節通常留給編譯器與runtime系統。 並且,更重要的是當惰性求值的計算進入runtime時,可能只部分(懶惰的)而不是一次性的計算運算式。 通常runtime將只計算讓目前的運算可以有進展所需要的運算式。 這是一個應用haed得簡單的Haskell statement,對於串列[1, 2, 3],這個函式會取回串列中的第一個元素(Haskell與Python共用一些列表語法): head [1,2,3] 如果你安裝的 GHC 這個Haskell runtime,你可以自己嘗試看看: [~] ghci GHCi, version 6.12.1: http://www.haskell.org/ghc/ : ? for help Loading p...

[Twisted] Part 20: Wheels within Wheels: Twisted and Erlang

圖片
本文由Dave的 Part 20: Wheels within Wheels: Twisted and Erlang 翻譯而成,你可以由 Part 1 開始閱讀這個系列的文章,也可以在 這裡 找到整個系列的目錄。 Introduction 在這個系列中我們發現一件事情,將同步的「普通Python」程式碼與非同步的Twisted程式碼混用並不是一項簡單的任務,因為在Twisted程式中阻塞一段不確定的時間將使你喪失嘗試使用非同步模型的許多好處。 如果這是你的第一的非同步程式設計的介紹,那麼你得到的知識似乎有些應用的侷限。你可以在Twisted中使用這些新技術,但是不能在一般Python程式碼的更廣闊的世界中使用。當使用Twisted時,你通常受限於特別寫來作為Twisted程式的一部分使用的函式庫,至少如果你想直接的從執行reactor的執行緒中呼叫它們的話。 但是非同步程式設計的技術已經存在很長的時間,而且絲毫不侷限於Twisted。事實上,光Python中就有數量驚人的非同步程式設計框架。稍微 搜尋一下 可能就有幾十個結果。 它們的細節與Twisted不同,但是基本的想法(非同步I/O、以多個資料串流的小區塊來處理資料)是相同的。 所以如果你需要或選擇去使用其他的框架,你會因為已經學習了Twisted而有很好的啟蒙。 而在Python之外,有許多其他的語言與系統,基於或使用了非同步程式設計的模型。當你在探索這個主題其他更廣泛的領域時,你Twisted的知識將會技術的幫助你。 在這個章節我們會瀏覽一下 Erlang ,它是一種程式語言與runtime system,它廣泛的使用非同步程式設計的概念,但以它獨特的方式實現。請注意這不是對Erlang的概論。相反的,這是對嵌入在Erlang中的一些概念的簡短探索,以及它們如何與Twisted中的概念產生連接。基本的主題是你在學習Twisted中得到的知識可以被應用在學習其他技術時。 Callbacks Reimagined 研究一下 圖6 ,callback的圖形表示。在 Part 6 中介紹的 3.0版本用戶端 與之後所有的詩歌用戶端,主要的callback都是 dataReceived 方法。每次我們從其中一台我們已經連接的詩歌伺服器取得一部分詩歌時,這個callback就會被調用。 假設...

[Twisted] Part 19: I Thought I Wanted It But I Changed My Mind

圖片
本文由Dave的 Part 19: I Thought I Wanted It But I Changed My Mind 翻譯而成,你可以由 Part 1 開始閱讀這個系列的文章,也可以在 這裡 找到整個系列的目錄。 Introduction Twisted是一個進行中的專案,Twisted的開發人員會定期的加入新的功能並擴展舊的功能。隨著Twisted 10.1.0的發布,開發人員為Deferred類別加入了一個新的能力-取消(cancellation),我們今天會來探討這個能力。 非同步程式設計將請求從回應中脫離,因而提升了一種新的可能性:在請求結果與取回結果之間,你可能決定你不再需要它了。想一想 Part 14 的詩歌代理伺服器。以下是代理伺服器的運作方式,至少第一次詩歌請求是這樣子: 來了一個詩歌的請求。 代理伺服器聯絡真的伺服器來取得詩歌。 一但詩歌下載完成,將它傳送給原來的用戶端。 這樣看起來都很好,但是如果用戶端在收到詩歌前中止了怎麼辦?也許它們一開始請求 Paradise Lost 的完整文本,後來決定它們真的想要的是 Kojo 的俳句。現在我們的代理伺服器正卡在下載前者,而慢速伺服器還需要一點時間。我們最好關閉這個連接,並且讓慢速伺服器回去睡覺。 回憶一下 圖15 ,那張顯示同步程式控制的概念流程的圖。在那張圖中我們看到函式呼叫是由上而下,而例外是由下而上返回。如果我們想要取消同步函式的呼叫(而這只是假設),流程控制會與函式呼叫的方向相同,像圖38從高層程式碼到底層程式碼: 圖38.有假設性取消的同步程式流程 當然,在同步程式中這是不可能的,因為直到底層程式碼操作完成前,高層程式碼根本不會恢復執行,在這個時間根本沒有東西可以取消。 但是在非同步程式中,高層程式碼在底層程式碼完成前得到控制權,這至少提升了在底層請求完成之前取消它的可能性。 在Twisted程式中,底層請求是由Deferred物件來具體化的,你可以想像它是未完成的非同步操作的「handle」。在deferred實例中訊息的一般流程是向下的,從底層程式碼到高層程式碼,這與同步程式中的回傳訊息流程一致。從Twisted 10.1.0開始,高層程式碼可以向反方向傳送訊息-這樣可以告訴底層程式碼它不在需要底層程式碼的結果了。看看圖39: 圖39.在def...