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高性能網關提供了前期基礎。
再來說互動路由吧,我們用
GET
用
QueryString
來互動傳參,我們保留
jsonp
參數做跨域使用,還有
_model
_cmd
就是我們的
Model
與
Command
,再除去
_
開頭的參數就是這次有效請求的參數,就這樣根據
Model
Command
帶着參數去路由,跑一遍,把再結果傳回給用戶端,就這樣完成這次請求了,他的原理就是這樣回事。下面我用
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
隻接收
Account
的
model
,此子產品的
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
,可以路由指令
Login
,
Register
Forget
Password
,每個指令都有自己的
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
參數,但
request
把
QueryString
規整化了,當請求中有
model
cmd
的時間,
QueryString
單值可以
request.sendValue()
擷取,多值可以用
request.sendValues()
得到;當請求無
model
cmd
的時,則會把請求把
QueryString
規整化到了對話框中,以對話框的方式擷取互動的值;
response
用戶端響應對象,他可以完成資料輸出或跳轉。一句話就是
request
是擷取用戶端資訊,
response
是操作響應内容的;
從上面講解中,我們知道
QueryString
會規整到
request
請求參數中去,這裡講一講請求參數與箭頭函數的之間的關系。箭頭函數在什麼樣的情況下執行呢,隻有在請求參數或會話中找到這對話框的參數值,則執行箭頭函數獲得一個對話框給并傳回到用戶端;先聲明一個對話框,對話框分為單值對話框和表單對話框,先說單值對話框與請求參數對應的關系吧,每個請求的對話框都有一個
asyncId
,也就是
asyncDialog
傳入進去
asyncId
,确認
asyncId
是不是有值,先從會話參數中找,如果沒有,從對話框參數池中找,如何不存在對話框參數,檢測
request.sendValue()
還沒有值,再用
asyncId
作為key來檢測
request.sendValues()
,如果都沒值的情況下,再去執行箭頭函數擷取對話框。這就是單值對話框擷取值的邏輯,下面我們再說說表單對話框擷取值的方式,第一步也是一樣從會話參數中找,沒有找到,再看對話框參數池是不是表單值,如果不是或沒有,再看
request.sendValues()
是不是能與此次表單
asyncId
對應,(他的對應關系架構會自行處理)如果不是或沒有,再去執行箭頭函數擷取表單對話框。這就是表單對話框擷取值的邏輯;整個對話框都是為了讓對話框的
asyncId
配對
QueryString
,這也說明隻要做準備好
WebActivity
所要的的參數,就能執行完
processActivity
邏輯,中途就不會去執行箭頭函數。
在對話框中從擷取值的方式上,可分為兩種,會話對話框和事件對話框,會話對話框前端送出之後就關閉,事件對話框是根據服務端傳回的事件,進行關閉或者重新整理。在我們的
UIGridDialog
UIFormDialog
都支援這兩種模式
現在我們講解一下上面的
AccountLoginActivity
processActivity
,此
processActivity
有登入表單對話框,此對話框并啟用了事件對話框,看
dialog.submit("登入", request, "User")
這塊表示啟用了事件對話框模式,
說明這麼多,實事上是希望大家了解此模式,這也就UMC架構的業務處理層的核心思想,其他的解譯都是豐富這模式下的應用場景。
回頭我們再看看
AccountLoginActivity
processActivity
方法,可從代碼中可以看出,此Activity有繪出一個使用者登入的
UIFormDialog
,還關聯到忘記密碼和使用者注冊,這就是我們登入功能的全部代碼,是不是簡單,掌握他就能開發出高性能的Andord,IOS和H5和小程式,因為他們的對應的用戶端都是用原生程式寫的,不是比其他任何内嵌引擎的都要快,對應後端工程師來說,掌握他不并跨出後端的知識體系。他用的是後端架構思維,驅動各前端應用,是不是掌握他是不是更有價值呢。