用户基本信息的展现.产品须要有3个页面,分别面向的是消费者,运营,商家。因此3个页面的内容不是彻底同样的,而且有些内容是敏感的,可是他们的数据源是一致的。如今一共有四种解决方案:性能
分别写三个DAO
,根据页面需求返回不一样的数据设计
分别写三个service
,调用的是同一个DAO
,在service
中根据页面需求进行裁剪code
分别写三个组合层的接口,组合层调用的是同一个service
,而后在组合层根据页面需求进行裁剪接口
根据页面需求在controller
层对字段进行裁剪,调用的是同一个组合层开发
处理方式:在这个场景中,我一开始选择的处理方式是第三种,当时是基于公有转换代码的重复利用。可是站在抽象层次和接口的复用率角度应该第四种才是最合理的产品
有两个接口ServiceA.methodA()
和ServiceA.methodB()
,如今在组合层须要同时调用methodA()
和methodB()
来组装成一个新的实体。有两种方案能够解决:电商
在ServiceA
中从新写一个方法methodC()
给组合层使用service
在组合层本身写私有方法或者Utils方法去组装实体方法
电商系统商品详情页,有放入购物车和直接购买两个选项,直接购买选项也会放入购物车,可是和实际上的购物车是分离的。实现方式有三种:时间戳
前台经过传递一个时间戳t
来标示是放入购物车仍是直接购买,若是t=0
就是放入购物车,若是是t!=0
就是直接购买。购物车相对应也有两个接口Service.MethodA()
,Service.MethodB(long t)
,分别对应放入购物车和直接购买(这里的t
对购物车模块有特殊做用)
购物车值提供一个接口Service.Method(long t)
,在购物车模块中根据t
本身去判断是直接购买仍是放入购物车
前台传一个标示flag
表示是否直接购买,购物车提供两个接口Service.MethodA()
,Service.MethodB()
(这里去除了购物车模块对时间戳t
的依赖)
一个Service.Method()
返回了一个A
实体.如今有新的需求发现A实体返回的字段太少了,得多加一个字段。这个时候有两种处理方式:
直接在A
实体中添加
从新写一个接口返回的是实体B
,B
比A
要多一些字段
场景一和场景四表明的是各个层次如何定义本身的接口,以及是否须要定义一些特殊的接口,目前感受:在开发以前须要评估一下每一个接口的调用频率,是否须要定义一些单独的返回接口(除非明显感受有性能问题,一些接口可能返回一些大字段,而这个大字段在不少场景下是用不到的,或者由于接口须要返回一个字段而须要作不少消耗性能的工做,或者接口返回50个字段,而我只须要一个字段,而且这种场景不少。这些能够单独定义一些特殊接口),而其它的能够共用的接口尽可能共用,当后期在线上运行的时候发现某个调用确实由于接口太粗而致使了性能问题,那么能够从新拎出一个接口。
场景二表明的是,一开始定义的接口粒度很小,可是后期需求发现上层调用须要用到一个粒度更加大的接口,这个时候须要分析这种场景是否不少,若是发现不少,就能够单独为其开一个新的接口,新的接口调用内部的粒度小的接口来组合成一个新的返回实体(假设这些实体分属不一样的表),这种至关于在原来的层次中间加了一层层次更加高的抽象,若是之后这种越来场景越多(小粒度组成大粒度),这层就会变得愈来愈明显。
场景三,表示的是模块须要给上层提供什么样子的接口,一些模块内部的信息或者其它东西就不要暴露给上层调用者,好比方法一合方法三的不一样之处就是是否须要知道内部的Key是要用时间戳来表示的,因此在设计接口的时候须要同时站在使用者的角度和设计者的角度考虑,尽可能不要把内部的实现细节暴露给使用者(好比上述的例子,若是之后不是以时间戳来当key的话,那么这个接口传入的时间戳就显得毫无心义的),固然也不是必定要遵循这个原则,当接口因为你传入一个参数而致使性能出现了质的飞跃,那么这些反设计的接口仍是容许存在的