第 14 章 理解應(yīng)用的結(jié)構(gòu)

2018-02-24 15:51 更新

本章將從程序員的視角來探討應(yīng)用的結(jié)構(gòu)問題。先從一個(gè)經(jīng)典的比喻開始,將應(yīng)用理解為一份菜譜,然后再從組件的角度,理解其對(duì)事件的響應(yīng),從而對(duì)應(yīng)用產(chǎn)生新的認(rèn)識(shí)。本章還將探討應(yīng)用如何提問、重復(fù)、記憶以及與Web交互,所有這些在后面章節(jié)均有更詳細(xì)的敘述。

{%}

大多數(shù)人是從用戶的角度來描述一個(gè)應(yīng)用,但是在程序員看來,應(yīng)用要復(fù)雜得多。我們必須充分理解應(yīng)用的內(nèi)部結(jié)構(gòu),才能更加有效地創(chuàng)建應(yīng)用。

通常從兩個(gè)方面來描述應(yīng)用的內(nèi)部結(jié)構(gòu):組件及行為,這大致與App Inventor的兩個(gè)主要窗口相對(duì)應(yīng):組件設(shè)計(jì)器及塊編輯器。前者用來設(shè)定應(yīng)用中的對(duì)象(組件),而后者用來編寫程序,實(shí)現(xiàn)對(duì)用戶及外部事件的響應(yīng)(應(yīng)用程序的行為)。

在圖14-1中,對(duì)應(yīng)用的架構(gòu)給出了總體描述,本章將對(duì)這種架構(gòu)進(jìn)行深入細(xì)致的探討。

{%}

圖 14-1 App Inventor應(yīng)用的內(nèi)部結(jié)構(gòu)

組件

應(yīng)用中的組件分為兩大類:可視組件及非可視組件??梢暯M件是在應(yīng)用啟動(dòng)后能夠看到的組件,如Button、Textbox及Label等,這些通常被視為應(yīng)用的用戶界面。

非可視組件是不可見的,因此它們不是用戶界面的組成部分,通常用于訪問設(shè)備的內(nèi)置功能,如,Texting組件用于收發(fā)短信,LocationSensor組件用于確定設(shè)備的位置,而TextToSpeech組件用于朗讀文字。非可視組件是設(shè)備的技術(shù)核心,是服務(wù)于應(yīng)用程序的小精靈。

兩類組件都是由一組屬性來定義,屬性相當(dāng)于組件信息的存儲(chǔ)空間。如可視組件的Width、Height及Alignment屬性,它們共同定義了組件的外觀。因此,最終用戶所看到的如圖14-2所示的“Submit”按鈕,實(shí)際上是在組件設(shè)計(jì)器中由一組屬性所定義的,如表14-1所示。

表14-1 按鈕屬性

Width Height Alignment Text
50 30 center Submit

{%}

圖 14-2 提交按鈕

可以將屬性理解為上面表格中的內(nèi)容,在組件設(shè)計(jì)器中,用它們來定義組件的初始外觀。如果將Width屬性從50改為70,那么無論是在設(shè)計(jì)器中,還是在實(shí)際應(yīng)用中,按鈕看起來都會(huì)變寬。注意,最終用戶不會(huì)看到70這個(gè)數(shù)字,他們只能看到按鈕變寬。

行為

一般來說,人們很容易了解組件的用途:文本框(Textbox)用于輸入信息,按鈕(Button)用來點(diǎn)擊等等。但是對(duì)于應(yīng)用中的行為,則往往是抽象的和復(fù)雜的。行為定義了應(yīng)用對(duì)事件的響應(yīng),無論是用戶發(fā)起的事件(如點(diǎn)擊按鈕),還是外部事件(如手機(jī)收到短信)。定義這些交互行為的難度恰恰是編程的挑戰(zhàn)性所在。

幸運(yùn)的是,App Inventor提供了一種非常適合于定義行為的可視化“塊”語言,本節(jié)為理解塊語言提供了一種模型。

應(yīng)用如菜譜

人們習(xí)慣于把軟件與菜譜相對(duì)比。像菜譜一樣,傳統(tǒng)的應(yīng)用由一系列的順序排列的指令構(gòu)成,如圖14-3所示,而計(jì)算機(jī)(廚師)則按順序執(zhí)行這些指令。

{%}

圖 14-3 傳統(tǒng)的軟件由一系列順序執(zhí)行的指令構(gòu)成

一項(xiàng)典型的銀行業(yè)務(wù)可能按如下順序執(zhí)行:

1. 啟動(dòng)某項(xiàng)業(yè)務(wù);

2. 執(zhí)行某些計(jì)算并修改客戶賬目;

3. 在屏幕上顯示新的余額信息。

應(yīng)用就是一系列的事件處理程序

然而,如今的絕大多數(shù)應(yīng)用,無論是手機(jī)的,還是Web或桌面電腦的,都不再適合采用這種菜譜模式了。應(yīng)用不再是順序地執(zhí)行一系列的指令,相反,更為普遍的是對(duì)事件的響應(yīng),事件的觸發(fā)者是最終用戶。例如,當(dāng)用戶點(diǎn)擊按鈕時(shí),程序會(huì)做出響應(yīng),執(zhí)行某些操作(如發(fā)送短信)。對(duì)于使用觸屏的手機(jī)或設(shè)備,當(dāng)你的手指在屏幕上拖動(dòng)時(shí),將觸發(fā)另一類事件,在應(yīng)用中可以利用這類事件,在手指最初的接觸點(diǎn)與最終的抬起點(diǎn)之間畫一條線,作為對(duì)該事件的響應(yīng)。

這種類型的應(yīng)用更適合于概括為“對(duì)事件做出響應(yīng)的組件的集合”。這類應(yīng)用中依然包含了“菜譜”——一些順序執(zhí)行的指令,但每個(gè)菜譜只限于對(duì)某些特定事件做出響應(yīng),如圖14-4所示的“菜譜”。

{%}

圖 14-4 擁有多個(gè)“事件菜譜”的應(yīng)用

因此,當(dāng)事件發(fā)生時(shí),應(yīng)用通過調(diào)用一系列的函數(shù)進(jìn)行回應(yīng)。這里的函數(shù)是指①利用某些組件來完成某些操作,如發(fā)送短信;②對(duì)某些組件屬性進(jìn)行操作,如在用戶界面上修改label的text屬性。調(diào)用函數(shù)意味著讓函數(shù)運(yùn)行,讓它產(chǎn)生作用。我們把事件,連同對(duì)事件進(jìn)行響應(yīng)的一系列函數(shù)統(tǒng)稱為事件處理程序(Event Handler)。

許多事件由最終用戶觸發(fā),但還有些不是。應(yīng)用可以對(duì)手機(jī)內(nèi)部的事件進(jìn)行響應(yīng),如方向傳感器的變化以及時(shí)鐘的行走(即時(shí)間的流逝),也可以對(duì)手機(jī)以外的事件做出響應(yīng),如來自于其他手機(jī)的事件,或收到來自web的數(shù)據(jù),等等。如圖14-5所示。

{%}

圖 14-5 應(yīng)用可以兼顧對(duì)內(nèi)部及外部事件的響應(yīng)

之所以稱App Inventor編程為“直觀”編程,是因?yàn)檫@種編程完全基于一種事件響應(yīng)模式,而“事件處理程序”則是該語言中最重要的詞匯(在其他語言中情況未必如此)。想要定義某個(gè)行為,首先要拖出一個(gè)事件塊,事件塊在形式上是這樣的:“When do”。假設(shè)有這樣一個(gè)“朗讀”應(yīng)用,當(dāng)用戶點(diǎn)擊按鈕時(shí),應(yīng)用大聲讀出用戶輸入的文字,這個(gè)應(yīng)用只需要一個(gè)事件處理程序,如圖14-6所示。

{%}

圖 14-6 “朗讀”應(yīng)用中的事件處理程序

這些塊的作用是,當(dāng)用戶點(diǎn)擊“SpeakItButton”按鈕時(shí),TextToSpeech組件將朗讀用戶在輸入框TextBox1中輸入的文字。在這里,事件是SpeakItButton.Click,對(duì)事件的響應(yīng)是調(diào)用TextToSpeech1.Speak函數(shù),事件處理程序中包括了圖14-6中的所有塊。

在App Inventor中,所有活動(dòng)都發(fā)生在對(duì)事件的響應(yīng)之中,應(yīng)用中不可能存在事件塊“when-do”之外的塊,如圖14-7這樣的單擺浮擱的塊是毫無意義的。

{%}

圖 14-7 事件處理程序之外的散在的塊毫無用處

事件類型

可以引發(fā)活動(dòng)的事件被分類列在表14-2中。

表14-2 能夠引發(fā)活動(dòng)的事件

事件類型 舉例
用戶發(fā)起的事件 當(dāng)用戶點(diǎn)擊Button1時(shí),執(zhí)行...
初始化事件 當(dāng)應(yīng)用啟動(dòng)時(shí),執(zhí)行...
計(jì)時(shí)器事件 當(dāng)20毫秒過去時(shí),執(zhí)行...
動(dòng)畫事件 當(dāng)兩個(gè)物體碰撞時(shí),執(zhí)行...
外部事件 當(dāng)電話收到短信時(shí),執(zhí)行...

用戶引發(fā)的事件

用戶引發(fā)的事件是一種最常見的事件類型,在輸入表單中,通常點(diǎn)擊按鈕事件會(huì)引發(fā)應(yīng)用的響應(yīng)。圖形化的應(yīng)用更多的是對(duì)觸摸及拖拽事件做出響應(yīng)。

初始化事件

有時(shí)需要在應(yīng)用啟動(dòng)時(shí)實(shí)現(xiàn)某些功能,這既不同于響應(yīng)最終用戶引發(fā)的事件,也不是對(duì)其他類型事件的響應(yīng),那么如何讓這種情況也適合于事件處理模式呢?

在App Inventor這種基于事件處理的語言中,應(yīng)用的啟動(dòng)也被視為一種事件。如果你想在應(yīng)用打開的同時(shí)實(shí)現(xiàn)某些功能,可以拖出Screen1.Initialize事件塊,并將某些函數(shù)調(diào)用塊放在其中。

例如,在第三章打地鼠游戲中,在應(yīng)用啟動(dòng)的同時(shí),通過調(diào)用MoveMole過程,將地鼠放在一個(gè)隨機(jī)的位置,如圖14-8所示。

圖 14-9 一旦Clock1.Timer開始運(yùn)行(計(jì)時(shí)),使用計(jì)時(shí)器事件塊來移動(dòng)球

動(dòng)畫事件

在canvas范圍內(nèi)的圖形對(duì)象(sprites精靈),它們的活動(dòng)將觸發(fā)動(dòng)畫事件,具體地說,當(dāng)兩個(gè)sprites發(fā)生碰撞,或一個(gè)sprites到達(dá)canvas的邊界時(shí),將觸發(fā)動(dòng)畫事件。因此可以編寫游戲或其他交互式動(dòng)畫程序,利用動(dòng)畫事件來定義游戲或動(dòng)畫的情節(jié)。更多信息請(qǐng)參見第17章。

外部事件

當(dāng)手機(jī)從接收到來自GPS衛(wèi)星的位置信息時(shí),將觸發(fā)一個(gè)外部事件;同樣,當(dāng)手機(jī)收到短信時(shí),也會(huì)觸發(fā)此類事件(圖14-10)。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)