基础知识漫谈(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语句分析成模型呢?

 

下篇文章会谈谈我在招聘时遇到的一些情况,希望会对正在找工作的朋友有所帮助。

posted @ 2016-06-29 14:55  荒土  阅读(6983)  评论(2编辑  收藏  举报