大數據

UMC面向Serverless的全棧開發架構,用後端體系開發原生移動應用

UMC介紹

UMC的全名是UI Model Command,意思是讓UI響應服務端的模塊指令,實現上就是設計了一套客戶端與服務端交互的文本協議,此協議能讓就是客戶端用標準請求服務端、服務端用標準JSON格式響應客戶端。客戶端分析出JSON端包含的事件,數據和UI組件,達到操控和繪製客戶端目的,現在服務端我們已經用java.net實現了此標準協議(後期我們會實現其他計算機語言),現在java後端工程師和.net後端工程師只要用此架構開發,就能快速實現了原生Android和原生IOS端和H5端和小程序(嵌套H5,後期會用原生小程序實現),H5都已經開源,此協議用一套標準,統一實現PC和H5端,小程序端,安卓和蘋果端的界面實現和後臺邏輯。
這也意為做,一個統一的後臺就可以管理各個終端,用此實現的業務不但開發維護簡單,業務維護也更簡單,對公司而言,有後端工程師就有各IOS和Android的團隊班子,對於後端工程師更是賦能,現在他們能開發Android和IOS應用了,對於Android和IOS工程師,讓他們告別雜亂UI繪製和UI跳轉方式,進入終端的組件式開發,且只要對新組件實現就可以了,讓終端開發更簡單,對發佈來太太減少APP版本發佈次數,我也相信每個後臺工程師和Android和IOS工程師都願意掌握此技能。
UMC是在數據通信上是採用Http GET方式請求,為什麼採用GET方式呢,客戶端與服務端做為非文件交互,整體來說交互所要的數據是相當少,GET方式足可滿足我們應用需要,如果需要文件交互,則採用先把資源上傳到文件服務器,再來由UMC處理,這樣就簡單高效了,還不用佔用帶寬,又起服務器分流等做用,此設計為我分佈式和API高性能網關提供了前期基礎。
再來說交互路由吧,我們用GETQueryString來交互傳參,我們保留jsonp參數做跨域使用,還有_model_cmd就是我們的ModelCommand,再除去_開頭的參數就是這次有效請求的參數,就這樣根據ModelCommand帶著參數去路由,跑一遍,把再結果返回給客戶端,就這樣完成這次請求了,他的原理就是這樣回事。下面我用java講解如何實現。

UMC的IWebFactory、WebFlow、WebActivity

請求路由路線是由model和cmd來確認,他對應的後臺路由類分別為IWebFactory接口,WebFlow基類、WebActivity基類,其中由IWebFactory來確認接收那此model並返回接收WebFlow類,再就WebFlow類確認cmd,由那個WebActivity處理,整個處理路由就是這樣,下面我們就來講解此邏輯

IWebFactory

//IWebFactory
public class FlowFactory implements IWebFactory {
    @Override
    public void init(WebContext context) {

    }

    @Override
    public WebFlow flowHandler(String mode) {
        switch (mode) {
            case "Account":
                return new AccountFlow();
        }
        return WebFlow.Empty;
    }
}

WebFlow

上例代碼展示,此IWebFactory只接收Accountmodel,此模塊的cmd路由由AccountFlow處理,下面我們就查看AccountFlow代碼

public class AccountFlow extends WebFlow {
    @Override
    public WebActivity firstActivity() {
        switch (this.context().request().cmd()) {
            case "Login":
                return new AccountLoginActivity();
            case "Register":
                return new AccountRegisterActivity();
            case "Forget":
                return new AccountForgetActivity();
            case "Password":
                return new AccountPasswordActivity();
        }

        return WebActivity.Empty;
    }
}

從上列代碼可以就看到AccountFlow,可以路由指令LoginRegisterForgetPassword,每個指令都有自己的WebActivity,WebActivity就是我們的業務實現了,處理業務業務方法在processActivity,下面我就用AccountLoginActivity來說明WebActivity的處理方式

WebActivity

public class AccountLoginActivity extends WebActivity {
    @Override
    public void processActivity(WebRequest request, WebResponse response) {

        WebMeta user = this.asyncDialog(d ->
        {
            UIFormDialog dialog = new UIFormDialog();
            dialog.title("賬戶登錄");
            dialog.addText("用戶名", "Username", "").put("placeholder", "手機/郵箱");
            dialog.addPassword("用戶密碼", "Password", "");
            dialog.submit("登錄", request, "User");//事件對話框
            dialog.addUIIcon('\uf1c6', "忘記密碼").put("Model", request.model()).put("Command", "Forget");
            dialog.addUIIcon('\uf234', "註冊新用戶").put("Model", request.model()).put("Command", "Register");
            return dialog;
        }, "Login");
        String username = user.get("Username");

        Membership userManager = WebADNuke.Security.Membership.Instance();
        int times = userManager.Password(username, passwork, maxTimes);
        switch (times) {
            case 0:
                Identity iden = userManager.Identity(username);

                AccessToken.login(iden, AccessToken.token(), request.isApp() ? "App" : "Client", true);

                this.context().send("User", true);

                break;
            case -2:
                this.prompt("您的用戶已經鎖定,請過後登錄");
                break;
            case -1:
                this.prompt("您的用戶不存在,請確定用戶名");

                break;
            default:
                this.prompt(String.format("您的用戶和密碼不正確,您還有%d次機會", maxTimes - times));

                break;
        }
    }
}

我這裡先說說processActivity方法的兩個參數吧,request,response其中request是請求的所有參數信息都這裡,包含客戶端環境,是不是APP中,是不是微信中,客戶的IP是多少,和QueryString參數,但requestQueryString規整化了,當請求中有modelcmd的時間,QueryString單值可以request.sendValue()獲取,多值可以用request.sendValues()得到;當請求無modelcmd的時,則會把請求把QueryString規整化到了對話框中,以對話框的方式獲取交互的值;response客戶端響應對象,他可以完成數據輸出或跳轉。一句話就是request是獲取客戶端信息,response是操作響應內容的;
從上面講解中,我們知道QueryString會規整到request請求參數中去,這裡講一講請求參數與箭頭函數的之間的關係。箭頭函數在什麼樣的情況下執行呢,只有在請求參數或會話中找到這對話框的參數值,則執行箭頭函數獲得一個對話框給並返回到客戶端;先聲明一個對話框,對話框分為單值對話框和表單對話框,先說單值對話框與請求參數對應的關係吧,每個請求的對話框都有一個asyncId,也就是asyncDialog傳入進去asyncId,確認asyncId是不是有值,先從會話參數中找,如果沒有,從對話框參數池中找,如何不存在對話框參數,檢測request.sendValue()還沒有值,再用asyncId作為key來檢測request.sendValues(),如果都沒值的情況下,再去執行箭頭函數獲取對話框。這就是單值對話框獲取值的邏輯,下面我們再說說表單對話框獲取值的方式,第一步也是一樣從會話參數中找,沒有找到,再看對話框參數池是不是表單值,如果不是或沒有,再看request.sendValues()是不是能與此次表單asyncId對應,(他的對應關係架構會自行處理)如果不是或沒有,再去執行箭頭函數獲取表單對話框。這就是表單對話框獲取值的邏輯;整個對話框都是為了讓對話框的asyncId配對QueryString,這也說明只要做準備好WebActivity所要的的參數,就能執行完processActivity邏輯,中途就不會去執行箭頭函數。
在對話框中從獲取值的方式上,可分為兩種,會話對話框和事件對話框,會話對話框前端提交之後就關閉,事件對話框是根據服務端返回的事件,進行關閉或者刷新。在我們的UIGridDialogUIFormDialog都支持這兩種模式

現在我們講解一下上面的AccountLoginActivityprocessActivity,此processActivity有登錄表單對話框,此對話框並啟用了事件對話框,看dialog.submit("登錄", request, "User")這塊表示啟用了事件對話框模式,
說明這麼多,實事上是希望大家理解此模式,這也就UMC架構的業務處理層的核心思想,其他的解譯都是豐富這模式下的應用場景。
回頭我們再看看AccountLoginActivityprocessActivity方法,可從代碼中可以看出,此Activity有繪出一個用戶登錄的UIFormDialog,還關聯到忘記密碼和用戶註冊,這就是我們登錄功能的全部代碼,是不是簡單,掌握他就能開發出高性能的Andord,IOS和H5和小程序,因為他們的對應的客戶端都是用原生程序寫的,不是比其他任何內嵌引擎的都要快,對應後端工程師來說,掌握他不併跨出後端的知識體系。他用的是後端架構思維,驅動各前端應用,是不是掌握他是不是更有價值呢。

Leave a Reply

Your email address will not be published. Required fields are marked *