mockito 静态方法_Mockito –带有注释和静态方法的额外接口

mockito 静态方法

在代码中,我最近遇到了一段非常糟糕的代码,该代码基于对对象执行某些操作的类转换。 当然,代码需要重构,但是如果您首先没有对该功能进行单元测试,则有时您可能无法做到/或者不想这样做(这应该是可以理解的)。 在下面的文章中,我将展示如何测试这种代码,如何重构它以及实际上我对这种代码的看法。

让我们看一下项目结构:

如关于Mocktio RETURNS_DEEP_STUBS for JAXB的帖子中所述,我们再次在com.blogspot.toomuchcoding.model包中使用了JAXB编译器生成的JAXB类。 让我们省略对pom.xml文件的讨论,因为它与上一篇文章完全相同。

com.blogspot.toomuchcoding.adapter包中,我们在JAXB PlayerDetails类上具有适配器,该类提供对Player接口的访问。 有:

CommonPlayerAdapter.java

package com.blogspot.toomuchcoding.adapter;import com.blogspot.toomuchcoding.model.Player;
import com.blogspot.toomuchcoding.model.PlayerDetails;/*** User: mgrzejszczak* Date: 09.06.13* Time: 15:42*/
public class CommonPlayerAdapter implements Player {private final PlayerDetails playerDetails;public CommonPlayerAdapter(PlayerDetails playerDetails){this.playerDetails = playerDetails;}@Overridepublic void run() {System.out.printf("Run %s. Run!%n", playerDetails.getName());}public PlayerDetails getPlayerDetails() {return playerDetails;}
}

DefencePlayerAdapter.java

package com.blogspot.toomuchcoding.adapter;import com.blogspot.toomuchcoding.model.DJ;
import com.blogspot.toomuchcoding.model.DefensivePlayer;
import com.blogspot.toomuchcoding.model.JavaDeveloper;
import com.blogspot.toomuchcoding.model.PlayerDetails;/*** User: mgrzejszczak* Date: 09.06.13* Time: 15:42*/
public class DefencePlayerAdapter extends CommonPlayerAdapter implements DefensivePlayer, DJ, JavaDeveloper {public DefencePlayerAdapter(PlayerDetails playerDetails){super(playerDetails);}@Overridepublic void defend(){System.out.printf("Defence! %s. Defence!%n", getPlayerDetails().getName());}@Overridepublic void playSomeMusic() {System.out.println("Oops I did it again...!");}@Overridepublic void doSomeSeriousCoding() {System.out.println("System.out.println(\"Hello world\");");}
}

OffensivePlayerAdapter.java

package com.blogspot.toomuchcoding.adapter;import com.blogspot.toomuchcoding.model.OffensivePlayer;
import com.blogspot.toomuchcoding.model.PlayerDetails;/*** User: mgrzejszczak* Date: 09.06.13* Time: 15:42*/
public class OffensivePlayerAdapter extends CommonPlayerAdapter implements OffensivePlayer {public OffensivePlayerAdapter(PlayerDetails playerDetails){super(playerDetails);}@Overridepublic void shoot(){System.out.printf("%s Shooooot!.%n", getPlayerDetails().getName());}
}

好的,现在让我们转到更有趣的部分。 让我们假设我们有一个非常简单的玩家工厂:

PlayerFactoryImpl.java

package com.blogspot.toomuchcoding.factory;import com.blogspot.toomuchcoding.adapter.CommonPlayerAdapter;
import com.blogspot.toomuchcoding.adapter.DefencePlayerAdapter;
import com.blogspot.toomuchcoding.adapter.OffensivePlayerAdapter;
import com.blogspot.toomuchcoding.model.Player;
import com.blogspot.toomuchcoding.model.PlayerDetails;
import com.blogspot.toomuchcoding.model.PositionType;/*** User: mgrzejszczak* Date: 09.06.13* Time: 15:53*/public class PlayerFactoryImpl implements PlayerFactory {@Overridepublic Player createPlayer(PositionType positionType) {PlayerDetails player = createCommonPlayer(positionType);switch (positionType){case ATT:return new OffensivePlayerAdapter(player);case MID:return new OffensivePlayerAdapter(player);case DEF:return new DefencePlayerAdapter(player);case GK:return new DefencePlayerAdapter(player);default:return new CommonPlayerAdapter(player);}}private PlayerDetails createCommonPlayer(PositionType positionType){PlayerDetails playerDetails = new PlayerDetails();playerDetails.setPosition(positionType);return playerDetails;}
}

好的,所以我们有制造Player的工厂。 让我们看一下使用工厂的服务:

PlayerServiceImpl.java

package com.blogspot.toomuchcoding.service;import com.blogspot.toomuchcoding.factory.PlayerFactory;
import com.blogspot.toomuchcoding.model.*;/*** User: mgrzejszczak* Date: 08.06.13* Time: 19:02*/
public class PlayerServiceImpl implements PlayerService {private PlayerFactory playerFactory;@Overridepublic Player playAGameWithAPlayerOfPosition(PositionType positionType) {Player player = playerFactory.createPlayer(positionType);player.run();performAdditionalActions(player);return player;}private void performAdditionalActions(Player player) {if(player instanceof OffensivePlayer){OffensivePlayer offensivePlayer = (OffensivePlayer) player;performAdditionalActionsForTheOffensivePlayer(offensivePlayer);}else if(player instanceof DefensivePlayer){DefensivePlayer defensivePlayer = (DefensivePlayer) player;performAdditionalActionsForTheDefensivePlayer(defensivePlayer);}}private void performAdditionalActionsForTheOffensivePlayer(OffensivePlayer offensivePlayer){offensivePlayer.shoot();}private void performAdditionalActionsForTheDefensivePlayer(DefensivePlayer defensivePlayer){defensivePlayer.defend();try{DJ dj = (DJ)defensivePlayer;dj.playSomeMusic();JavaDeveloper javaDeveloper = (JavaDeveloper)defensivePlayer;javaDeveloper.doSomeSeriousCoding();}catch(ClassCastException exception){System.err.println("Sorry, I can't do more than just play football...");}}public PlayerFactory getPlayerFactory() {return playerFactory;}public void setPlayerFactory(PlayerFactory playerFactory) {this.playerFactory = playerFactory;}
}

让我们承认吧……这段代码很糟糕。 在内部,当您查看它时(不管它是否使用 operator 实例 ),您都会感觉到它是邪恶的。 正如您在代码中看到的那样,我们正在进行一些类强制转换……我们到底如何进行测试? 在大多数测试框架中,您无法对模拟进行此类类转换,因为它们是使用CGLIB库构建的,并且可能会抛出一些ClassCastExceptions。 您仍然无法返回模拟和真实的实现(假设它们在构造过程中不会执行任何丑陋的工作),并且它实际上可以工作,但仍然如此–这是错误的代码

Mockito可以使用其extraInterfaces功能(尽管您不应该过度使用此功能-实际上,如果您需要使用它,请考虑对其进行重构):

extraInterfaces

MockSettings extraInterfaces (java.lang.Class <?>…接口)

指定模拟应实现的额外接口。 对于遗留代码或某些极端情况可能很有用。 有关背景信息,请参见此处的问题51。此神秘功能应偶尔使用。 被测对象应该确切知道其协作者和依赖项。 如果您碰巧经常使用它,请确保您确实在生成简单,干净且可读的代码。

例子:

Foo foo = mock(Foo.class, withSettings().extraInterfaces(Bar.class, Baz.class));//now, the mock implements extra interfaces, so following casting is possible:Bar bar = (Bar) foo;Baz baz = (Baz) foo;

参数:

interfaces –应该实现的额外接口。

返回:设置实例,以便您可以流畅地指定其他设置
现在让我们看一下测试:

PlayerServiceImplTest.java

package com.blogspot.toomuchcoding.service;import com.blogspot.toomuchcoding.factory.PlayerFactory;
import com.blogspot.toomuchcoding.model.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.*;/*** User: mgrzejszczak* Date: 08.06.13* Time: 19:26*/
@RunWith(MockitoJUnitRunner.class)
public class PlayerServiceImplTest {@MockPlayerFactory playerFactory;@InjectMocksPlayerServiceImpl objectUnderTest;@Mock(extraInterfaces = {DJ.class, JavaDeveloper.class})DefensivePlayer defensivePlayerWithDjAndJavaDevSkills;@MockDefensivePlayer defensivePlayer;@MockOffensivePlayer offensivePlayer;@MockPlayer commonPlayer;@Testpublic void shouldReturnOffensivePlayerThatRan() throws Exception {//givengiven(playerFactory.createPlayer(PositionType.ATT)).willReturn(offensivePlayer);//whenPlayer createdPlayer = objectUnderTest.playAGameWithAPlayerOfPosition(PositionType.ATT);//thenassertThat(createdPlayer == offensivePlayer, is(true));verify(offensivePlayer).run();}@Testpublic void shouldReturnDefensivePlayerButHeWontBeADjNorAJavaDev() throws Exception {//givengiven(playerFactory.createPlayer(PositionType.GK)).willReturn(defensivePlayer);//whenPlayer createdPlayer = objectUnderTest.playAGameWithAPlayerOfPosition(PositionType.GK);//thenassertThat(createdPlayer == defensivePlayer, is(true));verify(defensivePlayer).run();verify(defensivePlayer).defend();verifyNoMoreInteractions(defensivePlayer);}@Testpublic void shouldReturnDefensivePlayerBeingADjAndAJavaDev() throws Exception {//givengiven(playerFactory.createPlayer(PositionType.GK)).willReturn(defensivePlayerWithDjAndJavaDevSkills);doAnswer(new Answer<Object>() {@Overridepublic Object answer(InvocationOnMock invocationOnMock) throws Throwable {System.out.println("Hit me baby one more time!");return null;}}).when(((DJ) defensivePlayerWithDjAndJavaDevSkills)).playSomeMusic();doAnswer(new Answer<Object>() {@Overridepublic Object answer(InvocationOnMock invocationOnMock) throws Throwable {System.out.println("public static void main(String... args){\n}");return null;}}).when(((JavaDeveloper) defensivePlayerWithDjAndJavaDevSkills)).doSomeSeriousCoding();//whenPlayer createdPlayer = objectUnderTest.playAGameWithAPlayerOfPosition(PositionType.GK);//thenassertThat(createdPlayer == defensivePlayerWithDjAndJavaDevSkills, is(true));verify(defensivePlayerWithDjAndJavaDevSkills).run();verify(defensivePlayerWithDjAndJavaDevSkills).defend();verify((DJ) defensivePlayerWithDjAndJavaDevSkills).playSomeMusic();verify((JavaDeveloper) defensivePlayerWithDjAndJavaDevSkills).doSomeSeriousCoding();}@Testpublic void shouldReturnDefensivePlayerBeingADjAndAJavaDevByUsingWithSettings() throws Exception {//givenDefensivePlayer defensivePlayerWithDjAndJavaDevSkills = mock(DefensivePlayer.class, withSettings().extraInterfaces(DJ.class, JavaDeveloper.class));given(playerFactory.createPlayer(PositionType.GK)).willReturn(defensivePlayerWithDjAndJavaDevSkills);doAnswer(new Answer<Object>() {@Overridepublic Object answer(InvocationOnMock invocationOnMock) throws Throwable {System.out.println("Hit me baby one more time!");return null;}}).when(((DJ) defensivePlayerWithDjAndJavaDevSkills)).playSomeMusic();doAnswer(new Answer<Object>() {@Overridepublic Object answer(InvocationOnMock invocationOnMock) throws Throwable {System.out.println("public static void main(String... args){\n}");return null;}}).when(((JavaDeveloper) defensivePlayerWithDjAndJavaDevSkills)).doSomeSeriousCoding();//whenPlayer createdPlayer = objectUnderTest.playAGameWithAPlayerOfPosition(PositionType.GK);//thenassertThat(createdPlayer == defensivePlayerWithDjAndJavaDevSkills, is(true));verify(defensivePlayerWithDjAndJavaDevSkills).run();verify(defensivePlayerWithDjAndJavaDevSkills).defend();verify((DJ) defensivePlayerWithDjAndJavaDevSkills).playSomeMusic();verify((JavaDeveloper) defensivePlayerWithDjAndJavaDevSkills).doSomeSeriousCoding();}@Testpublic void shouldReturnCommonPlayer() throws Exception {//givengiven(playerFactory.createPlayer(null)).willReturn(commonPlayer);//whenPlayer createdPlayer = objectUnderTest.playAGameWithAPlayerOfPosition(null);//thenassertThat(createdPlayer, is(commonPlayer));}
}

这里有很多测试,所以让我们看一下最有趣的测试。 但是在开始之前,我们先:提供@RunWith(MockitoJUnitRunner.class)批注,这使我们能够使用Mockito批注,例如@Mock@InjectMocks

说到哪个@Mock注释会创建一个Mock,而@InjectMocks则通过构造函数或setter注入所有模拟(这太棒了吗?)。

对于防御性玩家,我们使用注记extraInterfaces的extra元素,该元素为给定的Mock提供其他接口。 您还可以编写(可以在shouldReturnDefensivePlayerBeingADjAndAJavaDevByUsingWithSettings测试中找到的内容 ):

DefensivePlayer defensivePlayerWithDjAndJavaDevSkills = mock(DefensivePlayer.class, withSettings().extraInterfaces(DJ.class, JavaDeveloper.class));

让我们仔细看看为与DefensivePlayer相关的功能和测试功能的转换部分编写的测试:

@Testpublic void shouldReturnDefensivePlayerBeingADjAndAJavaDev() throws Exception {//givengiven(playerFactory.createPlayer(PositionType.GK)).willReturn(defensivePlayerWithDjAndJavaDevSkills);doAnswer(new Answer<Object>() {@Overridepublic Object answer(InvocationOnMock invocationOnMock) throws Throwable {System.out.println("Hit me baby one more time!");return null;}}).when(((DJ) defensivePlayerWithDjAndJavaDevSkills)).playSomeMusic();doAnswer(new Answer<Object>() {@Overridepublic Object answer(InvocationOnMock invocationOnMock) throws Throwable {System.out.println("public static void main(String... args){\n}");return null;}}).when(((JavaDeveloper) defensivePlayerWithDjAndJavaDevSkills)).doSomeSeriousCoding();//whenPlayer createdPlayer = objectUnderTest.playAGameWithAPlayerOfPosition(PositionType.GK);//thenassertThat(createdPlayer == defensivePlayerWithDjAndJavaDevSkills, is(true));verify(defensivePlayerWithDjAndJavaDevSkills).run();verify(defensivePlayerWithDjAndJavaDevSkills).defend();verify((DJ) defensivePlayerWithDjAndJavaDevSkills).playSomeMusic();verify((JavaDeveloper) defensivePlayerWithDjAndJavaDevSkills).doSomeSeriousCoding();}

我们正在使用BDDMockito静态方法,如给定(...)。willReturn(...)。willAnswer(...)等。然后,将空方法与自定义Anwsers结合使用。 在下一行中,您可以看到,为了存根另一个接口的方法,必须将模拟转换为给定的接口。 这与验证阶段有关,在该阶段,我不检查是否已执行方法,您必须将模拟转换为给定的接口。

您可以通过从工厂返回一个真实的实现来改进测试,或者如果创建一个繁琐的操作,则可以返回这种实现的模拟。 我想在这里展示的是如何在Mockito中使用额外的接口(也许我的用例不是最好的用例)。 无论如何,测试中提出的实现都是不好的,所以我们应该考虑重构它的方法……

一种想法可能是,假设在Service中完成的附加逻辑是对象创建的一部分,将代码原样移至工厂:

PlayFactoryImplWithFieldSettingLogic.java

package com.blogspot.toomuchcoding.factory;import com.blogspot.toomuchcoding.adapter.CommonPlayerAdapter;
import com.blogspot.toomuchcoding.adapter.DefencePlayerAdapter;
import com.blogspot.toomuchcoding.adapter.OffensivePlayerAdapter;
import com.blogspot.toomuchcoding.model.*;/*** User: mgrzejszczak* Date: 09.06.13* Time: 15:53*/public class PlayerFactoryImplWithFieldSettingLogic implements PlayerFactory {@Overridepublic Player createPlayer(PositionType positionType) {PlayerDetails player = createCommonPlayer(positionType);switch (positionType){case ATT:return createOffensivePlayer(player);case MID:return createOffensivePlayer(player);case DEF:return createDefensivePlayer(player);case GK:return createDefensivePlayer(player);default:return new CommonPlayerAdapter(player);}}private Player createDefensivePlayer(PlayerDetails player) {DefencePlayerAdapter defencePlayerAdapter = new DefencePlayerAdapter(player);defencePlayerAdapter.defend();defencePlayerAdapter.playSomeMusic();defencePlayerAdapter.doSomeSeriousCoding();return defencePlayerAdapter;}private OffensivePlayer createOffensivePlayer(PlayerDetails player) {OffensivePlayer offensivePlayer = new OffensivePlayerAdapter(player);offensivePlayer.shoot();return offensivePlayer;}private PlayerDetails createCommonPlayer(PositionType positionType){PlayerDetails playerDetails = new PlayerDetails();playerDetails.setPosition(positionType);return playerDetails;}
}

这样就没有强制转换代码是干净的。 现在,PlayerService如下所示:

PlayerServiceImplWIthoutUnnecessaryLogic.java

package com.blogspot.toomuchcoding.service;import com.blogspot.toomuchcoding.factory.PlayerFactory;
import com.blogspot.toomuchcoding.model.*;/*** User: mgrzejszczak* Date: 08.06.13* Time: 19:02*/
public class PlayerServiceImplWithoutUnnecessaryLogic implements PlayerService {private PlayerFactory playerFactory;/*** What's the point in having this method then?* @param positionType* @return*/@Overridepublic Player playAGameWithAPlayerOfPosition(PositionType positionType) {return playerFactory.createPlayer(positionType);}public PlayerFactory getPlayerFactory() {return playerFactory;}public void setPlayerFactory(PlayerFactory playerFactory) {this.playerFactory = playerFactory;}
}

随之而来的问题是,您的代码库中是否甚至需要这种方法……

总结一下,我希望我能展示如何:

  • 使用MockitoJUnitRunner以干净的方式注入模拟
  • 使用注释或静态方法添加可以由您的模拟使用的额外接口
  • 使用BDDMockito执行方法存根
  • 带有自定义答案的存根无效方法
  • 附加接口的存根和验证方法
  • 重构使用类强制转换的代码

来源可从TooMuchCoding Bitbucket存储库和TooMuchCoding Github存储库中获得。

参考: Mockito –来自我们的JCG合作伙伴 Marcin Grzejszczak(位于Blog上)的 具有注释和静态方法的Extra Interfaces, 用于编码瘾君子博客。

翻译自: https://www.javacodegeeks.com/2013/06/mockito-extra-interfaces-with-annotations-and-static-methods.html

mockito 静态方法

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

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

相关文章

手机推送信息到本地服务器,服务器信息推送到手机

服务器信息推送到手机 内容精选换一换服务器的计费方式为“包年/包月”&#xff0c;如果在计费周期内不想再继续使用&#xff0c;请参考本节指导进行退订。执行退订操作前&#xff0c;请确保待退订的服务器数据已完成备份或者迁移&#xff0c;退订完成后资源将被完全删除&#…

怎么修改服务器上的cpt文件,DELL-服务器-RAID-配置详解(28页)-原创力文档

DELL 服务器 RAID 配置详解磁盘阵列可以在安装系统之前或之后产生&#xff0c;系统会视之为一个(大型)硬盘&#xff0c;而它具有容 错及冗余的功能。磁盘阵列不单只可以加入一个现成的系统&#xff0c;它更可以支持容量扩展&#xff0c;方 法也很简单&#xff0c;只需要加入一个…

Apache Camel 2.21发布–新增功能

我们刚刚发布了Apache Camel 2.21&#xff0c;我将在此博客中重点介绍值得注意的更改。 此版本不支持Spring Boot2。对Spring Boot 2的支持将在Camel 2.22中提供&#xff0c; 我们计划在2018年夏季之前发布。 1&#xff09;处理大型JMS消息 我们在JMS组件中添加了更好的支持&…

linux下网站服务器,Linux下使用Apache搭建Web网站服务器(示例代码)

[[email protected] ~]# yum install elinks –y主配置文件[[email protected] ~]# ls/etc/httpd/conf/httpd.conf/etc/httpd/conf/httpd.conf#我们又是怎么知道httpd的注配置文件是在你那里的呢&#xff1f;查看httpd注配置文件位置[[email protected] ~]# rpm -pql/mnt/Packa…

程序内存泄露监视_监视和检测Java应用程序中的内存泄漏

程序内存泄露监视因此&#xff0c;您的应用程序内存不足&#xff0c;您日夜不停地分析应用程序&#xff0c;以期捕获对象中的内存漏洞。 后续步骤将说明如何监视和检测您的内存泄漏&#xff0c;以确保您的应用程序处于安全状态。 1.怀疑内存泄漏 如果您怀疑有内存泄漏&#xf…

服务器可以装两个系统吗,云服务器可以装多个系统吗

云服务器可以装多个系统吗 内容精选换一换示例&#xff1a;购买并登录Windows弹性云服务器示例&#xff1a;购买并登录Linux弹性云服务器云平台提供了多种实例类型供您选择&#xff0c;不同类型的实例可以提供不同的计算能力和存储能力。同一实例类型下可以根据CPU和内存的配置…

与Spring的计划任务一起按时运行

您是否需要每天像闹钟一样在同一时间运行某个流程&#xff1f; 然后&#xff0c;Spring的预定任务适合您。 允许您使用Scheduled注释方法&#xff0c;以使其在指定的时间或内部间隔运行。 在本文中&#xff0c;我们将研究如何设置一个可以使用计划任务的项目&#xff0c;以及如…

jboss url路径_在JBoss的服务器端正确解码URL参数

jboss url路径我今天花了很多时间来弄清楚如何在运行在JBoss上的JSF应用程序中&#xff08;使用JBoss 7 Final&#xff09;强制正确解码编码的字符。 当您有例如通过URL传递中文字符时&#xff0c;就会发生此问题。 假设您有指点事件&#xff0c;编码为&#xff05;E6&#xff…

在JDK 10中不可变与不可修改

大约两个月前&#xff0c; 斯图尔特马克斯 &#xff08; Stuart Marks&#xff09;写道&#xff1a;“ 不变性就像葡萄酒 。” 然后&#xff0c;他提醒读者注意叔本华的熵定律 &#xff1a;“如果将一勺酒倒入装满污水的桶中&#xff0c;就会产生污水。 如果将一勺污水倒入装满…

@async方法不调用了_在Spring中使用Future对象调用Async方法调用

async方法不调用了下一个示例将演示Spring容器内部的异步方法调用。 为什么我们需要异步方法调用&#xff1f; 在某些情况下&#xff0c;我们并不真正知道是否需要重播或何时应返回结果。 传统方式在Java EE世界中处理异步调用的方法是使用队列/主题。 我们可以在Spring中进行相…

不同的休眠命名策略

本文讨论了hibernate提供的不同命名策略&#xff0c;以及命名策略从hibernate 4中的hibernate.ejb.naming_strategy到hibernate 5中的hibernate.implicit_naming_strategy和hibernate.physical_naming_strategy的转变。最后&#xff0c;我们将研究一下在休眠和配置中实施自定义…

基于FPGA,如何用Verilog HDL实现64位宽的扰码器?附上仿真结果。

文章目录前言一、扰码器1、什么是扰码器2、扰码的原理3、产生扰码的多项式二、Scrambler的Verilog实现1、scrambler.v2、scrambler_tb.v三、仿真结果四、总结前言 在数字信号处理系统中&#xff0c;因为发送端的数字信号序列可能会出现很长一段都是“0”&#xff0c;或很长一段…

基于FPGA,解扰码器Verilog的实现,以及扰码器与解扰码器的联合仿真。附上仿真结果。

文章目录前言一、扰码器二、解扰码器三、Descrambler的Verilog实现1、descrambler.v2、descrambler_tb.v四、扰码器与解扰码器的联合仿真1、scrambler_test.v2、scrambler_test_tb.v3、联合仿真结果五、总结前言 在数字信号处理系统中&#xff0c;因为发送端的数字信号序列可能…

光纤通信系统简介

文章目录前言一、直接检测光通信系统二、相干光通信系统三、直接检测与相干检测1、直接检测2、相干检测3、相干检测的优缺点&#xff08;1&#xff09;相干检测的缺点&#xff08;2&#xff09;相干检测的优点总结参考文献前言 光通信系统的基本组成结构如下图所示。光通信系统…

epyc rome_使用Encog,ROME,JSoup和Google Guava进行博客分类

epyc rome继续进行编程收集情报 &#xff08; Programming Collection Intelligence &#xff0c;PCI&#xff09;&#xff0c;下一个练习是使用距离得分根据相关博客中使用的单词来确定博客列表。 我已经找到Encog作为AI /机器学习算法的框架&#xff0c;为此&#xff0c;我需…

重构字符串型系统

去年&#xff0c;我加入了一个项目&#xff0c;该项目接管了另一个未能满足客户需求的软件公司。 如您所知&#xff0c;在“继承”的项目及其代码库中&#xff0c;有许多事情可以并且应该加以改进。 可悲的是&#xff08;但并不奇怪&#xff09;领域模型就是这样一个孤零零&…

OFDM仿真程序,可直接运行,注释详细(没人注释比我还详细了)

OFDM仿真程序 clc clear allIFFT_bin_length128; %IFFT点数128个 carrier_count50; %子信道&#xff08;子载波&#xff09;数目 bits_per_symbol2; %4进制符号 symbols_per_carrier200;%每个子信道或者说子载波有200个符号 SNR0:1:40; for num1:41baseband_out_lengthcarrie…

Delta-Sigma调制(DSM)技术

前言 数字信号处理和通信系统的性能很大程度上受到了模拟信号到数字信号转换接口——ADC的精度和分辨率的限制。而传统的线性脉冲编码调制&#xff08;PCM&#xff09;ADC受到了制造工艺的限制&#xff0c;无法达到很高的分辨率。但基于Delta-Sigma调制技术的ADC可以在现有工艺…

无载波幅度和相位调制(CAP)与QAM调制的详细解析(可见光通信应用场景),以及CAP matlab程序下载链接

文章目录前言一、QAM调制&#xff1f;二、无载波幅度和相位调制&#xff08;CAP)三、CAP调制与QAM调制之间的联系&#xff08;异同点&#xff09;四、CAP调制相比于QAM调制的优缺点4.1、优点4.2、缺点五、无载波幅度和相位调制matlab程序五、Reference前言 目前的通信系统中&a…

jpa 事务嵌套事务_JPA 2 | EntityManagers,事务及其周围的一切

jpa 事务嵌套事务介绍 对我来说&#xff0c;最令人困惑和不清楚的事情之一是&#xff0c;作为Java开发人员&#xff0c;一直是围绕事务管理的谜团&#xff0c;尤其是JPA如何处理事务管理。 事务什么时候开始&#xff0c;什么时候结束&#xff0c;实体的持久化方式&#xff0c;持…