亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        一種基于指令驅(qū)動(dòng)模型的移動(dòng)編程通訊接口的設(shè)計(jì)與實(shí)現(xiàn)

        2020-09-02 06:52:20王樂琪
        關(guān)鍵詞:網(wǎng)絡(luò)接口發(fā)送器接收器

        侯 杰,王 靜,2,王樂琪

        1(上海海洋大學(xué) 信息學(xué)院,上海 201306)2(農(nóng)村農(nóng)業(yè)部漁業(yè)信息重點(diǎn)實(shí)驗(yàn)室,上海 201306)

        E-mail:wangjing@shou.edu.cn

        1 引 言

        隨著智能手機(jī)、平板電腦等移動(dòng)設(shè)備的普及,各類移動(dòng)應(yīng)用的發(fā)展愈加繁榮[1].與此同時(shí),移動(dòng)應(yīng)用的體積越來(lái)越龐大,通過網(wǎng)絡(luò)接口獲取數(shù)據(jù)是移動(dòng)應(yīng)用展示內(nèi)容的主要來(lái)源[2,3],因此移動(dòng)應(yīng)用中的網(wǎng)絡(luò)通訊模塊也變得越來(lái)越重要.由于移動(dòng)應(yīng)用與網(wǎng)絡(luò)接口的交互在移動(dòng)應(yīng)用開發(fā)中具有重要地位,并且在移動(dòng)應(yīng)用程序中,網(wǎng)絡(luò)接口請(qǐng)求的代碼塊非常多而且所在位置比較離散,所以移動(dòng)應(yīng)用和網(wǎng)絡(luò)接口的交互模塊在編寫和調(diào)試上具有較高的復(fù)雜度,影響著移動(dòng)應(yīng)用的開發(fā)效率.

        目前存在很多成熟的框架可用于實(shí)現(xiàn)移動(dòng)應(yīng)用與網(wǎng)絡(luò)接口交互的開發(fā),例如在安卓開發(fā)中可以采用Retrofit請(qǐng)求框架,后臺(tái)則常采用Struts2,SpringMVC等框架[4,5].這些框架對(duì)于移動(dòng)開發(fā)中的網(wǎng)絡(luò)通訊模塊已經(jīng)給出了可行的解決方案.在后臺(tái)服務(wù)器編寫接口,移動(dòng)應(yīng)用程序中編寫請(qǐng)求.對(duì)于每一個(gè)移動(dòng)端的網(wǎng)絡(luò)接口調(diào)用,在服務(wù)器端對(duì)應(yīng)已編寫好的url,實(shí)現(xiàn)對(duì)應(yīng)請(qǐng)求參數(shù)的處理代碼模塊.這種明確的分工使得移動(dòng)應(yīng)用開發(fā)中的接口調(diào)試與協(xié)同開發(fā)變得困難和復(fù)雜.在沒有開發(fā)網(wǎng)絡(luò)接口之前,移動(dòng)端開發(fā)時(shí)的UI顯示只能使用假數(shù)據(jù)填充,之后再改為網(wǎng)絡(luò)接口請(qǐng)求來(lái)的數(shù)據(jù),并調(diào)試接口數(shù)據(jù)的適配問題,其中開發(fā)出錯(cuò)率,以及開發(fā)復(fù)雜度都顯著提高.問題在于服務(wù)器端和移動(dòng)端在開發(fā)模塊實(shí)現(xiàn)隔離的同時(shí)對(duì)交互數(shù)據(jù)也進(jìn)行了隔離,因而難以實(shí)現(xiàn)協(xié)同開發(fā).因而,涉及網(wǎng)絡(luò)請(qǐng)求的移動(dòng)應(yīng)用開發(fā)不能僅考慮移動(dòng)端,如何讓移動(dòng)端和服務(wù)器端相輔相成,配合恰當(dāng),在簡(jiǎn)化移動(dòng)端的同時(shí)可以讓服務(wù)器端也方便的開發(fā)接口,實(shí)現(xiàn)協(xié)同開發(fā),從而降低開發(fā)復(fù)雜度,讓移動(dòng)端和服務(wù)器端具有數(shù)據(jù)一致性的同時(shí)也具有模塊隔離性,是目前移動(dòng)應(yīng)用中網(wǎng)絡(luò)通訊模塊設(shè)計(jì)與開發(fā)面臨的主要問題.

        本文采用面向?qū)ο笏枷雽?duì)移動(dòng)編程通訊接口設(shè)計(jì),在服務(wù)器端引入指令驅(qū)動(dòng)模型,通過JSON格式的請(qǐng)求指令實(shí)現(xiàn)請(qǐng)求數(shù)據(jù)和返回?cái)?shù)據(jù)端到端的處理,使移動(dòng)端與服務(wù)器端具備數(shù)據(jù)一致性,從而提高移動(dòng)端與服務(wù)器端的協(xié)同開發(fā)效率,并且提高了應(yīng)用程序的可擴(kuò)展性和測(cè)試效率.進(jìn)一步基于此架構(gòu),以Android 應(yīng)用為例介紹具體開發(fā)過程和效果.

        2 基于指令驅(qū)動(dòng)模型的移動(dòng)應(yīng)用通訊接口設(shè)計(jì)

        2.1 通用開發(fā)模式

        移動(dòng)應(yīng)用網(wǎng)絡(luò)接口開發(fā)是典型的前后端分離式的開發(fā),移動(dòng)應(yīng)用想要訪問服務(wù)器資源,需要通過HTTP協(xié)議向指定的服務(wù)器傳遞信息,服務(wù)器根據(jù)應(yīng)用請(qǐng)求調(diào)用相應(yīng)的接口,并返回相應(yīng)的結(jié)果.整個(gè)流程所涉及的操作為移動(dòng)端定義請(qǐng)求接口方法,創(chuàng)造請(qǐng)求數(shù)據(jù),填充URL和數(shù)據(jù),向服務(wù)器發(fā)送請(qǐng)求,服務(wù)器調(diào)用指定URL的網(wǎng)絡(luò)接口處理請(qǐng)求,返回請(qǐng)求結(jié)果,移動(dòng)端根據(jù)請(qǐng)求結(jié)果刷新UI.移動(dòng)應(yīng)用網(wǎng)絡(luò)接口的通用設(shè)計(jì)模式如圖1所示.

        圖1 通用設(shè)計(jì)示意圖Fig.1 General design diagram

        在這種設(shè)計(jì)模式下,移動(dòng)端與服務(wù)器端交互時(shí)傳遞的數(shù)據(jù)較為復(fù)雜,并且特定URL的請(qǐng)求數(shù)據(jù)和返回?cái)?shù)據(jù)必須事先約定.然而,請(qǐng)求數(shù)據(jù)和URL之間卻沒有明確的聯(lián)系,如果在發(fā)送請(qǐng)求時(shí)攜帶了錯(cuò)誤的請(qǐng)求數(shù)據(jù),移動(dòng)端將不能接受到正常的返回結(jié)果.本模式中存在的另一個(gè)問題是接口對(duì)請(qǐng)求數(shù)據(jù)的邏輯處理耦合在接口之中,即使是使用MVC架構(gòu)將邏輯處理模塊獨(dú)立起來(lái),邏輯處理模塊所處理的數(shù)據(jù)仍然需要通過上層數(shù)據(jù)接收層傳遞給它,并沒有把網(wǎng)絡(luò)請(qǐng)求的發(fā)送與接收完全屏蔽,無(wú)法真正實(shí)現(xiàn)移動(dòng)端像調(diào)用函數(shù)一樣調(diào)用接口,無(wú)法達(dá)到移動(dòng)端與服務(wù)器端數(shù)據(jù)的一致性.因而,本文提出基于指令驅(qū)動(dòng)模型對(duì)移動(dòng)應(yīng)用通訊接口的整個(gè)架構(gòu)進(jìn)行優(yōu)化,確保請(qǐng)求數(shù)據(jù)與URL之間具有明確的聯(lián)系,而且能夠?qū)崿F(xiàn)數(shù)據(jù)傳輸與數(shù)據(jù)處理的隔離.

        2.2 框架整體設(shè)計(jì)

        本文提出的編程架構(gòu)共分為四個(gè)模塊,構(gòu)造請(qǐng)求指令,指令發(fā)送器,指令接收器,指令驅(qū)動(dòng)模型,其中構(gòu)造請(qǐng)求指令和指令驅(qū)動(dòng)模型是一組,指令發(fā)送器和指令接收器是一組.整個(gè)流程如圖2所示.

        圖2 整體架構(gòu)設(shè)計(jì)Fig.2 Overall architecture design

        圖2中:

        標(biāo)注1,2,3:將需要發(fā)送給服務(wù)器的數(shù)據(jù)構(gòu)造為指令

        標(biāo)注4,5,6:將服務(wù)器返回的數(shù)據(jù)用于刷新UI界面

        標(biāo)注7,8:客戶端與服務(wù)器之間傳遞指令和返回的數(shù)據(jù)

        標(biāo)注9,10:將指令送給指令驅(qū)動(dòng)模型處理,得到返回值

        標(biāo)注11,12:服務(wù)器端與數(shù)據(jù)庫(kù)交互部分

        移動(dòng)應(yīng)用要訪問服務(wù)器,需要通過HTTP協(xié)議向服務(wù)器發(fā)送信息,由于JSON格式[6,7]在傳輸效率上優(yōu)于其它數(shù)據(jù)傳輸格式,因此本文在設(shè)計(jì)接口架構(gòu)時(shí),使用JSON數(shù)據(jù)格式來(lái)傳遞信息.網(wǎng)絡(luò)接口通過URL來(lái)訪問,URL可以視為一個(gè)導(dǎo)向,移動(dòng)端在請(qǐng)求URL時(shí)需要攜帶相應(yīng)的請(qǐng)求數(shù)據(jù),通常一個(gè)URL對(duì)應(yīng)著固定的請(qǐng)求數(shù)據(jù)和返回?cái)?shù)據(jù).由于URL與傳輸數(shù)據(jù)具有這種強(qiáng)關(guān)聯(lián)的關(guān)系,本文把URL視為操作碼,將URL與傳輸數(shù)據(jù)抽象為一個(gè)整體,即指令,把指令視為網(wǎng)絡(luò)請(qǐng)求傳輸?shù)幕緮?shù)據(jù)單位,指令包含了URL和傳輸數(shù)據(jù)所表達(dá)的信息.

        在移動(dòng)端構(gòu)造請(qǐng)求指令后,通過指令發(fā)送器發(fā)送到服務(wù)器,服務(wù)器通過指令解析器解析出具體的指令,并把指令交給指令驅(qū)動(dòng)模型處理,得到指令驅(qū)動(dòng)模型的返回結(jié)果并返回給移動(dòng)端.其中指令發(fā)送和指令解析是網(wǎng)絡(luò)數(shù)據(jù)傳輸過程,它們的任務(wù)就是傳遞指令,而與具體的URL和請(qǐng)求數(shù)據(jù)無(wú)關(guān),這樣可以屏蔽掉網(wǎng)絡(luò)傳輸過程,讓程序的編寫和調(diào)試更加方便,也方便將請(qǐng)求接口函數(shù)化.指令驅(qū)動(dòng)模型是服務(wù)器端與網(wǎng)絡(luò)傳輸無(wú)關(guān)的運(yùn)行單元,在移動(dòng)端構(gòu)造的請(qǐng)求指令是可以直接用于對(duì)應(yīng)指令驅(qū)動(dòng)模型的,這就滿足了數(shù)據(jù)一致性,讓移動(dòng)應(yīng)用調(diào)用接口如同調(diào)用本地函數(shù),這給程序的調(diào)試帶來(lái)了極大的便利.在這種模式下,當(dāng)需要修改功能或者是添加新功能時(shí),只需要修改指令驅(qū)動(dòng)模型就可以完成,極大的提高了程序的可擴(kuò)展性.

        2.3 指令驅(qū)動(dòng)模型和構(gòu)造請(qǐng)求指令的設(shè)計(jì)

        在整個(gè)網(wǎng)絡(luò)接口架構(gòu)中,指令驅(qū)動(dòng)模型和構(gòu)造請(qǐng)求指令是一套完整的體系,獨(dú)立在網(wǎng)絡(luò)傳輸之外,如果部署到同一臺(tái)設(shè)備仍然可以執(zhí)行,構(gòu)造的請(qǐng)求指令就是要投入指令驅(qū)動(dòng)模型中來(lái)得到返回結(jié)果,本文采用面向?qū)ο蟮乃枷雽?duì)其進(jìn)行設(shè)計(jì).

        在大多數(shù)需要與數(shù)據(jù)庫(kù)交互的程序中,基本上都是把數(shù)據(jù)庫(kù)的每張表看作一個(gè)類,表里的每一行看為一個(gè)對(duì)象,正是由于這種面向?qū)ο蟮乃枷?,在程序與數(shù)據(jù)庫(kù)交互方面誕生了不少優(yōu)秀的框架[8,9].而移動(dòng)應(yīng)用向服務(wù)器發(fā)送請(qǐng)求,最終也是對(duì)服務(wù)器數(shù)據(jù)庫(kù)進(jìn)行一定的操作,這些操作是面向數(shù)據(jù)庫(kù)表的抽象數(shù)據(jù)類型的,因此移動(dòng)應(yīng)用的網(wǎng)絡(luò)請(qǐng)求可以根據(jù)具體操作的抽象數(shù)據(jù)類型來(lái)劃分,所以指令的操作碼部分應(yīng)該包含類和對(duì)類的操作,指令的數(shù)據(jù)部分可能有很多參數(shù),為了更好的組織代碼,提高代碼質(zhì)量,對(duì)于操作碼中的每個(gè)操作,指令中都需要有對(duì)應(yīng)所有參數(shù)的抽象數(shù)據(jù)類型.指令結(jié)構(gòu)如圖3所示.事實(shí)上,對(duì)一個(gè)類的操作并不會(huì)很多,而且可能只是增刪改查,所以很多指令的操作數(shù)部分只需要類本身對(duì)象就足夠了.如果嚴(yán)格按照每個(gè)操作對(duì)應(yīng)的參數(shù)創(chuàng)建抽象參數(shù)對(duì)象,在移動(dòng)端編程時(shí)填充指令對(duì)象就會(huì)方便很多,且不易出錯(cuò),這在一定程度上可以提高開發(fā)效率,提高系統(tǒng)可擴(kuò)展性.

        圖3 本文提出的指令格式Fig.3 Instruction format proposed in this paper

        指令驅(qū)動(dòng)模型是從面向?qū)ο蟮乃枷氤霭l(fā),它需要實(shí)現(xiàn)的功能是能夠執(zhí)行相應(yīng)的指令,返回執(zhí)行結(jié)果.所謂指令驅(qū)動(dòng),就是模型內(nèi)部的執(zhí)行過程是靠指令來(lái)驅(qū)動(dòng)的.指令驅(qū)動(dòng)模型是處理請(qǐng)求指令的核心,所以模型在使用時(shí)應(yīng)該具有良好的可擴(kuò)展性,在設(shè)計(jì)指令驅(qū)動(dòng)模型時(shí)需要充分考慮到程序是否具有低耦合高內(nèi)聚的特性.

        本文提出的指令驅(qū)動(dòng)模型具有處理請(qǐng)求指令的功能,而對(duì)請(qǐng)求指令的處理是通過指令的操作碼實(shí)現(xiàn)對(duì)指令操作數(shù)的處理.由于設(shè)計(jì)指令時(shí),指令能夠通過指令要操作的類進(jìn)行劃分,指令驅(qū)動(dòng)模型就可以根據(jù)這一特點(diǎn),分析指令的操作碼然后把指令交到具體類的操作對(duì)象,由具體的操作對(duì)象對(duì)指令的操作數(shù)處理并返回處理結(jié)果.所以用于處理操作數(shù)的對(duì)象也會(huì)由類來(lái)劃分,這樣就會(huì)保證程序的可擴(kuò)展性.當(dāng)然,具體類的操作對(duì)象需要注冊(cè)到指令驅(qū)動(dòng)模型中,以保證指令驅(qū)動(dòng)模型在收到指令后可以正常運(yùn)作.

        因此,在驅(qū)動(dòng)模型中需要一個(gè)具體操作對(duì)象的管理器來(lái)管理這些對(duì)象,在收到指令后可以分發(fā)給具體的操作對(duì)象去處理.由于指令是有格式的,具體的操作對(duì)象也具備一定的格式才能正常處理對(duì)應(yīng)的指令.因此不是任何一個(gè)對(duì)象都可以通過指令驅(qū)動(dòng)模型處理,也不是任何一個(gè)對(duì)象都可以注冊(cè)到指令驅(qū)動(dòng)模型中作為具體操作對(duì)象.因此,本驅(qū)動(dòng)模型中還具備一個(gè)分析器,不僅可以實(shí)現(xiàn)注冊(cè)操作對(duì)象時(shí)對(duì)操作對(duì)象的分析,而且能夠完成模型執(zhí)行指令時(shí)對(duì)指令的分析,從而保證模型的健壯性.另外,本模型具備異常處理模塊,因開發(fā)時(shí)因?yàn)殄e(cuò)誤的使用模型而使程序不正常運(yùn)行,能夠報(bào)出異常,并可以提示異常原因,從而提高開發(fā)效率.

        在使用指令驅(qū)動(dòng)模型編程時(shí),只需要編寫不同類別的具體操作對(duì)象然后注冊(cè)到模型中.當(dāng)然,操作對(duì)象必須可以處理相應(yīng)指令,而指令和操作對(duì)象的關(guān)系就如函數(shù)的形參與函數(shù)的關(guān)系.因而,在本文設(shè)計(jì)的框架下,指令處理后的返回結(jié)果是任意的.如果把操作對(duì)象類比于函數(shù),這里的返回結(jié)果任意性不是說(shuō)函數(shù)的返回值不需要定義,而是可以將返回值定義為任何類型,也即是對(duì)于同一個(gè)操作碼,操作對(duì)象可以把返回值定義任何類型,在將結(jié)果返回時(shí)都可以正常接收返回?cái)?shù)據(jù).這是由于,如果調(diào)用者需要調(diào)用模型處理一條指令,在調(diào)用模型之前它是知道需要的返回結(jié)果類型的.操作對(duì)象返回結(jié)果的任意性可以提高工作效率,簡(jiǎn)化代碼,減少不必要的前后臺(tái)數(shù)據(jù)協(xié)商.

        2.4 網(wǎng)絡(luò)數(shù)據(jù)傳輸設(shè)計(jì)

        在網(wǎng)絡(luò)數(shù)據(jù)傳輸中,本文所設(shè)計(jì)的指令發(fā)送器和指令接收器只需要完成指令的前后臺(tái)傳遞,具有傳輸JSON數(shù)據(jù)的功能.

        圖4 網(wǎng)絡(luò)數(shù)據(jù)傳輸流程Fig.4 Transmission process of network data

        在移動(dòng)應(yīng)用工程中,出于網(wǎng)絡(luò)通訊安全性的考慮,往往需要對(duì)指令進(jìn)行加密,而且操作數(shù)具有不同的特性,如圖片資源和普通參數(shù),因此需要對(duì)指令進(jìn)行分類,此分類不同于將指令按操作碼的類別劃分,前者相當(dāng)于指令的標(biāo)簽,后者是指令中操作碼具有的性質(zhì).因此本研究在設(shè)計(jì)網(wǎng)絡(luò)數(shù)據(jù)傳輸時(shí),需要指令發(fā)送器可以區(qū)分指令的標(biāo)簽,根據(jù)指令的標(biāo)簽信息對(duì)指令進(jìn)行相應(yīng)的操作,在向服務(wù)器發(fā)送指令時(shí),攜帶著指令的標(biāo)簽信息,構(gòu)造擴(kuò)展指令,方便服務(wù)器對(duì)指令的正確解析.依據(jù)擴(kuò)展指令可以完成指令的發(fā)送和接收,然而在返回?cái)?shù)據(jù)的傳輸方面,就會(huì)略顯復(fù)雜,由于一條指令的返回結(jié)果具有任意性,這就給返回?cái)?shù)據(jù)的接收帶來(lái)了挑戰(zhàn),為了方便返回?cái)?shù)據(jù)的接收和解析,可以對(duì)指令好返回?cái)?shù)據(jù)統(tǒng)一化處理,都采用擴(kuò)展指令的形式封裝.事實(shí)上,指令和返回?cái)?shù)據(jù)都是一種抽象數(shù)據(jù)類型,因此可以統(tǒng)一化處理,使用統(tǒng)一的擴(kuò)展指令來(lái)傳遞,使網(wǎng)絡(luò)數(shù)據(jù)傳輸過程仍然具備前后端分離的特性.擴(kuò)展指令由附加信息和指令/返回?cái)?shù)據(jù)構(gòu)成.

        本文設(shè)計(jì)網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)牧鞒虨橹噶畎l(fā)送器分析指令標(biāo)簽,生成擴(kuò)展指令發(fā)送到指令接收器,指令接收器解析出指令并傳遞到指令驅(qū)動(dòng)模型,指令接收器拿到對(duì)應(yīng)指令返回?cái)?shù)據(jù)后生成擴(kuò)展指令返回給指令發(fā)送器,指令發(fā)送器解析出返回?cái)?shù)據(jù).統(tǒng)一化處理指令和返回?cái)?shù)據(jù),屏蔽了網(wǎng)絡(luò)傳輸過程,提高了開發(fā)效率和程序的可擴(kuò)展性,并且給程序的調(diào)試帶來(lái)了便利.網(wǎng)絡(luò)數(shù)據(jù)傳輸流程如圖4所示.

        3 基于指令驅(qū)動(dòng)模型的移動(dòng)應(yīng)用通訊接口框架實(shí)現(xiàn)

        Java是一個(gè)廣泛使用的面向?qū)ο蟮木W(wǎng)絡(luò)編程語(yǔ)言,其具有良好的可移植性,跨平臺(tái)性,安全性,被廣泛應(yīng)用在各種場(chǎng)景的程序開發(fā)[10],本文使用Java編程語(yǔ)言面向Android應(yīng)用實(shí)現(xiàn)基于指令驅(qū)動(dòng)模型的移動(dòng)應(yīng)用通訊接口架構(gòu).

        3.1 指令驅(qū)動(dòng)模型的實(shí)現(xiàn)

        指令驅(qū)動(dòng)模型是本文設(shè)計(jì)架構(gòu)的基礎(chǔ)功能模塊,因此在實(shí)現(xiàn)架構(gòu)前需要先實(shí)現(xiàn)指令驅(qū)動(dòng)模型.指令驅(qū)動(dòng)模型模塊需要實(shí)現(xiàn)的是指令的實(shí)現(xiàn)和驅(qū)動(dòng)模型的實(shí)現(xiàn).指令包含操作碼和操作數(shù),操作碼可以根據(jù)要操作的實(shí)體類進(jìn)行劃分,故把操作碼設(shè)計(jì)為“實(shí)體類.具體操作”,對(duì)同一個(gè)實(shí)體類操作的指令使用同一個(gè)指令類.在用Java實(shí)現(xiàn)時(shí),對(duì)于每一個(gè)實(shí)體類都編寫一個(gè)對(duì)應(yīng)的指令類并統(tǒng)一命名規(guī)范,指令類命名為“要操作實(shí)體類加后綴Come”,操作碼字段使用request.操作對(duì)象要對(duì)指令對(duì)象操作,需要有對(duì)應(yīng)指令對(duì)象的屬性,把操作對(duì)象統(tǒng)一命名“實(shí)體類+Actor”.

        指令驅(qū)動(dòng)模型可以根據(jù)指令對(duì)象的request的實(shí)體類標(biāo)識(shí)找到具體的操作對(duì)象,根據(jù)request的具體操作標(biāo)識(shí)找到具體的操作方法,進(jìn)而處理指令和返回結(jié)果.request字段與操作對(duì)象其中的方法存在映射關(guān)系,如圖5所示.驅(qū)動(dòng)模型根據(jù)映射關(guān)系正確的處理指令,可以使用Java編程語(yǔ)言的高級(jí)特性-注解[11,12]和反射編程.通過在Actor類中添加相應(yīng)的注解說(shuō)明Come和Actor之間的映射關(guān)系.

        圖5 Come指令和Actor的映射關(guān)系Fig.5 Mapping relationship between come instruction and actor

        通過定義注解(@Come,@Actor,@Action)然后使用在Actor類中,就可以通過類似與user.register來(lái)定位到UserActor中的register方法.當(dāng)然UserActor需要提前注冊(cè)到驅(qū)動(dòng)模型中.

        定義指令驅(qū)動(dòng)模型的控制器為Context類,實(shí)現(xiàn)為單例模式,Context類的方法應(yīng)該有addActor():向Context注冊(cè)Actor類,getComeClass():通過Come對(duì)象的類名獲取類的字節(jié)碼對(duì)象,這個(gè)方法主要是和利用JSON解析指令相關(guān),showWorks():此方法用于顯示出注冊(cè)到Context中的Actor類的所有指令到處理方法的映射路線,back(Come),此方法用于對(duì)接收Come對(duì)象并產(chǎn)生返回結(jié)果.

        分析器作用是分析Come對(duì)象中request字段是否符合規(guī)范,以及注冊(cè)到Context的Actor類是否符合規(guī)范.如果不符合規(guī)范,交由異常處理模塊進(jìn)行相應(yīng)處理.操作對(duì)象管理器負(fù)責(zé)實(shí)例化Actor對(duì)象,并將收到的Come指令填充其中的Come屬性,根據(jù)Come指令的request字段調(diào)用@Action對(duì)應(yīng)的方法,如果Actor對(duì)象中含有該方法返回值類型的引用,調(diào)用方法前會(huì)把返回值的引用實(shí)例化.

        每個(gè)操作碼對(duì)應(yīng)這一種返回?cái)?shù)據(jù)類型,但是開發(fā)人員在使用驅(qū)動(dòng)模型時(shí)是不希望總是寫強(qiáng)制類型轉(zhuǎn)化的,因此在實(shí)現(xiàn)Context的back()方法時(shí),通過利用Java的泛型編程消除強(qiáng)制類型轉(zhuǎn)化步驟.

        測(cè)試指令驅(qū)動(dòng)模型:

        public class TestCome {

        private String request;

        }

        @Actor(name = “user”)

        public class TestActor {

        @Come

        TestCome come;

        TestBack testBack;

        @Action(name = “test”)

        TestBack getBack(){

        testBack.setData(“Hello World!”);

        return testBack;

        }

        @Action(name = “testList”)

        List getList(){

        List list=new ArrayList();

        return list;

        }

        }

        //注冊(cè)TestActor

        Context context=Context.getContext();

        context.addActor(TestActor.class);

        context.showWorks();

        TestCome comeData=new TestCome();

        //測(cè)試返回TestBack類型

        comeData.setRequest(“user.test”);

        TestBack backData=context.back(comeData);

        //測(cè)試返回list類型

        comeData.setRequest(“user.testList”);

        List string1=context.back(comeData);

        3.2 網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)膶?shí)現(xiàn)

        在實(shí)現(xiàn)指令和返回?cái)?shù)據(jù)的傳遞方面,擴(kuò)展指令的定義非常重要,擴(kuò)展指令包含附加信息和指令/返回?cái)?shù)據(jù),附加信息很少,只需要定義幾個(gè)字段即可,但是不同的指令和數(shù)據(jù)具有不同的數(shù)據(jù)類型,如果在擴(kuò)展指令類中一一定義,會(huì)使擴(kuò)展指令對(duì)象變的極為復(fù)雜,而且影響程序的可擴(kuò)展性.所以本文實(shí)現(xiàn)的擴(kuò)展指令對(duì)象中的指令或數(shù)據(jù)屬于字符串類型,字段定義為data,用來(lái)存放JSON格式的指令或數(shù)據(jù),這樣就可以對(duì)指令和數(shù)據(jù)進(jìn)行統(tǒng)一化實(shí)現(xiàn).指令接收器接收到擴(kuò)展指令后需要對(duì)指令反序列化,解析成Java對(duì)象,因此在擴(kuò)展指令的附加信息中需要有指令類的類名,指令接收器就可以調(diào)用Context對(duì)象的getComeClass拿到指令的字節(jié)碼,進(jìn)而將其解析為Java對(duì)象.本文把擴(kuò)展指令定義為Body類,字段包括name,data和key,其中name是指令或返回?cái)?shù)據(jù)的類名,data是指令或返回?cái)?shù)據(jù)的JSON格式字符串,key用于請(qǐng)求驗(yàn)證,擴(kuò)展指令的傳遞同樣需要JSON數(shù)據(jù)傳輸格式.

        指令接收器用servlet實(shí)現(xiàn),定義一個(gè)servlet接收J(rèn)SON字符串形式的Body,定義一個(gè)數(shù)據(jù)處理類,用于JSON解析和數(shù)據(jù)加密.指令接收器只負(fù)責(zé)將擴(kuò)展指令Body中的Come通過數(shù)據(jù)處理對(duì)象解析出來(lái),交給指令驅(qū)動(dòng)模型處理,拿到返回?cái)?shù)據(jù)再通過數(shù)據(jù)處理對(duì)象包裝成Body作為返回體.數(shù)據(jù)處理對(duì)象用來(lái)將數(shù)據(jù)對(duì)象化,進(jìn)行token認(rèn)證,數(shù)據(jù)加密和解密處理[13].這種模式下只需要?jiǎng)?chuàng)建一個(gè)servlet即可,具體的指令處理與指令接收隔離開,指令驅(qū)動(dòng)模型與指令接收器是隔離的,可以極大的提高程序的易讀性和可擴(kuò)展性.

        對(duì)于指令發(fā)送器,本文采用Retrofit封裝網(wǎng)絡(luò)請(qǐng)求模塊,讓指令發(fā)送器負(fù)責(zé)將指令封裝為擴(kuò)展指令Body,對(duì)其發(fā)送與接收,采用異步的請(qǐng)求處理方式,使用谷歌的Gson進(jìn)行JSON數(shù)據(jù)解析.在具體請(qǐng)求代碼塊中構(gòu)造請(qǐng)求指令,向指令發(fā)送器傳遞Come對(duì)象并接收返回對(duì)象,并且收到返回?cái)?shù)據(jù)后可以通過doSucces和doFailure方法刷新UI界面.同樣的,指令發(fā)送器也利用數(shù)據(jù)處理對(duì)象將指令轉(zhuǎn)化為Body發(fā)送或者將接收到的Body中的返回?cái)?shù)據(jù)轉(zhuǎn)化為Java對(duì)象,同時(shí)需要根據(jù)Come指令的類別(比如需要加密)對(duì)指令進(jìn)行相應(yīng)的處理.

        圖6 整體架構(gòu)的實(shí)現(xiàn)Fig.6 Implementation of overall architecture

        指令發(fā)送器和指令接收器交互只用Body進(jìn)行,因此指令發(fā)送器只需編寫一個(gè)請(qǐng)求方法,這簡(jiǎn)化了網(wǎng)絡(luò)請(qǐng)求編寫的復(fù)雜度.數(shù)據(jù)處理對(duì)象與指令接收器中的數(shù)據(jù)處理對(duì)象類似,實(shí)現(xiàn)數(shù)據(jù)對(duì)象之間的解析轉(zhuǎn)化,其中將返回Body中的放回?cái)?shù)據(jù)解析成具體對(duì)象是一個(gè)難點(diǎn),因?yàn)橛蒍SON類型字符串解析成Java對(duì)象,需要有Java對(duì)象的字節(jié)碼對(duì)象或者對(duì)象類型,如果接收一個(gè)帶有泛型的Map或者List,運(yùn)行時(shí)泛型就會(huì)被擦除,導(dǎo)致無(wú)法正確解析到想要的對(duì)象,針對(duì)此問題,本文通過Gson的TypeToken獲取具體對(duì)象的Type,Type type = new TypeToken(){}.getType();再進(jìn)行相應(yīng)的解析,但是每個(gè)請(qǐng)求得到的返回類型有差異,為了減少編寫復(fù)雜度,本文采用面向?qū)ο蟮睦^承特性,創(chuàng)建DoBack抽象類繼承Gson的TypeToken,完美的解決了這個(gè)問題.

        調(diào)用請(qǐng)求只需要構(gòu)造Come指令,交給指令發(fā)送器,就可以獲得返回對(duì)象,進(jìn)而進(jìn)行相應(yīng)的處理,處理的方法也是在UI線程中的,可直接刷新界面.這樣一來(lái),就完成了Come指令到返回?cái)?shù)據(jù)端到端的處理過程,提高程序的可讀性和開發(fā)效率.

        3.3 整體框架的實(shí)現(xiàn)

        在定義好擴(kuò)展指令Body類,指令發(fā)送器,指令接收器之后,就在應(yīng)用與服務(wù)器之間生成了一條數(shù)據(jù)傳輸線,在編寫請(qǐng)求時(shí),只需要面向指令驅(qū)動(dòng)模型進(jìn)行編寫.測(cè)試時(shí)在數(shù)據(jù)傳輸線沒有錯(cuò)誤的情況下,只需要對(duì)具體請(qǐng)求塊和指令驅(qū)動(dòng)模型進(jìn)行測(cè)試,具體請(qǐng)求塊的測(cè)試屬于客戶端獨(dú)立的測(cè)試,指令驅(qū)動(dòng)模型屬于服務(wù)器端獨(dú)立的測(cè)試,從而可以提高測(cè)試效率.整體架構(gòu)的實(shí)現(xiàn)如圖6所示.

        3.4 框架實(shí)現(xiàn)具體代碼

        具體請(qǐng)求塊:使用一個(gè)抽象類繼承GSON的TypeToken,使之具有g(shù)etType方法,用于獲取真正的類型.

        public abstract class DoBack extends TypeToken{

        protected DoBack(Object object){

        Api.getApi().go(object,this);

        }

        public abstract void doSuccess(T t);

        public abstract void doFailure();}

        指令發(fā)送器:使用Retrofit框架定義網(wǎng)絡(luò)請(qǐng)求接口傳輸Body的JSON字符串:

        @FormUrlEncoded

        @POST(“ActionService”)

        Call request(@Field(“data”)String body);

        創(chuàng)建Api類定義Retrofit的HttpClient,JSON參數(shù)解析等基本配置,getApi()得到單例對(duì)象Api,go(object,this)是請(qǐng)求方法,object是Come對(duì)象,用DoBack本身作為參數(shù),用于準(zhǔn)確接收想要的返回類型,配備返回?cái)?shù)據(jù)的處理方法.go方法定義如下:

        public void go(final T t,final DoBack doBack){

        String data= BCB.createBodyString(t);

        Call call = getOwnApi().request(data);

        call.enqueue(new Callback(){

        @Override

        public void onResponse(Call call,Response response){

        if(response.body()!= null){

        Object obj=BCB.ComeOrBack(response.body(),doBack.getType());

        if(obj == null)

        doBack.doFailure();

        else

        doBack.doSuccess(obj);

        } else {

        doBack.doFailure();

        }

        }

        @Override

        public void onFailure(Call call,Throwable t){

        doBack.doFailure();

        }

        });}

        BCB是定義的數(shù)據(jù)處理對(duì)象,可以看到傳入doBack的doSuccess()方法的obj是解析好的返回?cái)?shù)據(jù)對(duì)象,因此在具體請(qǐng)求塊就可以直接利用返回?cái)?shù)據(jù)對(duì)象進(jìn)行相應(yīng)的刷新頁(yè)面.

        指令接收器:

        data=req.getParameter(“data”);

        body=BCB.Body(data);

        if(BCB.checkTime(body)==false){

        onDefeat();

        return;

        }

        String result=

        BCB.createBodyString(

        context.back(

        BCB.ComeOrBack(body,context.getComeClass(body.getName()))));

        if(result==null){

        onDefeat();

        return;

        }

        writer.write(result);

        其中context是指令驅(qū)動(dòng)模型的控制器,先調(diào)用getComeClass()得到傳到指令接收器的Come指令對(duì)象的字節(jié)碼文件,調(diào)用BCB解析出Come對(duì)象,調(diào)用context.back()得到返回?cái)?shù)據(jù)對(duì)象,進(jìn)而包裝為Body的JSON字符串返回.

        4 基于Android 應(yīng)用的網(wǎng)絡(luò)接口實(shí)現(xiàn)

        樣例APP實(shí)現(xiàn)user的注冊(cè)登錄,登錄成功顯示新聞列表,數(shù)據(jù)庫(kù)連接使用Hibernate框架,user表字段uid,username,password.news表字段 nid,title,content.IDE使用AS和eclipse.

        定義UserActor和NewsActor,注冊(cè)到指令驅(qū)動(dòng)模型.兩個(gè)Actor面對(duì)的Come都是UserCome,UserCome中只有一個(gè)request字段和一個(gè)User對(duì)象.UserActor對(duì)應(yīng)的指令是user.login和user.register,NewsActor對(duì)應(yīng)的指令是news.getList.編寫APP頁(yè)面并加入具體請(qǐng)求塊,用于注冊(cè)的具體請(qǐng)求塊如下:

        User user=new User();

        user.setUsername(username.getText().toString());

        user.setPassword(password.getText().toString());

        UserCome userCome=new UserCome();

        userCome.setRequest(“user.register”);

        userCome.setUser(user);

        DoBackdoBack=new DoBack(userCome){

        @Override

        public void do Success(String s){

        T;

        }

        @Override

        public void doFailure(){

        F;

        }

        };

        獲取News的具體請(qǐng)求塊如下:

        userCome.setRequest(“news.getList”);

        DoBack> doBack1=new DoBack>(userCome){

        @Override

        public void doSuccess(List news){

        T;

        }

        @Override

        public void doFailure(){

        F;

        }

        };

        登陸模塊與此類似.指令驅(qū)動(dòng)模型編寫在Actor中使用Hibernate進(jìn)行數(shù)據(jù)庫(kù)交互.例如user.register和news.getList如下所示:

        @Actor(name = “user”)

        public class UserActor {

        @Come

        UserCome userCome;

        @Action(name = “register”)

        String register(){

        User user=

        HibernateUtil.getobj(User.class,“username”,

        userCome.getUser().getUsername());

        if(user==null){

        HibernateUtil.save(userCome.getUser());

        return “注冊(cè)成功”;

        }else {

        return “用戶名已存在”;

        }

        }

        }

        @Actor(name = “news”)

        public class NewsActor {

        @Come

        UserCome userCome;

        @Action(name = “getList”)

        List get(){

        List list=

        HibernateUtil.listByHql(“from News”,null);

        return list;

        }

        }

        捏造UserCome對(duì)登錄、注冊(cè)和獲取新聞列表接口測(cè)試,測(cè)試結(jié)果如圖7所示.

        圖7 部分測(cè)試結(jié)果示意圖Fig.7 Illustration of some testing results

        采用本文提出的框架進(jìn)行開發(fā),開發(fā)測(cè)試和擴(kuò)展過程歸約到對(duì)指令驅(qū)動(dòng)模型開發(fā)測(cè)試和擴(kuò)展,屏蔽了網(wǎng)絡(luò)傳輸過程,提高開發(fā)效率.如果采用Retrofit(請(qǐng)求框架)+Struts2或SpringMVC(后臺(tái)框架)搭建應(yīng)用框架,則需要對(duì)每個(gè)請(qǐng)求接口編寫請(qǐng)求方法,在請(qǐng)求時(shí)指向URL并攜帶參數(shù),后臺(tái)編寫對(duì)應(yīng)的Action類或Controller類來(lái)接受參數(shù)并進(jìn)行處理.使用Struts2框架或者SpringMVC框架,前端后臺(tái)是通過網(wǎng)絡(luò)傳輸這一過程進(jìn)行分割,通過URL傳遞參數(shù)進(jìn)行溝通,這無(wú)疑會(huì)使開發(fā)過程脫離不了網(wǎng)絡(luò)傳輸,在編寫調(diào)試方面都會(huì)提高復(fù)雜度.表1給出了各框架在開發(fā)模式、編碼、測(cè)試、維護(hù)與擴(kuò)展進(jìn)行理論上的比較,并總結(jié)了應(yīng)用各框架的開發(fā)復(fù)雜度和各框架的作用.

        表1 各個(gè)框架詳細(xì)對(duì)比Table 1 Comparison with some common frameworks

        在開發(fā)模式上,本文將URL和參數(shù)抽象為指令,結(jié)合指令發(fā)送器和接收器屏蔽了網(wǎng)絡(luò)傳輸過程,使接口的請(qǐng)求僅依賴指令驅(qū)動(dòng)模型,這給編碼測(cè)試和擴(kuò)展提供了便利.

        5 結(jié) 論

        本文提出了基于指令驅(qū)動(dòng)模型對(duì)移動(dòng)編程通信接口設(shè)計(jì),把整個(gè)通信過程分解為構(gòu)造請(qǐng)求指令,指令發(fā)送器,令接收器,指令驅(qū)動(dòng)模型,進(jìn)而產(chǎn)生了指令到網(wǎng)絡(luò)傳輸?shù)街噶铗?qū)動(dòng)模型的開發(fā)框架,通過請(qǐng)求指令化,在保證模塊隔離性的同時(shí)也保證了前后臺(tái)數(shù)據(jù)的一致性,指令驅(qū)動(dòng)模型成為實(shí)際數(shù)據(jù)交互的載體,保證程序的擴(kuò)展性,提高測(cè)試效率.這種架構(gòu)可以屏蔽具體網(wǎng)絡(luò)傳輸,降低數(shù)據(jù)耦合度,簡(jiǎn)化移動(dòng)端和服務(wù)器端的代碼編寫,根據(jù)該架構(gòu)開發(fā)基于Android系統(tǒng)的 APP應(yīng)用并對(duì)比了各個(gè)框架的使用情況,驗(yàn)證了此架構(gòu)的有效性和實(shí)用性.

        在請(qǐng)求指令化后,指令就成為移動(dòng)應(yīng)用請(qǐng)求的基本數(shù)據(jù)單元,移動(dòng)端的請(qǐng)求被抽象為一條條指令的發(fā)送.通常在移動(dòng)應(yīng)用中,一個(gè)界面可能具有很多可能要發(fā)送的指令,而且指令具有一定的邏輯關(guān)系.因此,可以在本文提出的編程架構(gòu)基礎(chǔ)上進(jìn)一步研究指令的對(duì)應(yīng)概念,如指令的順序執(zhí)行,分支結(jié)構(gòu)和循環(huán)結(jié)構(gòu),以適應(yīng)具體開發(fā)場(chǎng)景.

        猜你喜歡
        網(wǎng)絡(luò)接口發(fā)送器接收器
        變電站網(wǎng)絡(luò)接口物理防護(hù)系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)
        移頻發(fā)送器冗余切換設(shè)計(jì)研究
        JXG-50S型相敏軌道電路接收器自動(dòng)測(cè)試臺(tái)
        埃及
        用于獲取車輛中的旋轉(zhuǎn)構(gòu)件的旋轉(zhuǎn)角度的傳感器組件
        傳感器世界(2017年4期)2017-03-23 10:50:49
        淺析CTC與GSM-R系統(tǒng)網(wǎng)絡(luò)接口及路由配置改進(jìn)措施
        ZPW-2000A軌道電路接收器冗余電路存在問題分析及對(duì)策
        網(wǎng)絡(luò)設(shè)置管理
        從兩起故障談ZPW-2000發(fā)送盒報(bào)警檢測(cè)的改進(jìn)
        京滬高鐵GSM-R網(wǎng)絡(luò)接口監(jiān)測(cè)網(wǎng)關(guān)子系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)
        亚洲人成网站在线播放小说| 野狼第一精品社区| 成人天堂资源www在线| 午夜国产精品久久久久| 99久久综合九九亚洲| 国产成人精品中文字幕| 中文字幕一区二区三区的| 国产亚洲欧美精品久久久| 中文文精品字幕一区二区| 精品蜜桃一区二区三区| 人妻少妇69久久中文字幕| 米奇7777狠狠狠狠视频影院| 91热这里只有精品| 蜜桃网站在线免费观看视频 | 久久精品国产视频在热| 国产成人一区二区三中文| 亚洲av一区二区三区网站 | 人人妻人人澡人人爽精品日本| 精品亚洲成在人线av无码 | 福利一区二区三区视频在线| 久久国产在线精品观看| 无码中文字幕免费一区二区三区| 国产啪精品视频网给免丝袜| 亚洲精品中文字幕乱码人妻| 精品人妻一区二区三区浪人在线| 亚洲熟妇无码八av在线播放| 日韩欧美国产亚洲中文| 成人免费毛片立即播放| 人人做人人爽人人爱| 亚洲国产一区二区三区亚瑟| 久久婷婷国产五月综合色| 国产不卡精品一区二区三区| 亚洲性啪啪无码av天堂| 毛片免费全部无码播放| 精品亚洲人伦一区二区三区| 精品人妻一区二区三区在线观看| 丰满人妻熟妇乱又伦精品软件 | 日本a片大尺度高潮无码| 亚洲成人小说| 亚洲精品国产av一区二区| 97成人精品国语自产拍|