萬物皆對象。
如果面試官問你“什么是面向對象”,萬物皆對象就是個很好的開場白。
在網上認識的一些新人(甚至部分有三五年經驗的老鳥),在談論到面向對象\面向過程的時候,就陷入了誤區。
誤區一,面向對象和面向過程是非此即彼的對立方,相互不兼容。
誤區二,面向對象是種形而上的東西,“實際”開發中壓根沒用。
會產生這些誤區,本質上,都是不理解面向對象和面向過程是什么,陷入了教條主義,所以這里統一一起說明。面向對象(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語句分析成模型呢?
下篇文章會談談我在招聘時遇到的一些情況,希望會對正在找工作的朋友有所幫助。