1

我想實現和單元測試(不一定是TDD)與某個應用協議中使用的TCP服務器進行通信的客戶端應用程序。客戶機/服務器 - 如何從網絡邏輯中分離協議?

我在here (1)here (2)這樣的地方見過,協議代碼應該最好從網絡代碼中分離出來,這樣我可以單獨對每一個進行單元測試。

但是我無法理解我應該如何設計和實現這些部分。

第一個鏈接使用方法HelloMessage()HowdyMessage()討論MyProtocolHandler類。這是否意味着協議處理程序預計會有兩種方法來生成消息並處理響應?我將如何使用它們?還有一件事,每個消息/響應對應該有不同的ProtocolHandler類,或者只有一個類適用於所有消息/響應對?

第二個鏈接說的是ReaderWriter。再次,我不能說我應該如何使用它們。

這兩個只是例子。主要問題是,我怎樣才能從網絡中分離出邏輯並對其進行單元測試?我必須說我還沒有嘗試過任何東西;我習慣於編寫耦合的代碼,不知道從哪裏開始。

回答

1

這些是不同的方法來處理任務。網絡堆棧被設計爲不同的層,其中每個層向上層提供「定義良好」的功能,並且它通過API提供這些功能。

所以,如果你想實現你自己的應用層協議運行在TCP或SSL上(反過來可能會運行在TCP上),你將使用套接字接口。您設計該零件的方式與設計任何應用程序的方式相同。一般來說,你想把你的應用程序邏輯與協議分開,稱之爲邏輯。您的協議A將負責使用套接字(寫入和讀取)向服務器發送消息,從服務器讀取消息,處理超時(例如,期待從未到達服務器的響應時),處理套接字錯誤,消息格式,消息解析等。協議A將隱藏您的應用程序中的所有這些問題。

您的應用程序將只與您的協議提供的API函數處理:像HelloMessage,它會調用該方法和內部,HelloMessage會處理套接字,消息格式等

現在你的協議A可以是僅由一個類或一組類來實現。如果它是一組類,我建議你讓它們成爲同一個包的一部分。

詳細闡述如何實現它,我會建議兩個選項: 1)您有一個Reader和Writer類,它們是套接字的包裝器。然後你的協議類使用這些讀者和作者,你可以測試它,而不必使用一個沒有使用套接字的兒童讀者和作者的網絡。 2)這更復雜一些,你可以有一個通信類,可以接收消息通過消息隊列發送,也可以使用另一個消息隊列發送收到的消息。 Communication類知道如何處理連接或套接字(取決於抽象級別)。它知道如何打開連接,處理超時等。這是一個更好的設計,但太複雜。

我希望這會有所幫助。

+0

這正是我如何實現它,使用一個類。然而,我對這個問題中鏈接文本的理解是,可以從實現API(協議代碼)的代碼中分離使用套接字的代碼(網絡代碼),這樣我就可以測試後者而不必實際上執行網絡。如何做到這一點是我無法理解的。 – Piovezan

+0

@Piovezan,我增加了更多的信息,但你必須努力工作,並提出一個設計。從簡單的事情開始,然後你會開始找出更好的方法來做到這一點。 – rodolk

+0

我會嘗試選項1.在選項2中,消息隊列是指完整的選項,如RabbitMQ或常規Java隊列? – Piovezan