mockito手动注入依赖_依赖注入–手动方式

mockito手动注入依赖

依赖注入是一种将行为与依赖解决方案分开的技术。 用简单的话来说,它使开发人员可以定义具有特定功能的类,这些功能取决于各种协作者,而不必定义如何获取对这些协作者的引用。 以此方式,实现了各个组件之间的解耦,并且通常引入了更简洁的代码。 更具体地说,一个组件仅列出必要的服务,而不是对依赖项进行硬编码,而在运行时,一个外部独立的组件将提供对这些服务的访问。 我们不应忘记,依赖注入只是控制反转的一种特殊形式,其中反转的关注点是获得所需依赖的过程。 前述技术的参考文章是Martin Fowler的 “控制容器的倒置和依赖注入模式” 。

为了注入依赖关系,已经出现了许多框架,最著名的是Spring和Guice (请参阅JavaCodeGeeks Spring相关文章)。 但是,对于小型项目使用整个框架无疑是一个过大的杀伤力。 我们的JCG合作伙伴之一, “ Death By Code”博客的作者,对如何手动处理依赖项注入做了简短的介绍 。 让我们看看他怎么说?

在另一篇文章中, “我真的需要单身人士吗?” ,我写了有关Singleton设计模式引入的问题的文章。 通过getInstance()方法访问单个唯一实例时,Singleton会变相充当全局变量,并引入紧密耦合和不必要的依赖关系。 我收到了读者的两个直接问题:

单例应该仅与依赖注入框架一起使用吗?
如果通过getInstance()访问Singleton创建紧密耦合,则通过new()创建任何其他类的实例也将导致紧密耦合。 那么,如何创建一个保持松散耦合的对象?

根据我的理解,依赖注入是这两个问题的答案。 但是,这并不要求使用框架。 依赖注入首先是一个概念,然后是一个框架。 当所讨论的应用程序很小时,我们总是可以通过手动注入依赖项来满足需求,而无需使用任何类似Spring的框架。

在任何Java应用程序中,我们都会反复遇到两个事件:

  • 对象创建
  • 对象之间的交互–业务逻辑

但是,通常我们将两者混为一谈,从而导致紧密耦合和不必要的依赖关系,这反过来又给维护以及单元测试带来麻烦。 让我尝试使用一个非常简单的示例来解释它:

class MyClass {private A a; //A is an interfaceprivate B b; //B is an interface//Object creation within constructorMyClass(A a, B b) {  a = new AImpl(); //AImpl is the concrete impl of Ab = new BImpl(); //BImpl is the concrete impl of B}//Application logic lies within this methodpublic void doSomething() {//Do A specific thing//Do B specific thingC c = new CImpl(); //Object creation within the method.//Do C specific thing}
}

此类的问题是:

  1. 它无法将对象创建与业务逻辑分开,从而导致紧密耦合。
  2. 此处已完成了“实现编程”,而不是接口。 明天,如果需要A,B或C的不同实现,则必须更改类中的代码。
  3. 测试MyClass需要首先测试A,B,C。

让我尝试解决问题:

class MyClass {private A a;private B b;private C c;MyClass(A a, B b, C c) {//Only Assignmentthis.a = a;this.b = b;this.c = c;}//Application Logicpublic void doSomething() {//Do A specific thing//Do B specific thing//Do C specific thing}
}//The Factory
class MyFactory {public MyClass createMyClass() {return new MyClass(new AImpl(), new BImpl(), new CImpl());}
}class Main {public static void main(String args[]) {MyClass mc = new MyFactory().createMyClass();mc.doSomething();}
}

在这里已经实现了什么:

1.构造函数没有new():
没有在MyClass的构造函数中创建对象。 该构造函数仅用于字段(A,B,C)分配。 在这里,构造函数要求依赖项作为参数,但不创建它们(这是依赖项注入的最简单定义)。 但是,可以在构造函数中创建简单的Collection对象(如ArrayList,HashMap或value / leaf对象,如Person / Employee)(即应用程序内的对象,这些对象又不会创建其他对象)。 构造函数不应用于任何其他操作,例如I / O,线程创建等。

根据经验法则,任何对象都应仅保留对其直接完成工作所需的其他对象的引用(这称为Demeter法则)。 例如,如果MyClass需要其他称为X的类,则MyClass的构造函数应直接要求X。不应要求其他工厂F可以返回X的实例。违反“ De​​meter法则”将导致不必要的依赖关系因此,如果您发现多个Dot(。)运算符,请当心-那里发生了非法事件。

2. Factory(MyFactory)负责对象的创建和连接:
所有新的操作员(90%-99%)应属于工厂。 它应负责为应用程序创建整个对象图,并应根据声明的依赖关系关联(连接)不同的对象(例如,MyClass需要A,B,C等)。 它不应包含任何其他内容-不应包含任何其他逻辑(没有I / O,线程创建等)。

明天如果C开始依赖于其他称为D的东西,则只会影响C和工厂,而不会影响整个对象图(C必须引入重载的构造函数,并且工厂必须合并对象实例化以及与对象接线相关的更改) 。

对于大型应用程序,当然可能会有多个工厂。 在这里,经验法则是一个工厂应该实例化具有相同寿命的所有对象。

3.对象的创建与业务逻辑是分开的:
MyClass现在是业务逻辑持有人。 它没有任何new()。 甚至,它也不了解用于业务逻辑的具体实现(即,它了解A,但不了解AImpl,即“接口程序而不是实现程序”)。

您一定已经开始认为我是在Singleton的背景下开始讨论的。 手动依赖项注入如何处理Singleton? 如何创建一个Singleton(减去紧密耦合,隐藏的依赖关系等)并在需要时访问它? 令人惊讶的是,我们的示例中已经有三个Singleton-AImpl,BImpl,CImpl。 如果工厂只负责创建Class的一个实例(通过仅调用new()一次),则其为Singleton。 是不是 然后,工厂可以将该依赖关系形式的唯一实例传递给需要它的所有其他对象。

4.那么,我们在哪里?
业务逻辑持有者MyClass的业务需要A,B和C。 它不会创建它们,而是要它们(依赖项)。 工厂(MyFactory)创建这些依赖关系并将其关联到MyClass。 但是,谁创造了工厂? 当然是主要方法(应用程序启动器:-)。 让我再重复一遍这个故事:main方法首先实例化工厂,工厂反过来实例化对象图,每个Object声明其依赖关系,最后main方法本身设置滚动-通过调用MyClass的doSomething()启动应用程序,即。 这些对象开始互相交谈,执行日常业务。

让我再重复一次: 创建工厂,使用工厂创建应用程序,然后启动应用程序! 对于大规模应用程序,可以通过像Spring,Google Guice等依赖注入框架来实现相同的目的。当然,它们还将带来许多其他好处。 但是,对于中小型应用程序,可以手动制作依赖项注入,从而使应用程序松散耦合,更易于维护并且当然对单元测试友好。

相关文章 :
  • 使用Spring AspectJ和Maven进行面向方面的编程
  • JBoss 4.2.x Spring 3 JPA Hibernate教程
  • GWT Spring和Hibernate进入数据网格世界
  • 建立自己的GWT Spring Maven原型
  • GWT 2 Spring 3 JPA 2 Hibernate 3.5教程– Eclipse和Maven 2展示
  • 使用Spring使用Java发送电子邮件– GMail SMTP服务器示例

翻译自: https://www.javacodegeeks.com/2010/12/dependency-injection-manual-way.html

mockito手动注入依赖

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

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

相关文章

ubuntu使用root权限登录的设置方法

Ubuntu系统默认是不允许用户以root身份登录的,在网上找到的方法如下: 1、首先设置root密码,利用现有管理员帐户登陆Ubuntu,在终端执行命令:sudo passwd root,接着输入密码和root密码,重复密码。…

visio 小技巧

Visio作图非常的方便 目前我还是用Visio2003,有一些小技巧,记录一下。 1、visio修改文本框文字对齐方式。默认的对齐方式是上下、左右居中。修改的位置: 在一个文档中可以插入多个标签页,当需要分页,用不同页归类不同信息的时候使…

java实现bean实体与map集合相互转换

方法一 //bean装换成map public static Map<?, ?> objectToMap2(Object obj) { if(obj null) return null; return new org.apache.commons.beanutils.BeanMap(obj); } 方法二 //bean装换成map public static Map&l…

java中字符串的精确匹配_Java最佳实践–字符串性能和精确字符串匹配

java中字符串的精确匹配在使用Java编程语言时&#xff0c;我们将继续讨论与建议的实践有关的系列文章&#xff0c;我们将讨论String性能调优。 我们将专注于如何有效地处理字符串创建&#xff0c; 字符串更改和字符串匹配操作。 此外&#xff0c;我们将提供我们自己的用于精确字…

My.Ioc 代码示例——避免循环依赖

本文的目的在于通过一些示例&#xff0c;向大家说明 My.Ioc 支持哪些类型的依赖关系。也就是说&#xff0c;如何设计对象不会导致循环依赖。 在 Ioc 世界中&#xff0c;循环依赖是一个顽敌。这不仅因为它会导致 Ioc 容器抛出异常&#xff0c;而且还因为它是不可预知的&#xff…

java实现base64加密解密

/** * 加密 * param str * return */ public static String getStr(String str){ BASE64Encoder base64 new BASE64Encoder(); return base64.encode(str.getBytes()); } /** * 解密 * param str * return * t…

设计模式之单件模式(Singleton Pattern)

一.单件模式是什么&#xff1f; 单件模式也被称为单例模式&#xff0c;它的作用说白了就是为了确保“该类的实例只有一个” 单件模式经常被用来管理资源敏感的对象&#xff0c;比如&#xff1a;数据库连接对象、注册表对象、线程池对象等等&#xff0c;这种对象如果同时存在多个…

asp.net中两款文本编辑器NicEdit和Kindeditor

分类&#xff1a; C#/ASP.Net 2012-10-09 22:35 665人阅读 评论(0) 收藏 举报 文本编辑asp.nettextboxserveraspsafari目录(?)[] 做过Web开发的朋友相信都使用过富文本编辑器&#xff0c;比较出名的CuteEditor和CKEditor很多人应该已经使用过&#xff0c;在功能强大的同时需要…

导出oracle awr分析报告,配置oracle内存参数,察看表空间使用率

cmd 命令生成awr报告: cmd 窗口 输入 -> Sqlplus sys/orclorcl as sysdba (sys登陆oracle).导出awr命令 ?/rdbms/admin/awrrpt.sql 3..输入导出的文件格式 为 html 回车 4输入数字1 为导出今天的分析报告 &#xff0c;2 3 。。。&#xff0c;回车 5.输入开始 snap id…

android多点触控自由对图片缩放

在系统的相册中,观看相片就可以用多个手指进行缩放.要实现这个功能,只需要这几步:1.新建项目,在项目中新建一个ZoomImage.javapublic class ZoomImageView extends View {//初始化状态常量public static final int STATUS_INIT1;//图片放大状态常量public static final int STA…

台阶问题额

题目名字 台阶问题 题意 初始化数组f的第一个元素为1。这表示到达第0级台阶的方式数为1&#xff0c;即不需要迈任何台阶。从第1级台阶开始&#xff0c;迭代计算每一级台阶的不同方式数。对于当前台阶i&#xff0c;内部循环从1到i和k中的较小值开始迭代。这是因为每次只能向上…

jboss eclipse_调试生产服务器– Eclipse和JBoss展示

jboss eclipse您是否编写有错误的代码&#xff1f; 不&#xff0c;当然不是。 对于我们其余的人&#xff0c;他们确实会编写带有bug的代码&#xff0c;我想解决一个非常敏感的问题&#xff1a;调试在生产服务器上运行的应用程序。 因此&#xff0c;您的应用程序已准备好进行部…

Chrome 控制台不完全指南

Chrome的开发者工具已经强大到没朋友的地步了&#xff0c;特别是其功能丰富界面友好的console&#xff0c;使用得当可以有如下功效&#xff1a; 更高「逼格」更快「开发调试」更强「进阶级的Frontender」Bug无处遁形「Console大法好」console.log 大家都会用log&#xff0c;但鲜…

datanucleus_DataNucleus 3.0与Hibernate 3.5

datanucleus如官方产品站点所述&#xff0c; DataNucleus Access Platform是现有的最符合标准的开源Java持久性产品。 它完全符合JDO1 &#xff0c; JDO2 &#xff0c; JDO2.1 &#xff0c; JDO2.2 &#xff0c; JDO3 &#xff0c; JPA1和JPA2 Java标准。 它还符合OGC简单功能规…

$.fn.zTree 展开 回显 选中

var ids节点字符串;// 字符串形式&#xff1a;选中节点&#xff0c;...&#xff0c;二级节点&#xff0c;根节点 var siids..split(",").length-1; var setting {view:{selectedMulti:false},data:{simpleData:{enable:true}}, async: { enab…

Android学习笔记——Menu(二)

知识点&#xff1a;这次将继续上一篇文章没有讲完的Menu的学习&#xff0c;上下文菜单(Context menu)和弹出菜单(Popup menu)。 上下文菜单上下文菜单提供对UI界面上的特定项或上下文框架的操作&#xff0c;就如同Windows中右键菜单一样。 在Android中&#xff0c;有两种提供上…

eclipse卡慢解决办法

1.设置JVM运行内存 1.1编辑eclipse.ini 1.2 编辑eclipse.ini,设置jvm运行内存参数&#xff0c;最小内存&#xff1a;物理内存*0.2&#xff0c; 最大内存&#xff1a; 物理内存*0.6&#xff1b; 其中-vmargs为必须添加参数&#xff08;-vmargs的意思是设置JVM参数&#xff09;,…

python学习之文件读写

实现文件的读写 #! /usr/bin/python file_add open(test.txt,a)for i in range(1,5): file_add.write("1.1.1.%d 255.255.255.255 %d 2.2.2.%d 255.255.255.168 \n" %(i,i,i))file_add.close() 期间遇到的问题&#xff1a; 1、字符串格式化问题—多个参数 -sh-4.1#…

ext3 tree tbar 初始化定义

var rc_store new Ext.data.SimpleStore( { fields : [ value, text ], data : [ [ 10, 行 ], [ 20, 列 ] ] }); var bar_v [ { text:展开, handler:function(){ tree.expa…

xuggler 中文开发_Xuggler开发教程

xuggler 中文开发大家好&#xff0c; 在这篇文章中&#xff0c;我想介绍JavaCodeGeeks上的一些很酷的新教程。 他们将讨论与Xuggler &#xff0c; FFmpeg和Wowza进行媒体&#xff08;音频/视频&#xff09;操纵的方式。 我将在这篇文章中跟踪所有相关的教程。 您可以通过查看P…