封装是指将数据与操作该数据的方法捆绑在一起。而信息隐藏是隐藏实现细节。封装和信息隐藏常常出现在一起,以致于它们几乎成了同义词,在一些上下文,它们也的确是同义词。封装提供了边界,而信息隐藏则屏蔽复杂实现,这两个常常出现在一起,我们在封装的同时使用信息隐藏。
那继承呢? 继承源于共性,不同的对象之间具备共性,那我们建模的时候就可以将共性抽出,将其当作父类,从而减少代码冗余,增强代码的简洁性。那多态呢?在《The Java™ Tutorials》(这个Java官方出的教程)在介绍多态的时候是这么介绍的:
The dictionary definition of polymorphism refers to a principle in biology in which an organism or species can have many different forms or stages. This principle can also be applied to object-oriented programming and languages like the Java language. Subclasses of a class can define their own unique behaviors and yet share some of the same functionality of the parent class.
多态性的字典定义是指生物学中的一个原则,其中一个生物体或物种可以有许多不同的形式或阶段。这一原则也适用于面向对象编程和Java语言等语言。类的子类可以定义自己独特的行为,但也可以共享父类的一些相同功能。
多态进一步细分,功能(函数)重载与对象重载,函数重载就意味着函数在拥有不同的类型的参数或者不同数量参数的时候拥有相同的方法名。而对象则与继承有关,一个父类可以有多个子类,子类可以复用父类的行为,当然也可以进行重写,借助多态可继承我们重用已有的代码。
目前的问题
在《让我们来聊聊前端的工程化》我们已经讨论过了软件危机,这里再回忆一下:
1970年代和1980年代的软件危机。在那个时代,许多软件最后都得到了一个悲惨的结局,软件项目开发时间大大超出了规划的时间表。一些项目导致了财产的流失,甚至某些软件导致了人员伤亡。同时软件开发人员也发现软体开发的难度越来越大。在软件工程界被大量引用的案例是Therac-25的意外:在1985年六月到1987年一月之间,六个已知的医疗事故来自于Therac-25错误地超过剂量,导致患者死亡或严重辐射灼伤。
鉴于软件开发时所遭遇困境,北大西洋公约组织在1968年举办了首次软件工程学术会议,并于会中提出"软件工程"来界定软件开发所需相关知识,并建议"软件开发应该是类似工程的活动"。软件工程自1968年正式提出至今,这段时间累积了大量的研究成功案例,广泛地进行大量的技术实践,借由学术界和产业界的共同努力,软件工程正逐渐发展成为一门专业学科。
关于软件工程的定义,在GB/T11457-2006《消息技术 软件工程术语》中将其定义为"应用计算机科学理论和技术以及工程管理原则和方法,按预算和进度,实现满足用户要求的软件产品的定义、开发、和维护的工程或进行研究的学科"。
Therac-25: 是加拿大原子能有限公司(AECL) 在 Therac-6 和 Therac-20 装置之后于 1982 年生产的一种计算机控制的放射治疗机。它有时会给患者带来比正常情况高数百倍的辐射剂量,导致死亡或重伤
那为了解决软件危机中的软件开发速度、软件开发越来越复杂,构建软件的编程语言引入了面向对象,着眼于强化于代码的重用性、可维护性。Java中我们如何复用别人的代码呢? 如果在一个项目里面,我们通常会直接用,即在需要用到的类和方法里面写类名即可,IDE会帮我们自动引入。如果是第三方提供我们是通过jar这样的形式来引入,JDK为我们提供的类库,像HashMap、ArrrayList,这些都放在JDK中的一个jar中。任何一个Java文件总是有一个public class,如果我构建了一个类库,只对外提供一些类和接口该怎么做呢,在JDK 8之前包含JDK8是做不到的,原因在于反射,私有的方法我照样可以通过反射来访问。这为后期的维护带来了很大的麻烦,例如我原先的实现不够好,对外提供的类和接口我不做改动,但我想改动不对外提供类的实现,但改动了不确定有没有人用,别人在升级的时候可能就会问候我两句。再有JDK的jar也太过臃肿,太过庞大了, 只有相当粗略的划分, JDK 8大致提供的jar如下:
- rt.jar 、charset.jar 、ckdrdara.jar、dnsns.jar、jaccess.jar、jce.jar、jfr.jar
- jsse.jar、localedata.jar、management.jar、access-brige-64.jar、sunec.jar
- sunjce.jar、sunjce_provide.jar、sunmscapi.jar、sunpkcs11.jar、zipfs.jar、nashron.jar
这些jar我们好像都不认识,其实rt.jar是我们的老熟人,集合类、并发集合都在里面,所以rt.jar在JDK8有60m大小,Nashron是一个JavaScript引擎。所以如果我们开发服务端应用,我们不需要JavaScript引擎,在安装JDK8的时候这个也会被安装进去,包括AWT、SWING,尽管我们用不到,那我们自然提出这样一个问题,我们能否按需定制自己所需的JDK呢,让打的jar变的小一点。这也就是模块化的缘起。JDK 的模块来自Project Jigsaw,这个项目的主要目标为:
- 使开发人员更容易构建维护库和大型应用程序。
- 提升Java SE平台的安全性和可维护性,特别是对于JDK
- 让Java SE 和 JDK 能够以更小的体积用于小型设备和云部署。
模块系统
那么关于模块系统我们自然而然就有以下三个问题:
- 模块系统的目标?
- 什么是模块?
- 该如何使用模块?
模块系统的目标
- Reliable configuration(依赖可配置):
模块化让JVM可以识别依赖关系,不管是在编译器还是运行时。系统根据这些依赖关系来确定程序所需要依赖的模块。
- Strong encapsulation (强封装)
模块的包只在模块显式的将其导出才可用,即使某个将其导出(export),另一个模块如果不声明需要(对应require), 那么这个模块也不能使用导出模块的包。这样就提升了Java平台的安全性, 因为模块潜在的访问者更少,模块可以帮助开发者提出更简洁、更合乎逻辑的设计。
- Scalable Java platform (Java平台的可扩展性)
以前,Java平台是由一个大量包组成的整体,这给后续的开发和维护带来了相当大的挑战,现在Java平台被模块化为95个模块(这个数字可能随着Java的发展而改变)。现在您就可以自定义运行时,让您的程序可以在运行时拥有仅它需要的模块。例如,如果您只想做服务端开发,不想要GUI模块,那么在打包的时候,就可以不需要。从而显著的减少运行时大小。
这里我的解读是我们平时会讲职责单一,这一概念也应当不仅仅局限于我们的类、方法,同时也应当上升到jar。就rt.jar来言,这个jar太大了,集合类、并发框架、awt和swing的部分类都在其中。rt是run time的缩写,但是对于服务端的运行时一般不会用到这些类,从职责单一角度,awt和swing应当被划分到桌面的jar里面,现在放在rt.jar里,这让rt.jar显得十分庞大。对此我想到的一个比喻是,rt.jar像是一个杂物间,放了太多不应该放的东西。现在模块化对其进行了分类整理,rt.jar被拆分。下面是JDK 9之后的模块化图:
https://www.bilibili.com/video/BV1hK4119739
https://www.bilibili.com/video/BV1fv4y197YR
https://www.bilibili.com/video/BV15d4y1s7pr
https://www.bilibili.com/video/BV1oV4y1A7Qr
现在最为核心的是java.base,职责更为单一,每个模块都声明了自己依赖于哪些模块,原本这些可能放在文档中,现在这些依赖关系进入了代码。让JDK平台的可维护性得到了进一步的加强。上面这幅图来自GitHub的module-graph。
标签:rt,Java,JDK,jar,笔记,软件工程,模块 From: https://blog.51cto.com/u_13971202/5928546