- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java 你知道什么是耦合、如何解(降低)耦合由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
耦合性(Coupling),也叫耦合度,是对模块间关联程度的度量。模块间的耦合度是指模块之间的依赖关系,包括控制关系、调用关系、数据传递关系。模块间联系越多,其耦合性越强,同时表明其独立性越差( 降低耦合性,可以提高其独立性).
假如:当我去new一个对象的时候,而这个对象不存在,这个时候程序会报编译时异常,也就意味着程序连运行都运行不了,我们可以理解为他们的耦合度较高.
我们可以利用Java的反射技术,通过类定名,来进行反射创建对象,这个时候我们可以成功的避免编译时异常,并且保证了项目在这个时候还能正常运行.
在实际开发中我们可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象创建出来并存起来。在接下来的使用的时候,直接拿过来用就好了。那么,这个读取配置文件,创建和获取三层对象的类就是工厂.
早期我们的 JDBC 操作,注册驱动时,我们为什么不使用 DriverManager 的 register 方法,而是采用 Class.forName 的方式?
1
2
3
4
5
6
7
8
9
10
11
|
public
class
JdbcDemo1 {
public
static
void
main(String[] args)
throws
Exception {
//1.注册驱动
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName(
"com.mysql.jdbc.Driver"
);
//2.获取连接
//3.获取预处理 sql 语句对象
//4.获取结果集
//5.遍历结果集
}
}
|
我们的类依赖了数据库的具体驱动类(MySQL),如果这时候更换了数据库品牌(比如 Oracle),需要修改源码来重新数据库驱动。这显然不是我们想要的.
当是我们讲解 jdbc 时,是通过反射来注册驱动的,代码如下:
Class.forName("com.mysql.jdbc.Driver");//此处只是一个字符串 。
此时的好处是,我们的类中不再依赖具体的驱动类,此时就算删除 mysql 的驱动 jar 包,依然可以编译(运行就不要想了,没有驱动不可能运行成功的)。同时,也产生了一个新的问题,mysql 驱动的全限定类名字符串是在 java 类中写死的,一旦要改还是要修改源码。解决这个问题也很简单,使用配置文件配置.
以上只是说的解耦的一种思维,方便大家理解.
解耦的核心思想:若要减少代码的耦合度,一定要尽量做到各个功能的代码不能交叉编写,编写封闭的代码.
广大程序猿同胞,经常会看到“解耦合”,也有很多人,会用这个词来装X,但是,实际真正能理解的人,并不多。接下来,带大家深入浅出的走一遍,如何解耦合.
首先,我们要知道,为什么要解耦合:通常,我们做一个项目,会用到很多基础功能块,比如xxx通信协议,xxxView等等,我们会把这种功能块封装成一个库,如果这个库,只能在这个指定的项目运行,这就叫高耦合,这就导致了,如果下次再次遇到一个类似的项目,需要用到同样功能的功能块时,你会要做很多重复工作。假设,每次使用json时,你都要对json库进行改造,那将会是一个晴天霹雳.
但是,事与愿违,有些情况,还真的不太好解耦.
一个排序功能,对于大部分比较初级的程序猿来说,可能会写成这样:
1
|
sort(List<Integer> list)
|
这样就导致了一个问题所在,这个方法只能排序int型数据,如果下一个项目,需要用到对String进行排序,那就很尴尬,感觉明明要成功了,但是又差一点。对,就是差这一点,就是代码解耦的关键.
我们先要明确,我们需要做的是排序功能,在这个过程中,我们不可避免的需要使用2个数据的大小对比,而这个数据,可能是任何数据,也就是说,排序算法,我们是可以确定下来,做成不动的库,但是有一个数据大小匹配是我们无法做到的,或者说是库的耦合点,那怎么办呢?
我们就让使用我们这个功能块的人,告诉我们就行啦.
下面,我们参考Android库里面,有个排序的api 。
1
|
Collections.sort(List<T> list, Comparator<?
super
T> c);
|
这里,Comparator这个接口,就是使用者,需要实现,并且传递进去的接口。这样做,这个排序功能块就可以应用在任何场合,达到一次开发,受用终身的目的。是不是很神奇?
我们在开发时,经常会用到socket库,而socket最常用,最常用的一个功能就是:“连接->发送数据->接收数据->断开连接->回调结果” 。
所以,如果需要把这个流程,封装成一个功能块是很有意义的.
但是,这里有一个问题,是阻碍封装的,就是 "接收数据->断开连接",socket读取数据时,是一个inputStream,是个流,也就是说,其实,你并不知道,数据怎么样才算接收 完整/完毕 。
可能,有的协议,是通过头2个字节来判断整个数据长度 。
可能,有的协议是有帧头,帧尾,转义符来判断整个数据长度 。
…… 。
这让我们很头疼,那怎么 解决了,既然无法知道的东西,就让应用程序来告诉你呗。和上面一样,传入一个协议实现呗:
1
2
3
|
public
interface
UnZipDataAction{
// 返回null,表示未接收完全,继续接收,返回完整的byte[]就认为是已经接收完毕,把结果返回给应用,并且断开连接
byte
[] getRealData(
byte
[] recvData); ErrorCode getErrorCode(); }
|
这样,我们就把“连接->发送数据->接收数据->断开连接->回调结果”整个流程封装成了通用的功能块了.
解耦总结来说就是:你能知道的东西就写死,不知道但是又必须知道的东西,就让应用程序来告诉你,在java里面叫接口,在有些语言(OC, swift, C/C++)里面叫做代码段.
以上为个人经验,希望能给大家一个参考,也希望大家多多支持我.
原文链接:https://blog.csdn.net/weixin_43888891/article/details/108289642 。
最后此篇关于Java 你知道什么是耦合、如何解(降低)耦合的文章就讲到这里了,如果你想了解更多关于Java 你知道什么是耦合、如何解(降低)耦合的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题? Update the question所以它是on-topic对于堆栈溢出。 9年前关闭。 Improve this que
我有一堆 php 脚本计划在 CentOS 机器上的 cron 中每隔几分钟运行一次。我希望每个脚本在启动时自我检查它的前一个实例是否仍在运行,如果是则停止。 最佳答案 我这样做是为了管理任务并确保它
是否有 bash 命令、程序或 libusb 函数(尽管我没有找到)来指示 USB 设备的 OUT 或 IN 端点是什么? 例如,libusb_interface_descriptor(来自 libu
我如何知道 NSTextField 何时成为第一响应者(即当用户单击它来激活它时,但在他们开始输入之前)。我尝试了 controlTextDidBeginEditing 但直到用户键入第一个字符后才会
我怎么知道我的代码何时完成循环?完成后我还得再运行一些代码,但只有当我在那里写的所有东西都完成后它才能运行。 obj.data.forEach(function(collection) {
我正在使用音频标签,我希望它能计算播放了多少次。 我的代码是这样的: ; ; ; 然后在一个javascript文件中 Var n=0; function doing(onplaying)
我正在尝试向 Package-Explorer 的项目上下文菜单添加一个子菜单。但是,我找不到该菜单的 menuid。 所以我的问题是如何在 eclipse 中找到 menuid? 非常感谢您的帮助。
我有一个名为“下一步”的按钮,它存在于几个 asp.net 页面中。实际上它是在用户控件中。单击“下一步”时,它会调用 JavaScript 中的函数 CheckServicesAndStates。我
我正在尝试在 Visual Studio 中使用 C++ 以纳秒为单位计算耗时。我做了一些测试,结果总是以 00 结尾。这是否意味着我的处理器(Ryzen 7-1800X)不支持 ~1 纳秒的分辨率,
我有一个自定义 ListView ,其中包含一些元素和一个复选框。当我点击一个按钮时。我想知道已检查的元素的位置。下面是我的代码 public class Results extends ListAc
如何在使用 J2ME 编写的应用程序中获取网络运营商名称? 我最近正在尝试在 Nokia s40 上开发一个应用程序,它应该具有对特定网络运营商的独占访问权限。有没有这样的API或库? 最佳答案 没有
我使用服务器客户端组件,当在此组件的 TransferFile 事件中接收文件时,我使用警报消息组件。所以我希望,如果用户单击警报消息,程序将继续执行 TransferFile 事件中的代码,以在单击
如果我创建一个类A具有一些属性,例如 a, b, c我创建对象 A x1; A x2; A x3; ... A xN 。有没有办法在同一个类中创建一个方法来检索我创建的所有对象?我想创建类似 stat
我正在制作一个应用程序,其中包含相同布局的 81 个按钮。它们都被称为我创建的名为“Tile”的对象。问题是这些图 block 存储在数组中,因此我需要知道以 int 格式单击了哪个按钮才能调用图 b
UIProgressView有这个setProgress:animated: API。 有没有办法确切知道动画何时停止? 我的意思是这样的? [myProgress setProgress:0.8f
我正在使用两个 jQuery 队列,我希望其中一个队列在另一个队列完成后出队。我怎么知道第一个是否完成?我应该使用第三个队列吗?! 这是我所拥有的: var $q = $({}); $q.que
jQuery 中有没有一种方法可以知道是否至少有一个复选框已被选中? 我有一个包含很多复选框的表单,每个复选框都不同。 我需要一种 jQuery 的方式来表达这样的内容,这就是逻辑: If at le
给定 2 个选择 100 50 100 在这两种情况下,我都想在 .example 中获取数字,使用相同的选择器或者以某种方式知道 .no-text 和 之间的区别。带文字 执行
我在我的应用程序中使用 System.ComponentModel.BindingList 作为 DataGridView.DataSource。该列表非常大,需要几秒钟才能绘制到 DataGridV
我想知道用户在 Android 中选择的默认键盘。我知道我可以使用 InputMethodManager 访问已启用的输入法列表,但我想知道用户当前使用的是哪一个。 到目前为止,我已经尝试获取当前的输
我是一名优秀的程序员,十分优秀!