在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. hdu 4432 数学杂题

    http://acm.hdu.edu.cn/showproblem.php?pid=4432 6分钟写的代码,一上午去调试,, 哎,一则题目没看懂就去写了,二则,哎,,恶心了.在坚持几天然后ACM退役 ...

  2. python 中的电子邮箱的操作

    通过python 的代码实现对email的操作,包括发送邮件和读取邮件. import poplib import smtplib from email.header import decode_he ...

  3. swich-----case语句的用法

    转:  http://xinzhi.wenda.so.com/a/1517927252619839

  4. 【TensorFlow-windows】(一)实现Softmax Regression进行手写数字识别(mnist)

    博文主要内容有: 1.softmax regression的TensorFlow实现代码(教科书级的代码注释) 2.该实现中的函数总结 平台: 1.windows 10 64位 2.Anaconda3 ...

  5. duplicate symbols for architeture arm64 linker command failed with code 1(use-c to see invocation)

    duplicate symbols for architeture arm64  linker command failed with code 1(use-c to see invocation) ...

  6. apktool + eclipse 动态调试APK

    用了会AndBug,尽管挺强大的可是作为习惯了OD.EDB作为动态调试工具的人,自然有些不习惯,于是乎寻求新的动态调试解决方式.但大多数都是NetBeans + apktool.想着还得多下一个IDE ...

  7. 用live555将内网摄像机视频推送到外网服务器,附源码

    最近很多人问,如何将内网的摄像机流媒体数据发布到公网,如果用公网与局域网间的端口映射方式太过麻烦,一个摄像机要做一组映射,而且不是每一个局域网都是有固定ip地址,即使外网主机配置好了每一个摄像机的映射 ...

  8. 超实用的 Nginx 极简教程,覆盖了常用场景(转)

    概述 安装与使用 安装 使用 nginx 配置实战 http 反向代理配置 负载均衡配置 网站有多个 webapp 的配置 https 反向代理配置 静态站点配置 搭建文件服务器 跨域解决方案 参考 ...

  9. CentOS 更换 usr 挂载分区

    由于之前挂载在/usr目录的分区空间过小,无法安装更多需要的软件,现在添加一块硬盘重新挂载在/usr目录,并将之前/usr 目录下的内容(包括权限.连接等)完整拷贝到新磁盘分区的/usr目录. 操作系 ...

  10. Chain of Responsibility Pattern

    1.Chain of Responsibility模式:将可能处理一个请求的对象链接成一个链,并将请求在这个链上传递,直到有对象处理该请求(可能需要提供一个默认处理所有请求的类,例如MFC中的Cwin ...