设计层次跟实现层次并不是完全统一的(2009-03-01 23:01)

设计层次和实现层次并不是完全统一的(2009-03-01 23:01)
设计层次是从大处着眼,处理软件的结构性问题。设计模型需要忽略实现的细节。

而实现时统满了细节,自然的设计模型,可能在实现时的细节是不自然的。

比如:使用strusts1.2 对公司的信息进行组合查询,公司的类型在设计时规定以整型来代表,分为三类,对应的整型值为:1 2 3。查询接口直接以组合查询条件作为参数,这里如果用户没有输入某个条件,则忽略这个条件(这种方式不能查询某字段为空的记录)。这时在设计时通常就把公司的类型作为接口的整型参数,这里还需要表达不用这个条件时的值,通常对整型用-1代表忽略对应的条件。这时就存在这样的问题,在action里得到的界面上传来的值,通常是字符串,对于字符串通常是用null和空串代表忽略的。这时对于公司类型条件,就不得不进行协议转换,增加了使用查询接口的工作量,但是增加的都是细节。如果把公司类型参数作为字符串型,则会方便action使用查询接口,可是这样必然使得接口不清晰,使实现和设计模型不附。

这里的数据类型转换是实现的细节问题,在设计接口时应不应该考虑实现的细节呢?要不要为了便于实现而把接口的公司类型参数调整为字符串型呢?

对于公司类型参数有如下三种选择:

1 int                       -1代表忽略              需要协议转换,注意:boolean无法表达忽略

2 Integer               null代表忽略            需要协议转换,表达上更一致一点。

3 String                 null代表忽略            不需要协转换,破坏了接口的语议。使软件的整体接口设计策略不统一,比如:String=>Date也存在类似的问题,而这个转换应该发生在action中,接口在整体上,设计方式应该是统一的。放便了action中对接口的使用。但如果方法会被多处使用,同样存在反向的协议转换的需要。

目前,我能想到的就这么多,我不是一个纯化主义者,因此在这三种方案之间,我难以做出先择。目前我认为,应该以明确接口为首要准则,所以应使用1或2。但是对于1的形式来说,是不能做为一个接口设计的一般要求的,因为对于boolean类型无法表示“忽略”的情况。对于2呢,也不能作为接口设计的一般要求,因为有些时候,接口上的查询参数用基本数据类型是最确切的,比如:查询员工数据时的一个条件为“只返回受过奖励的员工”,那么这个条件就只有两种情况,应该使用boolean最好。

因此这里总结一下查询参数的设计方法如下:
我想第1和第2都是可行的,2用null来表达忽略应该好一些。对于3,要注意,String是界中数据的基本形式,不要因为从界面来的数据是String类型的就把接口的参数也定义成String类型的,模型的接口应该和接口的语义一致。

对于一些脚本语言其实不存在这样的问题,默认就是第三种方案,比如:php。