(读书笔记)Java应用架构设计-模块化模式与OSGi

本书主要模块化模式的好处、模块化方法与模式、OSGi简单使用等内容,分3大部分:

第一部分介绍了模块化概念,为什么要模块化,以及一些模块化要考虑的东西,如模块粒度,依赖关系,重用性灵活性等。

第二部分介绍模块化的一些模式,采用了GoF设计模式的格式(模式名称、模式表述、图示、描述、多种实现、效果、样例、小结),看着有些乱,但是收获不少。

第三部分介绍OGSi结合Java如何使用,以及如何模块化现有系统。Java中无法直接模块化(Java SE模块化功能Jigsaw被推迟到了Jave SE 9),因为你可以随时访问其他模块类中的任意public方法,想要强制性模块化,只允许访问发布的方法,可以使用OSGi框架。

这里模块化的概念和组件化相似,可部署、可管理、原生可重用、可组合、无状态的软件单元,对外提供了简介的接口。在Java中,最适合模块化的单元就是Jar文件。

代码层面我们关注的太多了,熟练的开发人员现在很少争论使用模式的好处,也不再识别哪个模式适合当前需要,因为都能够本能地使用各种设计原则和模式,从GoF的设计模式到衍生出的设计原则,现在很多原则已经几乎变成了本能,如“优先组合而不是继承”、“面向抽象而不是面向实现”。

但是只考虑类级别的设计,那么不管设计的多么漂亮,都不会代码预期的收益。因为现有的设计原则和面向对象开发模式不能帮助管理大型软件系统的复杂性,因为他们解决的是不同的问题。

架构的目标是尽可能减少变化的影响和成本。模块化通过填补高层架构组件以及底层代码之间的空白,帮助我们实现这个目标。

通用的原则:

1、接口要更接近使用它们的类,而远离实现它们的类。

2、异常应该接近抛出它们的类或接口,而不是接近捕获异常的模块

模块化的一些模式和方法,大体的思想原则和类设计的原则相似,很多方法都是基于“依赖抽象而非依赖实现”这个原则的。

1、悖论,粒度越小的模块越灵活,管理起来也就越复杂,如何在灵活性和管理复杂度两者间取舍。最大化重用使得可用复杂化,粒度越小的模块重用性越高,可用性越低,也就是越不方便用,如何在重用性和可用性之间取舍。虽然没有绝对的结论,但是大方向上有了结论。

2、稳定性,具有大量被依赖的模块应该是很稳定的,也就是很少发生变化,变化带来的影响更大。确保模块稳定性最好的方式就是将其转换为抽象模块。具有大量依赖其他模块的模块,是不稳定的,很容易进行变化,易于使用,但是不容易测试(因为依赖其他模块太多),最好的方式应该依赖抽象模块。

3、模块等级必须分等级,模块必须等级化,高等级依赖低等级,低等级不能依赖高等级,低等级不能有太多依赖,等级越低的模块应该越稳定,不稳定的模块应该放到高等级。

4、模块重用,类级别重用不能跨应用(比如工具类),而模块级别重用可以跨应用。

软件开发初期,需求处于不断变化之中,模块粒度应该大,易于管理和使用。随着识别出需求变化的重点,找出了可重用的地方,较大模块应该拆分成较小的、更易于重用的细粒度模块。软件开发初期就试图定义较小的细粒度模块是很困难的,因为只能猜测重用点在哪,通常是失败的。

5、模块内聚:高内聚的模块易于理解、维护和重用。影响模块内聚的因素有2点,一个是类变化的频率,另一个是类的可重用性。软件开发初期应基于变化频率构建模块,因为系统不稳定,系统稳定后,应基于重用构建模块。也就是说软件前期很难创建高内聚的模块,随着系统稳定,开发团队应该重新组织系统以确保模块都是内聚的。

6、模块依赖,高等级模块单向依赖低等级模块是最好的,最不好的就是循环依赖,这里提供几个方法消除依赖。单向依赖时,比如低层级模块依赖高等级模块了,解决方法:

反转关系:稳定模块A依赖B的部分抽象接口,依赖自己接口,B去实现这个接口,达到B依赖A的反转。

消除关系:抽象出模块C,A依赖C(A使用C),B依赖C(B实现C),达到A和B不依赖关系。

两个模块有循环依赖关系,通常就是一个模块,应该合并。如果不合并就要打破这种关系,解决办法有:

上移:将依赖成因上移到高等级模块,创建一个更高等级模块,抽象出最低等级模块依赖关系,达到单向依赖。

下移:将依赖成因下移到高等级模块,与上移相反,创建一个更低等级模块而已。

回调:定义一个抽象体,将其注入到模块中,达到单向依赖甚至消除依赖个可能。

其实通过反转和消除,也能解决循环依赖,根据具体使用场景选择吧。

7、模块应该轻量级,不依赖容器和运行环境,可单独部署使用最好。

8、模块管理,如果不打算重用某个模块,那么依赖管理的动力就是可维护性,如果想要可维护性提高,就要关注可测试性(越容易测试、则越容易维护)。最好在开始的时候尽可能简单并随着需求出现增强模块,而不是开始的时候基于预测创建复杂模块。

9、默认实现,模块应该有一个默认实现,如果没有任何实现,模块实际上只是一个规范。(比如默认实现就是插件式开发的一种方式。)

10、依赖抽象就必须保证获取实现类的实例时,不能new,常用方法有3类,工厂方法、动态创建(如Spring注入)、OSGi μService。

11、如果依赖抽象体的所有类都在一个模块中,那么将这些类和抽象体放在同一个模块中。如果依赖抽象体的所有类位于多个模块中,那么将抽象体放到一个单独的模块中。

最后说说为什么要用OGSi来强制模块化,“优雅的理念设计在实现的过程中很快就可能变得一团糟,没有开发人员能够理解最初的高级愿景要如何展现在代码中。尽管你很清楚预期的模块关系是什么,但是不想要的依赖依然会进入你的应用。”真实情况确实如此,不论什么原因,最终的结果都是一样的,就是我们的代码越来越差,模块关系混乱了,代码可以定期重构,但是模块重构的代价比较大,OGSi有个办法强制解决,“等级化构建会强制你思考模块依赖...因为任何新的依赖都需要修改构建脚本,所以对于开发人员,定义新的依赖必须要慎重。等级化构建使引入新的依赖要做更多的事情。”

刚参加工作时,开发过程中很多功能如果使用前必须配置好几处的配置文件,当时觉得非常麻烦,一直没找到很有说服力的理由,读完本书总算发现了:

1、配置复杂通常代表着灵活程度高,越灵活使用起来越麻烦,越灵活越复杂,很多事都这样,没有完美,只有当前最适合的平衡点。

2、复杂的配置,让开发人员更慎重,如果没有这么复杂的配置,开发人员会随便乱写,最终造成系统极其糟乱。

3、复杂的配置,集中于一处或一类地方,也方便审查梳理。

最后,本书的模块化设计思想让我收获颇多,目前还不是特别流行,希望未来会变的非常流行,未来的OSGi也将会带来生态系统(Eclipse就是成功基于OSGi的生态系统)。

时间: 2024-10-23 11:54:05

(读书笔记)Java应用架构设计-模块化模式与OSGi的相关文章

(札记)Java应用架构设计-模块化模式与OSGi

本书主要模块化模式的优点.模块化方法与模式.OSGi简单使用等内容.分3大部分: 第一部分介绍了模块化概念.为什么要模块化,以及一些模块化要考虑的东西,如模块粒度,依赖关系,重用性灵活性等. 第二部分介绍模块化的一些模式.採用了GoF设计模式的格式(模式名称.模式表述.图示.描写叙述.多种实现.效果.例子.小结),看着有些乱,可是收获不少. 第三部分介绍OGSi结合Java怎样使用.以及怎样模块化现有系统.Java中无法直接模块化(Java SE模块化功能Jigsaw被推迟到了Jave SE 9

Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle

Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle 1. 主键1 2. uniq  index2 3. 检查约束 (Check Counstraint) 对该列数据的范围.格式的限制(如:年龄.性别等)2 4. 默认约束 (Default Counstraint) 该数据的默认值2 5. trigger2 6. 外键机制  参照完整性:2 7. 断言约束:不必与特定的列绑定,可以理解为能应用于多个表的

UML笔记1---结合架构设计用对象建模

UML笔记1---结合架构设计用对象建模 一.UML的视图和图 视图,只是表达系统某一方面特征的UML建模组件的子集:视图被划分成三个视图域:结构分类.动态行为和模型管理. ---结构分类,描述了系统中的结构成员及其相互关系.类元包括类.用例.构件和节点.类元为研究系统动态行为奠定了基础.类元视图包括静态视图.用例视图和实现视图. ---动态行为描述了系统随时间变化的行为.行为用从静态视图中抽取的瞬间值的变化来描述.动态行为视图包括状态机视图.活动视图和交互视图. ---模型管理说明了模型的分层

读书笔记-----Java并发编程实战(一)线程安全性

线程安全类:在线程安全类中封装了必要的同步机制,客户端无须进一步采取同步措施 示例:一个无状态的Servlet 1 @ThreadSafe 2 public class StatelessFactorizer implements Servlet{ 3 public void service(ServletRequest req,ServletResponse resp){ 4 BigInteger i = extractFromRequest(req); 5 BigInteger[] fact

读书笔记2013-2 Linux内核设计与实现A

<Linux内核设计与实现> 简介 这本书不是想Linux源码剖析那样一行行分析Linux源代码的书,而是从Linux历史,Linux哲学,Linux设计原理和原则,计算机硬件相关知识,编译安装内核实战等多方面多角度讲述和Linux相关的方方面面.从中学到的更多的不单内核的源代码,而是Linux的哲学.建议所有从事Linux相关工作的猿都要读一下,读完之后,很多东西都变得容易理解,知其然,知其所以然.如果没有读过<深入理解计算机>类似的图书,建议和<深入理解计算机>一起

模块化模式与 OSGi

Android 模块化探索与实践 一.前言 万维网发明人 Tim Berners-Lee 谈到设计原理时说过:"简单性和模块化是软件工程的基石:分布式和容错性是互联网的生命." 由此可见模块化之于软件工程领域的重要性. 从 2016 年开始,模块化在 Android 社区越来越多的被提及.随着移动平台的不断发展,移动平台上的软件慢慢走向复杂化,体积也变得臃肿庞大:为了降低大型软件复杂性和耦合度,同时也为了适应模块重用.多团队并行开发测试等等需求,模块化在 Android 平台上变得势在

Head First Design Pattern 读书笔记(3)装饰者模式

Head First Design Pattern 读书笔记(3) Decorator Pattern 装饰者模式 Decorator Pattern 类图 定义 装饰者模式:通过让组件类与装饰者类实现相同的接口,装饰类可以在不修改原有组件类的情况下,动态拓展组件类的新功能,并且可以无限拓展下去. 几个OO的原测 类应该对修改关闭,对拓展开放.–>"开闭原则",即尽量不要修改已经在用的类,而通过继承的方式去拓展类的新功能. 设计类时应当尽量考虑不修改原有的代码.–>同&qu

[笔记]《游戏架构设计与策划基础》第三章 游戏概念及原型设计

概念设计的过程:产生创意.加工创意和创建游戏概念设计文档. 3.1 创意的来源 (1)大胆设想 (2)利用现有的娱乐资源 (3)利用现有的游戏体系 (4)收集创意 3.2 加工创意 (1)合成--需要考虑如何将两个概念融合而成一款游戏,带给玩家新的游戏体验. (2)共鸣--含有协作的意思,它使故事和主题内容对游戏玩家能够产生更加深刻的影响. 3.3 游戏概念设计文档 一般包括以下要素的部分或全部:      标题--游戏的名称.      平台--游戏适合的平台.      种类--游戏的种类.

读书笔记-敏捷软件开发 原则,模式与实践

看了一下夹在书中的发票,2010年在当当网购买的. 断断续续的也看过几次,一直没有看完过. 这次试着写写读书笔记.看看能不能坚持住.