基礎知識漫談(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 implements SQLModel

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語句分析成模型呢?

 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM