WTF IOC?
java面试中经常会碰到如下情景:
问:“你用过Spring吗?”
答:“用过”
问:"Spring有啥特点“?
答:”IOC和AOP"
问:"AOP是啥?怎么实现AOP"?
答:"AOP就是面向切面编程,将像log, transaction, statistical这种本来分散在各个逻辑模块中的辅助代码抽象成单独的模块;然后将其注入(植入)到业务逻辑的代码中。(参考什么是AOP)。实现有动态代理,修改class字节码等
问:“什么是动态代理”
答:”......"
关于Spring中的IOC,谈到的较少。
IOC是控制反转,反转啥?在layer结构中,通常是上层调用下层的接口,上层依赖于下层,即调用者依赖于被调用者。而控制反转的意思就是使得上层不依赖于下层的接口,调用者来决定被调用者。
实现原则:
- 上层模块不依赖于下层模块,而是依赖于抽象接口;且该抽象接口而上层模块来定义
- 抽象层不依赖于具体的实现,具体的实现依赖于抽象;即下层模块来实现上层模块定义的接口
factory pattern | |
service locator pattern | jax-ws的provider, JDK中大量使用了此模式 |
构造函数注入 |
Spring |
setter注入 | Spring |
接口注入 | InterfaceInjection |
上下文查找 | JINI ? |
设计中的控制反转
在三层结构中,我们一般的设计顺序是
===========================================================================
User Case
|
DB Schema (Data layer)
|
Service Interface (Logic layer)
|
JSP/Javascript (Presentation Layer)
===========================================================================
根据上面的设计顺序,Service Interface 依赖于DB Schema,而JSP/Javascript 依赖于Service Interface,上层依赖于下层。
一种常见的说法是:service的接口定义并不依赖于DB层,但是:
1) service的实现直接依赖于Data层的DAO interface
2) DB schema设计的好坏直接影响着service的实现,间接的影响着service的接口
往上推之,Presentation Layer同样依赖于Service Interface.
采用控制反转的思路,系统设计顺序如下:
===========================================================================
User Case
|
JSP/Javascript (Presentation Layer)
|
Frontend API Contract (Contract Layer)
|
Service Interface (Logic layer)
|
DB Schema (Data layer)
===========================================================================
Prototype完毕,根据User case和Presentation Layer的code定义出前端API Contract, 所有jsp/javascript使用此接口。
后端逻辑层实现前端的Frontend contract API,控制反转,让后端依赖于前端。
两种设计顺序的区别在哪?
前者是以DB Schema作为稳定的data model,后者是以API(class)作为稳定的data model.
软件开发中有句话:
Requirements Are Like Water. They're Easier To Build On When They're Frozen
API(class)相比DB schema,更能直接的反映Frozen的requirements.
Contract API 和 Service API 的区别在哪?
Contract API 更加面向前端(web/web service),面向user case,一般是粗粒度的接口;
Service API 则更加面向实现,是较细粒度的接口;
适用场景
如果你有一套遗留系统,修修补补都相当费事--太多的technique debt.
现在打算开发一套新的系统,已有系统的组件/service又不想全部扔掉,毕竟有些组件还是相当有用。
于是你想和遗留系统的一部分组件进行对接。
一方面是新的系统/UI,一方面又是老的接口/模型。直接对接吗?
引入一层Adapter layer,定义新系统的contract api, 新系统前端在此API上进行开发。
后台是继续和遗留系统对接,还是彻底推翻,重新来过,all is hidden to upper layer.