第十一章 系统
-
将系统的构造和使用分开。
系统的构造和使用是非常不一样的过程,在起始过程中构建应用对象,会存在相互结缠的依赖关系。
public Service getService() { if (service == null) service = new MyServiceImpl(...); // Good enough default for most cases? return service; }
这就是所谓延迟初始化/赋值。
好处:在真正使用到对象之前,无需操心这种架空构造,起始时间更短,而且永远不会返回null值。
坏处:我们也得到了MyServiceImpl及其构造器所需一切的硬编码依赖,不分解这些依赖关系就无法编译,即便在运行时永不使用这种类型的对象!
解决方法:
将全部构造过程搬迁到main或被称之为main的模块中,设计系统其余部分时,假设所有对象都已经构造和设置。
- 工厂: 有的时候应用程序也要负责确定何时创建对象。
设计模式——抽象工厂模式(Coming out...) 依赖注入DI:控制反转IOC在依赖管理中的一种应用手段。控制反转将第二权责从对象中拿出来,转移到另一个专注于此的对象,符合SRP。
JNDI是查找DI的一种部分实现。在JNDI中,对象请求目录服务器提供一种符合某个特定命名的服务。MyService myService = (MyService)(jndiContext.lookup("NameOfMyService"));
调用对象并不控制真正返回对象的类别(前提是实现了恰当的接口),但调用对象仍然主动分解了依赖。
Spring框架提供了最有名的Java DI容器。
-
扩容
EJB架构处理持久化、安全和事务的方法是预期面向方面编程AOP,AOP是恢复横贯式关注面模块化的普适手段。
AOP中,方面aspect的模块构造指明了系统中那些点的行为会以某种一致方式被修改,从而支持某种特定的场景。这种说明是用某种简洁的声明或编程机制来实现的。
以持久化为例,可以声明哪些对象和属性应当被持久化,然后将持久化任务委托给持久化框架。行为的修改由AOP框架以无损方式在目标代码中进行。 -
Java代理
适用于简单情况的,例如在单独的对象或类中包装方法调用。JDK提供的动态代理仅能与接口协同工作。
代码量和复杂度是代理的两大弱点,同时代理没有提供在系统范围内执行点的机制(AOP解决方案必须的)。 -
纯Java AOP框架
Spring AOP和JBoss AOP内嵌代理,从而能够以纯Java代码实现面向方面编程。
-
AspectJ的方面
通过方面来实现关注面切分的功能最全语言——AspectJ。
最佳的系统架构是由模块化的关注面领域组成,每个关注面均用Java对象实现,不同领域之间用最不具有侵害性的方面或类方面工具整合起来。这种架构能测试驱动,就像代码一样。
-
优化决策
模块化和关注面切分成就了分散化管理和决策。
拥有模块化关注面的POJO系统提供的敏捷能力,允许我们基于最新的知识做出优化的、时机刚好的决策。决策的复杂性也降低了。