1. 程式人生 > >基礎知識漫談(5):應用面向物件來分析“語言”

基礎知識漫談(5):應用面向物件來分析“語言”

萬物皆物件。

如果面試官問你“什麼是面向物件”,萬物皆物件就是個很好的開場白。

在網上認識的一些新人(甚至部分有三五年經驗的老鳥),在談論到面向物件\面向過程的時候,就陷入了誤區。

誤區一,面向物件和麵向過程是非此即彼的對立方,相互不相容。

誤區二,面向物件是種形而上的東西,“實際”開發中壓根沒用。

會產生這些誤區,本質上,都是不理解面向物件和麵向過程是什麼,陷入了教條主義,所以這裡統一一起說明。面向物件(OOP)是為了方便開發而產生的,它把常識中的概念,抽象成了對應的類。舉一個例子,貓吃老鼠

老鼠

語法層面

名詞·主語

動詞·謂語

名次·賓語

面向物件層面

貓類

貓類的方法

老鼠類

程式表達層面

cat

.eat

(mouse)

我們可以看到,日常語法結構,和程式語言結構達到了統一。反過來推論這個例子:Animal animal=new Cat();

在日常語言裡怎麼表達呢?這個動物,是一隻貓。

這一句話,就應用到了OOP三個基本特性裡的多型和繼承。在常識裡,動物的概念是囊括了貓的概念的,那麼,我們說“那裡有一隻動物”,語法上毫無問題,但是那隻“動物”就僅僅只是動物了麼?“動物”作為一種抽象概念,它在實際中並不能獨立存在是不是?它必須得是一隻貓,或者一隻老鼠。但它絕不能是一個瓶子。

綜上,我們可以推論得出:

1、動物是個抽象概念,所以Animal應當是個抽象類或者介面,你絕不能寫出new Animal();這樣的語句出來。

2、老鼠和貓是繼承\實現自Animal的,而瓶子不是。

3、談論到類的時候,要分清語境,到底是談論的類定義還是類例項,比如貓這個概念,是類定義,具體的某一隻貓就是類的例項。也就是Cat和某個cat=new Cat()的區別。

說完了這些,我們來應用這些基礎知識實際的分析SQL語句本身,來看看面向物件到底有沒有實際作用。

select * from user where id>1 and name<>’Abby’ group by sexsual sort by age

分析開始:

1、這是一條SQL語句,所以,我們需要有一個類SQLStatement

2、具體而言,這是一條Select語句,所以,會有class SelectStatement extends SQLStatement

3、該類語句的基本結構是select [Columns] from [Table] [Where][GroupBy][SortBy]

select和from是特定關鍵字,用字串記錄在SelectStatement即可,Columns、Table、Where、GroupBy、SortBy都是SQL元素(SQLElement),明顯的,和SQL語句有相似性又有所不同。這裡提出一個更加抽象的概念SQL模型(SQLModel)。使SQLStatement\SQLElement implementsSQLModel

ColumnElement,TableElement,WhereElement等等類的設計是不是也理所當然了?

下面特別講解下ColumnElement和WhereElement的設計問題。

在SQLStatement中能存在多個ColumnElement,所以需要一個集合結構來存放ColumnElement。

一個Column,應當具備列名和別名。所以ColumnElement會具備String型別的name屬性和alias屬性。

結構如圖所示:

 

WhereElement就要複雜一些,本質上來說,Where表達的是查詢條件,查詢條件又是由一個到多個條件表示式(Expression)組成,

簡單的表示式(SimpleExpression)如:

a、id=1

b、id between 0 and 10

c、name like ‘N%’

可以總結出,SimpleExpression結構大致如下:[列名\別名] [操作符] [值]

複合的表示式(ComplexExpression),則是在簡單的基礎上加上AND\OR條件,如:

id=1 AND id between 0 and 10

也就是說,ComplextExpression結構如下:[左側表示式][條件][右側表示式]

思考一個問題,A AND B OR C這樣的結構,要如何使用符合表示式來展現呢?

解答,我們可以把 A AND B OR C視為 Exp1 =  A AND B,Exp2= Exp1 OR C。綜上,我們可以大概得出WhereElement的設計如下:

 

應用以上的思路,我們可以想想,子查詢要怎麼對映成我們的SQLModel呢?這裡不再詳細解答,可以注意,在SimpleExpression裡,[值]部分我使用了一個ValueModel,對於它的設計將會帶給你答案。

完成這些設計後,究竟要怎麼使用它呢?

對於熟悉面向物件的讀者來著,這道理是顯而易見的,我這裡舉一個例子:輸出SQL語句。

試想,JavaBean是可以靈活組合的,現在,你已經組合出了一個你滿意的SelectStatement,要如何拼裝出對應的SQL呢?答案是,呼叫toSQL()方法。SelectStatement#toSQL()大概輸出如下:

Select [遍歷ColumnElement#toSQL()] From [TableElement#toSQL()] [WhereElement#toSQL()] [GroupByElement#toSQL()][SortByElement#toSQL()]

ColumnElement#toSQL()會輸出為ID nid這樣的格式。

WhereElement#toSQL()則遍歷它內部的Expression#toSQL()向下迭代輸出。

每一個語句塊的輸出格式由它自身負責,語句塊之間的組織由上一級的語句塊負責,最終,就達到了靈活拼裝SQL的效果。

思考一個問題:我們有沒有思路,將SQL語句分析成模型呢?

下篇文章會談談我在招聘時遇到的一些情況,希望會對正在找工作的朋友有所幫助。