定義
一切計(jì)算機(jī)程序,不過(guò)是對(duì)人類頭腦中的現(xiàn)實(shí)世界抽象的一種形式化描述。因此,也就是說(shuō),程序根源于人類對(duì)現(xiàn)實(shí)世界的抽象。這種抽象即模型。比如說(shuō),人在認(rèn)識(shí)一個(gè)東西是否是貓的時(shí)候,會(huì)用貓的抽象去比對(duì),以比較現(xiàn)實(shí)世界的這個(gè)東西是否符合心中對(duì)貓的抽象——貓的模型,假如說(shuō),他認(rèn)為兩者是契合的,那么,該東西就會(huì)被打上貓的標(biāo)簽。在這一整個(gè)過(guò)程中,出現(xiàn)了兩樣?xùn)|西,即模型——心中對(duì)于所有的貓的一種抽象——和實(shí)例——那個(gè)符合貓的模型的現(xiàn)實(shí)世界的東西。
然而,人類的心中還有千千萬(wàn)萬(wàn)的模型,諸如狗的模型,豬的模型等。這些模型之間的比較不能依賴于實(shí)例的比較。實(shí)例的比較只能說(shuō)明實(shí)例的不同而不能說(shuō)明模型的不同。當(dāng)我們?cè)谟懻撠埡凸返膮^(qū)別的時(shí)候,我們說(shuō)的并不是某一只貓和某一只狗的區(qū)別(當(dāng)然,一些哲學(xué)家恰好持有相反的論點(diǎn)。但是在一般人的概念里,他比較狗和貓的區(qū)別,雖然心中浮現(xiàn)的是具體的貓和具體的狗,但是實(shí)際上他認(rèn)為他比較的是抽象的貓和狗。),而是說(shuō)的是心中貓和狗的模型的差別。
比如說(shuō),我們說(shuō)貓的叫聲是喵喵叫,而狗的叫聲是汪汪叫,說(shuō)的不是鄰居家的狗和自己家的貓,而是指一種普遍性的比較。這種比較只能是模型的比較。而要比較兩個(gè)東西,我們首先需要一個(gè)對(duì)于這兩個(gè)東西的描述,因?yàn)?,如果我們無(wú)法描述一個(gè)東西,顯然不能比較它與別的東西。也就是說(shuō),我們要比較兩個(gè)模型,就得首先有兩個(gè)模型的描述。這種描述即元數(shù)據(jù)。
因此,模型是一種普遍的概念,是對(duì)于某一類事物的抽象;實(shí)例則是模型的具體的例子,也可以說(shuō)是我們借以抽象出模型的那些個(gè)獨(dú)特的事物;而元數(shù)據(jù),則是對(duì)模型的一種描述。
模型的模型
此外,還有一種特殊的東西,即模型的模型。模型既然是一種現(xiàn)實(shí)的東西,它雖然只是一種純粹的思維的產(chǎn)物,也就是說(shuō)在現(xiàn)實(shí)中找不到任何一個(gè)模型,但是這并不妨礙模型會(huì)產(chǎn)生模型。也就是說(shuō),不妨礙我們對(duì)模型進(jìn)行進(jìn)一步的抽象,得到“模型的模型”。在貓和狗的例子中,我們可以對(duì)貓和狗的模型進(jìn)行進(jìn)一步的抽象。假如說(shuō),我們的狗的模型就是“叫聲是汪汪的”,而貓的模型就是“叫聲是喵喵的”,當(dāng)我們要進(jìn)一步抽象的時(shí)候,我們抽象的其實(shí)就是“叫聲是汪汪的”的和“叫聲是喵喵的”這兩個(gè)分別對(duì)狗和貓的模型的描述。于是我們可以得出,貓和狗的模型的模型就是“描述了叫聲的模型”。
這里有一個(gè)很模糊的地方。就是,假如我們對(duì)狗和貓的模型進(jìn)行抽象,能否得到動(dòng)物的模型。也就是說(shuō),能否認(rèn)為動(dòng)物模型是貓模型和狗模型的模型。這是一個(gè)很微妙的問(wèn)題。對(duì)此,我的答案是不能。因?yàn)榫蛷呢埡凸返睦觼?lái)看,抽象出來(lái)的動(dòng)物模型是“會(huì)叫的東西”。這兩者抽象的對(duì)象明顯不同,一個(gè)是對(duì)模型的抽象,一個(gè)是對(duì)所有的貓和狗的實(shí)例的抽象。也就是說(shuō),貓和狗的模型的模型,是對(duì)模型的抽象;而動(dòng)物的模型,是對(duì)貓和狗的實(shí)例的抽象。
我用Java來(lái)說(shuō)明這個(gè)問(wèn)題。我們對(duì)貓和狗的抽象,對(duì)應(yīng)的是貓和狗的類,而對(duì)貓和狗的類的抽象,應(yīng)該是Java中的Class類。而動(dòng)物的抽象應(yīng)該是一個(gè)動(dòng)物的類。顯然動(dòng)物的類不等于Class類。動(dòng)物的抽象和貓與狗的抽象之間的關(guān)系,應(yīng)該是繼承,具體化的關(guān)系而不是實(shí)例化的關(guān)系。
**商品模型的例子
**
在電商中,很重要的一個(gè)需求是建立一個(gè)商品系統(tǒng)。在商品系統(tǒng)的演進(jìn)過(guò)程中,最開始可能只是為每一個(gè)單獨(dú)的商品類型都建立一個(gè)模型(這個(gè)可能對(duì)應(yīng)于數(shù)據(jù)庫(kù)的一張表,或者代碼中的一個(gè)類),但是當(dāng)商品類型多了之后,會(huì)發(fā)現(xiàn)這種方式基本上無(wú)法工作(考慮一下淘寶上面成千上萬(wàn)的商品類型以及依舊還在源源不斷產(chǎn)生的新的類型)。
這種情況下,才催生了對(duì)于模型的模型的探討和設(shè)計(jì)。也就是,我們需要一個(gè)模子,這個(gè)模子能批量生產(chǎn)不同的商品類型。這就如同我們定義了一個(gè)商品類型作為模子,而后生產(chǎn)了千千萬(wàn)萬(wàn)的該類型的商品。
要能夠創(chuàng)造這么一個(gè)模子,首先要解決的問(wèn)題是對(duì)所有商品類型的抽象。首先,要先仔細(xì)區(qū)分一個(gè)商品類型所必然要有的東西。比如說(shuō),一個(gè)商品類型要有名字,例如“手機(jī)”。然后還有一些個(gè)性化的東西,比如說(shuō)手機(jī)類型可能會(huì)有一個(gè)“內(nèi)存大小”的屬性。這些屬性都是對(duì)商品類型的抽象。必備的屬性和可選的屬性有一個(gè)很重要的區(qū)別,就是必備的屬性在商品類型里面其值是確定的,而可選的屬性,其值是不確定的。通常來(lái)說(shuō),抽象的對(duì)象涵蓋的范圍越多,那么必備的屬性就越少,而可選的屬性就越多。(如果對(duì)整個(gè)世界的商品類型進(jìn)行抽象,大概只有名字一個(gè)是必備的了)
暫時(shí)不需要理會(huì)什么是必備的屬性和可選的屬性。我們需要從前面的結(jié)論進(jìn)一步探討,對(duì)商品類型建模,究竟是建立什么。顯然,對(duì)于必備屬性來(lái)說(shuō),我們需要給它們一個(gè)值,例如某個(gè)具體商品類型(模型的實(shí)例)的名字;對(duì)于可選屬性,我們需要將所有可能的可選屬性列出來(lái)。如果我們排除必備屬性和可選的屬性的區(qū)別,那么可以統(tǒng)一抽象為,創(chuàng)建某個(gè)商品類型,就是指明這個(gè)商品類型有些什么屬性,并且這些屬性可以取的值為什么。依舊使用手機(jī)的例子。在創(chuàng)建這個(gè)手機(jī)類型的時(shí)候,我們需要給出手機(jī)會(huì)有什么屬性,比如說(shuō),手機(jī)有品牌,顏色,大小。這就意味著,商品類型的模型能夠完成這種指定屬性的過(guò)程——也就是,商品類型模型的實(shí)例化過(guò)程。
因此,現(xiàn)在已經(jīng)可以看到商品類型的模型究竟是一個(gè)什么東西。但是,我們還有一個(gè)問(wèn)題:不同商品類型有不同的屬性,而我們無(wú)法窮舉所有的屬性。這么看起來(lái),我們似乎無(wú)法把這個(gè)模型建立起來(lái)。
要解決在系統(tǒng)中建立商品類型模型的問(wèn)題,我們還需要進(jìn)行一次抽象。在這次抽象中,我們將某個(gè)屬性看成是一個(gè)實(shí)例,而我們的抽象是要建立起來(lái)屬性的模型。這體現(xiàn)的解決問(wèn)題的思路就是:如果我無(wú)法窮舉所有的東西,但是我能夠窮舉所有的生產(chǎn)這些東西的方法,那么我依然可以生產(chǎn)出任何我需要的東西。這有點(diǎn)類似于設(shè)計(jì)模式里面的建造者類型的設(shè)計(jì)模式,如工廠模式、抽象工廠模式。
現(xiàn)在是仔細(xì)觀察屬性的時(shí)候了。我的觀察結(jié)果是,屬性具備幾個(gè)基本的特性:名字,描述,取值范圍。其中描述甚至不是必須的,因?yàn)槊趾兔枋鰺o(wú)非是為了人類理解而做出的一種標(biāo)記。我要重點(diǎn)討論的是屬性的取值范圍。屬性的取值可以分成兩種,開放式取值和閉合式取值。所謂開放式取值,是指屬性的值無(wú)法枚舉出來(lái),其可能性是無(wú)窮的;閉合式取值是,屬性的值是從特定的某些值里面選取,這些特定的值是有窮的并且是可以被確定下來(lái)的。所以,要?jiǎng)?chuàng)建一個(gè)新的屬性,無(wú)非就是指定屬性的名字,指定名字的取值范圍。(其實(shí),屬性還可以具備別的特性,不過(guò)這些特性更加多的是一種補(bǔ)充性質(zhì)的,所以這里不加探討)。對(duì)屬性的特性進(jìn)行分類,可以減少屬性模型實(shí)例化的工作量。因?yàn)榫陀?jì)算機(jī)來(lái)說(shuō),常見的無(wú)非就是文本,字符串,數(shù)字,多選,單選,多媒體。
現(xiàn)在已經(jīng)解決了屬性無(wú)限性的問(wèn)題,我們可以很方便的利用屬性模型產(chǎn)生任何一種屬性,無(wú)論是什么屬性。而這些屬性的不同組合方式可以產(chǎn)生各種商品類型。各種商品類型的實(shí)例化,最終就得出了無(wú)數(shù)的商品。用一幅圖來(lái)描述:

在這里,商品類型模型就是一個(gè)屬性集,該屬性集用來(lái)描述所有的商品類型。
在真實(shí)的系統(tǒng)中,商品類型模型是找不到一個(gè)實(shí)體來(lái)對(duì)應(yīng)它的,它實(shí)際上表現(xiàn)為一個(gè)創(chuàng)建屬性以及給商品類型分配屬性的模塊。這樣的一個(gè)系統(tǒng)大概會(huì)有幾個(gè)組成部分:
屬性錄入部分。這個(gè)部分如果采用模板的方式的話,只需要準(zhǔn)備幾個(gè)模板便足夠了。當(dāng)然,如果不同的屬性,屬性的不太值之間有很強(qiáng)的依賴,那么這個(gè)部分就會(huì)變得比較復(fù)雜;
商品類型定義部分。這個(gè)部分無(wú)非就是一些屬性的組合,復(fù)雜點(diǎn)的包括屬性之間的約束,屬性的現(xiàn)實(shí)取值等;
商品的錄入。在商品類型定義的部分,定義好的商品類型,也就是商品模型,已經(jīng)能夠很明確的說(shuō)明的一個(gè)商品是一個(gè)什么樣的東西了。
這三個(gè)部分并不是一定要有準(zhǔn)確的系統(tǒng)模塊與之對(duì)應(yīng)。實(shí)際上,簡(jiǎn)單起見的話,1和2是可以結(jié)合在一起。這種結(jié)合在一起的形式,還能避免一些“同樣”的屬性在不同的商品類型里面有不同的約束的問(wèn)題。
**總結(jié)
**
除了上面舉出來(lái)的例子,現(xiàn)實(shí)世界中還有很多可以應(yīng)用的方面,尤其是在我們想要解決一些通用性的問(wèn)題的時(shí)候。比如說(shuō)審核。在一個(gè)互聯(lián)網(wǎng)企業(yè)中,需要人工審核的內(nèi)容有很多,其形式也是多樣的。但是,依然可以抽象為類似于這種結(jié)構(gòu)。每一類的審核內(nèi)容,就對(duì)應(yīng)于一個(gè)商品類型——一般也會(huì)被稱為審核模板。比如說(shuō)審核商品的信息,審核用戶評(píng)論。而一個(gè)制造出這種模板的東西,就是審核模板模型,對(duì)應(yīng)于商品類型模型。而這些模板依舊是由屬性構(gòu)成的,不同的構(gòu)成方式?jīng)Q定了模板,構(gòu)成模式一定時(shí),屬性的取值就是一個(gè)個(gè)最終的審核實(shí)例。
那么,一直抽象到屬性的模型,是否就已經(jīng)到達(dá)了抽象的終點(diǎn)?并不是這樣的。在計(jì)算機(jī)領(lǐng)域內(nèi),二進(jìn)制是抽象的終點(diǎn)。凡是計(jì)算機(jī)里面的東西,都是由二進(jìn)制表示而成的,最終也將回歸到這一點(diǎn)。