在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有个办法强制解决,“等级化构建会强制你思考模块依赖...因为任何新的依赖都需要修改构建脚本,所以对于开发人员,定义新的依赖必须要慎重。等级化构建使引入新的依赖要做更多的事情。”

Java应用架构设计模块化模式与OSGI摘录的更多相关文章

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

    本书主要模块化模式的优点.模块化方法与模式.OSGi简单使用等内容.分3大部分: 第一部分介绍了模块化概念.为什么要模块化,以及一些模块化要考虑的东西,如模块粒度,依赖关系,重用性灵活性等. 第二部分 ...

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

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

  3. 模块化模式与 OSGi

    模块化模式与 OSGi Android 模块化探索与实践 一.前言 万维网发明人 Tim Berners-Lee 谈到设计原理时说过:“简单性和模块化是软件工程的基石:分布式和容错性是互联网的生命.” ...

  4. JAVA师徒架构班 - 带徒模式

    (转: http://www.jeecg.org/forum.php?mod=viewthread&tid=2291&extra=page%3D1&page=1) 一个程序员技 ...

  5. java网站架构设计

    涉及到的技术及工具:java,springmvc,ibatis,freemarker,mysql,mongdb,memcached,ehcache,maven. 一个网站不可能说一开始就是要设计一个能 ...

  6. 15套java互联网架构师、高并发、集群、负载均衡、高可用、数据库设计、缓存、性能优化、大型分布式 项目实战视频教程

    * { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩 展 ...

  7. 2017最新技术java高级架构、千万高并发、分布式集群、架构师入门到精通视频教程

    * { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩展. ...

  8. Java开发架构篇:DDD模型领域层决策规则树服务设计

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 在上一章节介绍了领域驱动设计的基本概念以及按照领域驱动设计的思想进行代码分层,但是仅 ...

  9. Swing程序最佳架构设计—以业务对象为中心的MVC模式(转)

    前言: 我打算写一系列关于Swing程序开发的文章.这是由于最近我在做一个Swing产品的开发.长期做JavaEE程序,让我有些麻木了.Swing是设计模式的典范,是一件优雅的艺术品,是一件超越时代的 ...

随机推荐

  1. 写一个dup2功能同样的函数,不能调用 fcntl 函数,而且要有出错处理

    实现的时候用到系统原来的dup函数 // mydup2.c // 2015/08/17 Lucifer Zhang version1.0 // write my own dup2 function / ...

  2. 安装odoo 9实录

    安装Ubuntu,省略 下载 odoo源码 使用 git 下载源码 mkdir /opt/openerp/server cd /opt/openerp/server git clone https:/ ...

  3. .Net Core表单验证

    验证 attributes: Attributes Input Type [EmailAddress] type=”email” [Url] type=”url” [HiddenInput] type ...

  4. 【MatConvNet】配置GPU

    参照大神的方法:http://www.th7.cn/system/win/201603/155182.shtml 第一步:需要安装cuda.VS2013:cuda默认路径,注意cuda版本和GPU要匹 ...

  5. 图像处理之opencv---mat、cvmat、IplImage之间的转换

    一.Mat类型:矩阵类型,Matrix.  在openCV中,Mat是一个多维的密集数据数组.可以用来处理向量和矩阵.图像.直方图等等常见的多维数据. Mat有3个重要的方法: 1.Mat mat = ...

  6. objective-c中#import和@class的差别

    在Objective-C中,能够使用#import和@class来引用别的类型, 可是你知道两者有什么差别吗? @class叫做forward-class,  你常常会在头文件的定义中看到通过@cla ...

  7. oracle 日志归档设置

    下面介绍下oracle的日志文档操作 归档日志作用:归档日志(Archive Log)是是处于非活动(INACTIVE)的状态的重做日志文件的备份,它对ORACLE数据库的备份和恢复起至关重要的作用. ...

  8. 【BZOJ4956】lydsy七月月赛 I 乱搞

    [BZOJ4956]lydsy七月月赛 I 题面 题解:傻题,Floyd传递闭包即可~ #include <cstdio> #include <cstring> #includ ...

  9. asp.net mvc4 之Webapi之应用客户端访问服务器端

    一.说明 客户端项目类型设计为:winform(winform窗体项目类型) 服务器端项目类型设计为:asp.net mvc4  webapi 在这里分为项目运行和调试两种情况讨论: 运行: 这种情况 ...

  10. File syncing and sharing software with file encryption and group sharing, emphasis on reliability and high performance.

    http://seafile.com/ showdoc haiwen/seafile: File syncing and sharing software with file encryption a ...