開發 Embedded Systems 相關應用時,常得處理多國語言。而系統資源受限的的場合,就算掛了 OS,往往也沒內建多國語言。這時候只能捲起袖子自己處理了。自幹的過程,很直覺地,多數人都會想到要有個類似右圖這樣的 Excel 字典檔當作翻譯表。
有了翻譯表後,我們還要有個字庫(font)。為了存取字庫裡的字,我們要先決定字序(character order)。有了字序後,我們就能根據字序,把翻譯表裡面的多國語言訊息,一一轉換成字序的串列(a sequence of character orders)。要秀某個訊息時,就根據這個字序列,回過頭把字庫裡的字形(glyph)抽取出來顯示。
typedef enum {
SEASON_BEGIN,
SPRING = SEASON_BEGIN,
SUMMER,
AUTUMN,
WINTER,
SEASON_END,
SEASON_TOTALS = SEASON_END // the total number of seasons
} Season;
在軟體開發過程,我們很可能得寫大量的程式碼來完成一些繁瑣、平凡的工作,避開這個窠臼的辦法就是「自動化」。誠如 Kernighan 和 Pike 在 The Practice of Programming 一書所闡述的,優秀的軟體設計運用幾個基本原則:簡單(simplicity)、清晰(clarity)、一般性(generality)、自動化(automation)。
舉個例子, IC designers 常會跟 f/w 人員一起關起門來,私下協調出各種用途的 registers (memory mapped I/O),這些開放給 f/w 人員使用的 register 介面,會有一份以 Verilog 形式存在,另一份則以 C code 的形式存在,在 IC 開發過程,這些 registers 會經歷多次的變更(例如改名字、改位址、添加 registers、刪減 registers 等)。可以想見,要手動讓這些 registers 在 Verilog 及 C 間維持一致,是件繁瑣、容易出錯的事。
為甚麼好的設計會來自於差的設計呢? Scott 在 Why Good Design Comes from Bad Design 提到攻讀 CMU Computer Science 博士時選了門介面設計課,第一堂課上他發現一位年輕人素描著隨身聽的各種變異版本,而且圖紙上已經堆積了三、四十種不同考量的版本了。 Scott 於是湊過去問這個小伙子「幹嘛費勁畫那麼多草稿?」,小伙子發楞了好一會才笑著回說:
I don't know what a good idea looks like until I've seen the bad ones.
經過時日洗煉, Scott 後來也體會到當初認為多餘的作法,其背後的精神,他提到:
Each new idea I sketched out was more informed than the last. Each bad idea illustrated some important aspect of the problem that I hadn't thought about before. Out of every five or six ideas, I'd have one or two that might be feasible.
I learned the right way to present ideas–you have to show the other candidates in order to help support the good ones.
When the design student showed me his sketches, he was showing me that he was a designer. All creative, talented people recognize the value of process, and have no concerns about revealing to others that it takes many bad ideas to obtain good ones.
At the start of an ambitious development project, we do not know the best way to structure the system. Often, we don't even know precisely what the system should do because particulars will become clear only through the effort of building, testing, and using the system. How - short of building the complete system - do we get the information necessary to understand what design decisions are significant and to estimate their ramifications?
-- ref. The C++ Programmming Language, p710
Software entities should be open for extension, but closed for modification
Principle of Encapsulation of Variation
Liskov Substitution Principle
Dependence Inversion Principle
Abstractions should not depend upon details. Details should depend upon abstractions.
Program to an interface, not an implementation
Composit/Aggregate Reuse Principle
Law of Demeter -- Least Knowledge Principle
Only talk to your immediate friends. Don't talk to strangers
Interface Segregation Principle
優秀的程式師總是在思索、尋求「一勞永逸」的作法。學習時不妨從具體案例開始;學成應用時,要改而著重背後的精隨,才不會被細節淹沒。這些年下來,我體會到這個精隨就是「因應變化而設計(Design for Change)」。
要明白 Design for Change ,這裡強烈推薦翻翻 Refactoring 裡提出的壞味。個人認為其中又以下列兩個壞味最為深刻:
這本書最合我胃口的是第二章〈小心!前有機器車〉,探討作者對機器自走車的實務經驗。裡面提到作者 Hans Moravec 在 Mobile Robot Laboratory 接受 Denning Mobile Robotics 委託,研究如何以二十四個聲納組成的障礙偵測裝置,量測、取得的距離資料,完成自主機器車導航的任務。
第三章 Power and Presence 主要探討計算能力與機器心智間的關係。曾經關注過電腦發展的人,對這章的推論應該不會太過驚訝:作者一開始先提提怎麼樣能力(如運算速度及記憶容量等)的電腦能達成怎麼樣的任務,然後粗估了人腦運算速度及記憶容量,既然電腦運算能力每年都要倍增,所以估出 2020 年時,個人電腦的能耐會達到人腦級。無論對這議題感到興趣或心存懷疑的,都非常建議也翻翻《心靈機器時代》,當中提到的時間與渾沌的定律(The Law of Time and Chaos),很值得一讀。
作者還在這章提到一個非常有意思的主題--電腦史上不同時間點 PC 的記憶容量(megabytes)與運算速度(MIPS)相除,會粗略維持一個常數,約 1 秒鐘(大概等於電腦將整塊記憶體掃一次需要耗費的時間),原因是電腦跟外界溝通的主要對象是人類,所以要受人類的速度感所束縛,原文對這部份描述得很生動:
The megabyte/MIPS ratio seems to hold for nervous systems too! The contingency is the other way around: computers are configured to interact at human time scales, and robots interacting with humans seem also to be best at that ratio.
On the other hand, faster machines, for instance audio and video processors and controllers of high-performance aircraft, have many MIPS for each megabyte.
Very slow machines, for instance time-lapse security cameras and automatic data libraries, store many megabytes for each of their MIPS.
Flying insects seem to be a few times faster than humans, so may have more MIPS than megabytes.
As in animals, cells in plants signal one other electrochemically and enzymatically. Some plant cells seem specialized for communication, though apparently not as extremely as animal neurons. One day we may find that plants remember much, but process it slowly.
Universal Robots
電腦是 Universal Turing Machine, UTM 的一個良好近似,和 UTM 對應的是 Universal Robots, UR 。不同的是 UTM 專職在虛擬的數位空間發揮運算能力, UR 則落實到現實世界裡的感官及行動上。