项目包装组织

程序包是Java的基本概念,是您开始用该语言编程时偶然发现的第一件事。 作为一个初学者,您可能不太在意软件包的结构,但是随着您成为经验丰富且成熟的软件开发人员,您开始思考可以采取哪些措施来提高其效率。 有几个主要选项需要考虑,选择正确的选项可能不是一个显而易见的选择。 本文应该为您提供常用策略的概述。

我们为什么使用包裹?

从语言的角度来看,Java包提供了两个重要的功能,编译器可以利用它们。 最明显的一个是类的名称空间定义。 几个名称完全相同的类可以在一个项目中使用,只要它们属于不同的包即可将一个类与另一个类区分开。 如果您无法想象如果没有包,该语言将是什么样子,那么请看一下JavaScript世界中的模块化策略。 在ES2015之前,没有官方标准,而且名称冲突并非罕见。

第二件事是,程序包允许为项目的特定成员定义访问修饰符。 对于不同包的成员,可以限制或完全禁止类,接口或其成员(如字段和方法)的可访问性。

编译器首先使用这两个功能来执行语言规则。 对于干净的编码人员和软件技术人员而言,软件包的主要属性可能具有有意义的名称,该名称描述了软件包的用途和存在的原因。 对于编译器,这只是一个随机的char字符串,而对于我们来说,这是表达我们意图的另一种方式。

什么是包裹?

在官方Java教程中,我们可以找到以以下形式开头的定义:

包是一个命名空间,用于组织一组相关的类和接口。 从概念上讲,您可以将软件包视为类似于计算机上的不同文件夹。 您可以将HTML页面保留在一个文件夹中,将图像保留在另一个文件夹中,并将脚本或应用程序保留在另一个文件夹中。 (...)

第一句话强调软件包的组织目的。 但是,该定义没有说明应该将哪种关系类和接口视为一个单独的组。 这个问题向所有软件开发人员开放。 最近,肯特·贝克(Kent Beck)写了一条一般性建议,该建议也适用于本文中讨论的主题:

但是,就像上述包装定义中的“相关”一词一样,“相似”一词对不同的人可能具有完全不同的含义。 在本文的其余部分,我们将在软件包组织的背景下考虑可能的选项。

逐层包装

项目类之间最普遍公认的相似之处可能是他们的责任。 使用此属性进行组织的方法称为逐层打包或水平切片,实际上,其外观或多或少类似于下图。

如果您没有机会从事具有这种结构的项目,则可以在一些框架教程中找到它。 例如,Play框架建议在2.2版之前使用这种方法。 Angular.js的教程最初建议根据事物的职责将事物保持在一起。

他们改变了对主题的看法,并更新了教程,这一事实可能会让您想到什么。 但是在判断解决方案之前,让我们先看一下它的优缺点。

优点

考虑到分层体系结构是使用最广泛的体系结构,开发人员旨在将所选的体系结构反映在包结构中也就不足为奇了。 这种方法的长期流行影响了将结构应用到新项目中的决定,因为团队的新手更容易在他们熟悉的环境中采用他们。

在这样的应用程序中为新类找到合适的位置实际上是不费吹灰之力的操作。 该结构是在开发之初创建的,在整个项目的存在过程中始终保持不变。 这种简单性使得即使经验不足的开发人员也可以使项目保持秩序,因为结构易于理解。

缺点

有人说将所有模型类放在一个位置使它们更易于重用,因为它们可以与整个包一起简单地复制到另一个项目中。 但是真的是这样吗? 特定域模型的形状通常仅在项目内的有限上下文中有效。 例如,产品类别在购物应用程序中将具有与管理制造商订单的应用程序不同的属性。 而且,即使您要使用相同的类,也有必要将它们提取到每个应用程序中标记为依赖项的单独jar中。 即使存在于独立但相关的项目中,代码重复也会导致错误,因此我们应避免粘贴粘贴。

逐层打包方法的主要缺点是过度使用了公共访问修饰符。 现代的IDE默认情况下使用public修饰符创建类和方法,而不会强迫开发人员考虑使用更合适的选项。 实际上,在分层包组织中没有其他选择。 仅将存储库暴露给单个服务类就要求该存储库是公共的。 副作用是,项目中的所有其他类都可以访问该存储库,即使是不应该与其直接通信的层也可以访问该存储库。 这种方法鼓励创建无法维护的意大利面条代码,并导致包装之间的高度耦合。

如今,无论它们位于何处,在IDE中的已连接类之间进行跳转都非常简单,但为新功能添加新的类集需要更多的注意。 当类分布在多个目录中时, 仅通过查看代码很难评估功能的复杂性

一开始,我们说过程序包的名称应提供有关其内容的其他详细信息。 在逐包方法中,所有程序包都描述了解决方案的体系结构,但它们分别没有提供任何有用的信息。 实际上,在许多情况下,它们会复制其成员的类名中显示的信息。

按功能包装

在硬币的另一面,您可以围绕要素或领域模型构建类。 您可能已经听说过这种方法是垂直切片组织。 如果只使用水平切片,乍一看可能看起来有些混乱,但是最后这只是心态问题。 下图表示与上一段相同的类,但包装布局不同。

您可能不会只将所有左脚鞋放在一个地方,而就将另一只脚鞋放在同一只脚上。 您要成对穿着鞋子,因为那是您使用鞋子的方式。 同样,您可以查看项目中的类。

垂直切片的核心思想是将构建特定功能的所有类放在单个程序包中。 遵循此规则,您将获得一些收益,但同时也会面临一些负面后果。

优点

当所有要素类都放在一个程序包中时,public access修饰符更具表现力,因为它允许描述要素的哪一部分应由应用程序的其他部分访问。 在包内,您应该赞成使用package-private修饰符来改善模块化。 最好在IDE中修改默认模板,以避免创建公共类和方法。 公开一些东西应该是一个有意识的决定。 来自不同程序包的类之间较少的连接将导致更简洁,更可维护的代码库。

在水平切片中,程序包在每个项目中具有相同的名称集,而在垂直切片方法中, 程序包具有更有意义的名称,这些名称描述了它们的功能用途 。 仅通过查看项目结构,您就可以猜测用户可以使用该应用程序做什么。 该方法还表示要素之间的层次关系。 域的聚合根很容易识别,因为它们存在于软件包树的最低级别。 包结构记录了应用程序。

根据功能对类进行分组可以使包更小,更容易浏览。 在横向方法中,每个新功能都会增加图层包中的类总数,并使它们更难浏览。 在长长的类列表中找到有趣的元素将成为一种低效率的活动。 相反, 仅当扩展了功能时关注该功能的软件包才会增长 。 新功能在树的适当节点中接收其自己的包。

还值得一提的是垂直切片包装的灵活性。 随着微服务架构的日益普及,拥有已经按功能分割的整体应用程序绝对比将项目按层组织的项目更容易转换成单独的服务。 采用按功能打包的方法可以为应用程序的可扩展性增长做好准备。

缺点

随着项目的发展,软件包的结构需要更多的注意。 重要的是要了解,随着应用程序变得越来越复杂,软件包树会随着时间的推移而发展。 您有时会不得不停下来一会儿,并考虑将程序包移动到另一个节点或将其拆分为较小的节点。 结构的清晰度不是免费的。 团队负责保持其良好状态,并与该领域的知识保持一致。

了解领域是清洁项目结构的关键要素。 为新功能选择合适的位置可能会遇到问题,特别是对于团队新手来说,因为这需要了解应用程序背后的业务。 某些人可能会认为这是一种优势,因为这种方法鼓励团队成员之间共享知识。 向该项目介绍新的开发人员比较耗时,但可能会被视为一项投资。

混合方式

您可能认为四肢没有好处。 我们难道不能仅从两种方法中取最大的优点,并创造介于两个极端之间的新质量吗? 有两种可能的组合。 程序包的第一层被一层划分,要素是它们的子级,要素建立在顶层,层是它们的子节点。

第一种选择是您可能遇到的,因为它是增长到大尺寸包装的常见解决方案。 它增加了结构的清晰度,但是不幸的是,逐层封装方法的所有缺点都像以前一样适用。 最大的问题是,仍然必须在几乎所有地方都使用public修饰符才能连接您的类和接口。

使用另一个选项,我们应该问一个问题,该解决方案是否真的有意义。 按功能打包的方法支持层的组织,但它是在类级别而不使用package来完成的 。 通过引入其他级别的软件包,我们将失去利用默认访问修饰符的能力。 我们在结构上也没有获得太多简化。 如果功能部件包变得无法管理,最好提取一个子功能部件。

摘要

在开始新项目时,选择包结构是您必须要做的第一选择。 该决定会影响整个解决方案的未来可维护性。 尽管从理论上讲,您可以在任何时间点更改方法,但是通常,这种转移的总成本只会阻止这种转移的发生。 这就是为什么在开始时与整个团队花费几分钟并比较可能的选择尤为重要的原因。 一旦做出选择,您要做的就是确保每个开发人员都遵循相同的策略。 对于按功能打包的方法而言,这可能会比较困难,尤其是第一次完成时,但是好处列表绝对值得付出努力。

如果您对垂直切面有任何经验,并且想在主题上增加两分钱, 请随时在评论中分享您的想法 。 另外,请考虑与您的同事分享该帖子。 阅读您的讨论结果和对该方法的感受将是很棒的。

翻译自: https://www.javacodegeeks.com/2017/07/project-package-organization.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/349627.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NOIP模拟测试30「return·one·magic」

magic 题解 首先原式指数肯定会爆$long$ $long$ 首先根据欧拉定理我们可以将原式换成$N^{\sum\limits_{i1}^{i<N} [gcd(i,N)1] C_{G}^{i} \%phi(p)}\%p$ 根据欧拉函数是积性的得出$phi(54184622)phi(2)*phi(27092311)$ 然后$phi(27092311)27092310$ $phi(2)1$所以$phi(541…

python作用域的理解-理解Python的UnboundLocalError(Python的作用域)

今天写代码碰到一个百思不得解为什么会出错的代码&#xff0c;简化如下&#xff1a; 1 2 3 4 5 6 7 x10 deffunc(): ifsomething_true(): x20 print(x) func() 意图很明显&#xff0c;首先我定义了一个全局的x&#xff0c;在函数中&#xff0c;如果有特殊需要&#xff0c;就重新…

threadlocals_如何使用ThreadLocals射击自己

threadlocals它将很好地启动。 像大多数故事一样。 您会发现一个新概念&#xff0c;并对其功能感到惊讶。 然后突然装备了这把新锤子&#xff0c;一切开始看起来像钉子。 根据我们过去几个月的经验&#xff0c; java.lang.ThreadLocal真是一锤定音。 我想这全都归结为ThreadLo…

ASP.NET Core Web API

1.简单介绍 ASP.NET Core Web API 是 ASP.NET Core MVC 的一个功能。ASP.NET Core MVC 包含了对 Web API 的支持。可以构建多种客户端的 HTTP 服务。ASP.NET Core Web API可用于在 .NET Core 上构建 RESTful 应用程序。 框架包含对 HTTP 内容协商的支持&#xff0c;内置支持以 …

win8配置_《FIFA 20》PC配置公布 最低仅需i3+GTX660

EA公布了新作《FIFA 20》的PC配置需求&#xff0c;玩家最低仅需 i3-2100 GTX 660 显卡即可进行游戏&#xff0c;推荐配置则为 i3-6300T GTX 670 显卡&#xff0c;考虑到本作的逼真画面效果&#xff0c;这配置可以说是非常亲民&#xff0c;另外硬盘空间需要大约 50 GB。最低配…

Thymeleaf + Spring中的验证

总览 我们将要讨论的重要主题涉及空值&#xff0c;空字符串和输入验证&#xff0c;因此我们不会在数据库中输入无效数据。 在处理空值时&#xff0c;我们使用了Java 1.8中引入的java.util.Optional 。 0 – Spring Boot Thymeleaf示例表单验证应用程序 我们正在为一所大学构…

技术管理规划-设定团队的职能

背景 职责 团队是干什么的 初步自查团队 1.公司为什么给我团队&#xff1f;希望我产出什么&#xff1f;完成对除了c端健康领域探索的研发任务&#xff0c;产出技术类产品 2.团队存在的独特价值是什么&#xff1f;研发过lx健康这款基础app,研发能力强&#xff0c;熟悉硬件相关技…

开发转测试没人要_前端开发,测试,后端,该如何选择?

一般来说前端会比后端简单一些的&#xff0c;初学者或者转行可能考虑前端多一点&#xff0c;但是后端开发的薪水又比前端高一些&#xff0c;就是比较枯燥。前端开发我目前一直在自学前端&#xff0c;从网上找资料&#xff0c;然后听课&#xff0c;只要是对编程有兴趣&#xff0…

技术管理规划-如何设定团队的目标

团队管理规划有4个互相关联的要素&#xff1a; 职能目标团队路径在未来的3个月&#xff0c;6个月&#xff0c;1年&#xff0c;2年&#xff0c;3年&#xff0c;5年中&#xff0c;你希望带着你的团队抵达一个什么样的目的地&#xff0c;也就是团队的目标。 更加清楚目标意味着什么…

a8处理器相当于骁龙几_天玑820相当于骁龙什么处理器?天梯图秒懂联发科天玑820性能排名...

5月18日&#xff0c;联发科发布了全新 天玑820处理器&#xff0c;号称目前最强中端芯&#xff0c;受到不少网友关注。联发科近年来在手机CPU市场沉寂多年&#xff0c;今年异常给力&#xff0c;先后发布了天玑1000/L、天玑800等多款处理器&#xff0c;采用了全新的命名方式&…

hibernate 继承_Hibernate继承:每个类层次结构的表

hibernate 继承在本教程中&#xff0c;我们将了解如何在hibernate中实现继承。可以通过3种方式在hibernate中实现继承。在本文中&#xff0c;我们将看到其中一种&#xff0c;即每个类层次结构一个表。 Hibernate中的继承&#xff1a; Java是面向对象的语言&#xff0c;继承是J…

vue - cli 脚手架安装

一、 node安装 1&#xff09;如果不确定自己是否安装了node,可以在命令行工具内执行&#xff1a; node -v &#xff08;检查一下 版本&#xff09;&#xff1b; 2&#xff09;如果 执行结果显示&#xff1a; xx 不是内部命令&#xff0c;说明你还没有安装node , node 安装地址…

python人工智能_人工智能福利丨Python核心语法实战

Python已正式跻身成熟语言行列&#xff0c;成为整个互联网的基础性语言之一&#xff0c;并以肉眼可见的速度&#xff0c;在全球攻城略地&#xff1a;——牢牢占据TIOBE世界编程语言排行榜第四名&#xff0c;且保持上升趋势——国家级人工智能四大平台确立——正式纳入全国计算机…

.NET Core 单元测试

应用程序测试的类型很多&#xff0c;包括集成测试&#xff0c;Web 测试&#xff0c;负载测试等。在最底层的是单元测试&#xff0c;此测试可以测试单个软件组件或方法。单元测试一般只测试开发人员的代码&#xff0c;不应该测试基础结构普、问题&#xff0c;如数据库&#xff0…

是什么原因导致OutOfMemoryError?

发生以下情况之一时&#xff0c;可能会引发OutOfMemoryError &#xff1a; JVM耗尽了本机内存 Java堆内存不足 PermGen或Metaspace内存不足 JVM花太多时间试图收集垃圾 通常可以从错误消息中OutOfMemoryError出OutOfMemoryError的根本原因。 让我们研究每种情况的细节。 …

win10电脑开机密码忘了怎么办_Mac电脑忘记开机密码怎么办?Mac开机密码快速恢复方法...

Mac忘记开机密码怎么办&#xff1f;虽然小编觉得大多数人应该都不会Mac忘记开机密码&#xff0c;但是如果真的有人忘记了怎么办呢&#xff1f;小编这里教你们一种方法&#xff0c;可以帮你1分钟快速恢复Mac电脑忘记开机密码&#xff0c;感兴趣的朋友快跟着小编一起来看看吧&…

技术管理规划-如何规划团队的架构

管理规划的4个要素 1.职能【清楚自己团队的基本职责和使命】 2.目标【为团队设定清晰的目标】 3.团队【团队的架构规划】 4.路径 团队目标 根据团队目标去梳理团队 团队目标&#xff1a; 某个时间节点&#xff0c;团队发展成什么状态。 要点说明规模实际人数和预算人数分工团队…

win10家庭版调出组策略_利用powershell为win10家庭版安装组策略

虽然win10家庭版阉割了组策略管理器&#xff0c;但至少到1607版本时还可以用cmd脚本安装它。可是随后win10更新了几个大版本&#xff0c;不知为何&#xff0c;cmd控制台常常会有诡异的Bug&#xff0c;导致无法用老办法安装组策略管理器。为了彻底解决这个问题&#xff0c;不妨另…

Spring批处理CSV处理

总览 我们将讨论的主题包括使用Spring Batch进行批处理的基本概念&#xff0c;以及如何将数据从CSV导入数据库。 0 – Spring Batch CSV处理示例应用程序 我们正在构建一个应用程序&#xff0c;该应用程序演示Spring Batch处理CSV文件的基础。 我们的演示应用程序将允许我们处…

NOIP模拟测试28「阴阳·虎·山洞」

写这几个题解我觉得我就像在按照官方题解抄一样 阴阳 题解 将题目中给的阴阳看作黑色和白色 首先我们观察到最后生成图中某种颜色必须是竖着单调递增或竖着单调递减 类似这样 否则不满足这个条件 但合法染色方案必须满足任意两个同颜色格子之间的格子也必须是该颜色。 然后我们…