程序员的量化交易之路(12)--Guice库的学习

Screenshot_2026-11-03-16-23-09-34.jpg 立即下载
Google Guice学习
在学习Cointrader的代码时候,要用到Google的guice用于依赖注入(Dependence Injection)。所以,在这里系统的学习一遍。这里我主要是对其官方文档进行有选择性的学习翻译。

动机

写类对象之间的组合关系是非常麻烦的一件事情。这里以一个网站订披萨作为案例:
public interface BillingService {


  /**
   * Attempts to charge the order to the credit card. Both successful and
   * failed transactions will be recorded.
   *
   * @return a receipt of the transaction. If the charge was successful, the
   *      receipt will be successful. Otherwise, the receipt will contain a
   *      decline note describing why the charge failed.
   */
  Receipt chargeOrder(PizzaOrder order, CreditCard creditCard);
}


直接用构造函数调用



public class RealBillingService implements BillingService {
  public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) {
    CreditCardProcessor processor = new PaypalCreditCardProcessor();//
    TransactionLog transactionLog = new DatabaseTransactionLog();//这两个直接在构造函数里面构造,不利于模块化和单元测试


    try {
      ChargeResult result = processor.charge(creditCard, order.getAmount());
      transactionLog.logChargeResult(result);


      return result.wasSuccessful()
          ? Receipt.forSuccessfulCharge(order.getAmount())
          : Receipt.forDeclinedCharge(result.getDeclineMessage());
     } catch (UnreachableException e) {
      transactionLog.logConnectException(e);
      return Receipt.forSystemFailure(e.getMessage());
    }
  }
}

工厂方法

工厂方法能够解耦一个接口的使用者和接口的实现者之间的关系。
public class CreditCardProcessorFactory {


  private static CreditCardProcessor instance;


  public static void setInstance(CreditCardProcessor processor) {
    instance = processor;
  }


  public static CreditCardProcessor getInstance() {
    if (instance == null) {
      return new SquareCreditCardProcessor();
    }


    return instance;
  }
}
在使用者这边,我们就可以替换掉new语句:
public class RealBillingService implements BillingService {
  public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) {
    CreditCardProcessor processor = CreditCardProcessorFactory.getInstance();
    TransactionLog transactionLog = TransactionLogFactory.getInstance();//工厂方法


    try {
      ChargeResult result = processor.charge(creditCard, order.getAmount());
      transactionLog.logChargeResult(result);


      return result.wasSuccessful()
          ? Receipt.forSuccessfulCharge(order.getAmount())
          : Receipt.forDeclinedCharge(result.getDeclineMessage());
     } catch (UnreachableException e) {
      transactionLog.logConnectException(e);
      return Receipt.forSystemFailure(e.getMessage());
    }
  }
}
这种工厂方法使得我们可以方便地写单元测试:
public class RealBillingServiceTest extends TestCase {


  private final PizzaOrder order = new PizzaOrder(100);
  private final CreditCard creditCard = new CreditCard("1234", 11, 2010);


  private final InMemoryTransactionLog transactionLog = new InMemoryTransactionLog();
  private final FakeCreditCardProcessor processor = new FakeCreditCardProcessor();


  @Override public void setUp() {//设置
    TransactionLogFactory.setInstance(transactionLog);
    CreditCardProcessorFactory.setInstance(processor);
  }


  @Override public void tearDown() {//重置
    TransactionLogFactory.setInstance(null);
    CreditCardProcessorFactory.setInstance(null);
  }


  public void testSuccessfulCharge() {//测试
    RealBillingService billingService = new RealBillingService();
    Receipt receipt = billingService.chargeOrder(order, creditCard);


    assertTrue(receipt.hasSuccessfulCharge());
    assertEquals(100, receipt.getAmountOfCharge());
    assertEquals(creditCard, processor.getCardOfOnlyCharge());
    assertEquals(100, processor.getAmountOfOnlyCharge());
    assertTrue(transactionLog.wasSuccessLogged());
  }
}

依赖注入

和工厂方法一样,依赖注入也是一种代码实现上的设计模式,它的原则是“separate behavior from dependency resolution”。
public class RealBillingService implements BillingService {
  private final CreditCardProcessor processor;
  private final TransactionLog transactionLog;


  public RealBillingService(CreditCardProcessor processor, 
      TransactionLog transactionLog) {
    this.processor = processor;
    this.transactionLog = transactionLog;
  }


  public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) {
    try {
      ChargeResult result = processor.charge(creditCard, order.getAmount());
      transactionLog.logChargeResult(result);


      return result.wasSuccessful()
          ? Receipt.forSuccessfulCharge(order.getAmount())
          : Receipt.forDeclinedCharge(result.getDeclineMessage());
     } catch (UnreachableException e) {
      transactionLog.logConnectException(e);
      return Receipt.forSystemFailure(e.getMessage());
    }
  }
}


这时候,不需要任何工厂类:
public class RealBillingServiceTest extends TestCase {


  private final PizzaOrder order = new PizzaOrder(100);
  private final CreditCard creditCard = new CreditCard("1234", 11, 2010);


  private final InMemoryTransactionLog transactionLog = new InMemoryTransactionLog();
  private final FakeCreditCardProcessor processor = new FakeCreditCardProcessor();


  public void testSuccessfulCharge() {
    RealBillingService billingService
        = new RealBillingService(processor, transactionLog);
    Receipt receipt = billingService.chargeOrder(order, creditCard);


    assertTrue(receipt.hasSuccessfulCharge());
    assertEquals(100, receipt.getAmountOfCharge());
    assertEquals(creditCard, processor.getCardOfOnlyCharge());
    assertEquals(100, processor.getAmountOfOnlyCharge());
    assertTrue(transactionLog.wasSuccessLogged());
  }
}


然后,使用:
  public static void main(String[] args) {
    CreditCardProcessor processor = new PaypalCreditCardProcessor();
    TransactionLog transactionLog = new DatabaseTransactionLog();
    BillingService billingService
        = new RealBillingService(processor, transactionLog);
    ...
  }


使用guice进行依赖注入

首先需要通过Guice的module来配置接口和实现之间的映射。
public class BillingModule extends AbstractModule {
  @Override 
  protected void configure() {
    bind(TransactionLog.class).to(DatabaseTransactionLog.class);
    bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class);
    bind(BillingService.class).to(RealBillingService.class);
  }
}


我们在RealBillingService的构造函数上添加@Inject标注,它会引导Guice去使用module。


public class RealBillingService implements BillingService {
  private final CreditCardProcessor processor;
  private final TransactionLog transactionLog;


  @Inject
  public RealBillingService(CreditCardProcessor processor,
      TransactionLog transactionLog) {
    this.processor = processor;
    this.transactionLog = transactionLog;
  }


  public Receipt chargeOrder(PizzaOrder order, CreditCard creditCard) {
    try {
      ChargeResult result = processor.charge(creditCard, order.getAmount());
      transactionLog.logChargeResult(result);


      return result.wasSuccessful()
          ? Receipt.forSuccessfulCharge(order.getAmount())
          : Receipt.forDeclinedCharge(result.getDeclineMessage());
     } catch (UnreachableException e) {
      transactionLog.logConnectException(e);
      return Receipt.forSystemFailure(e.getMessage());
    }
  }
}


最后使用:
public static void main(String[] args) {
    Injector injector = Guice.createInjector(new BillingModule());
    BillingService billingService = injector.getInstance(BillingService.class);
    ...
  }
研发流程后端开发工具,提示功能开发效率 后端开发工具 立即下载

相关推荐

机器人具有扰动抑制功能的有限时间基于方位角的领航者-跟随者编队控制(Matlab代码实现)

内容概要:本文档标题为《Plecs全桥LLC谐振变换器仿真模型.txt》,但实际内容并未涉及该主题的具体技术细节或仿真建模过程。相反,文档实质是一份由科研服务团队发布的跨学科资源目录,集中展示了大量基于Matlab、Simulink、Python、PSCAD等平台实现的科研项目与算法开发案例,涵盖电力系统、无人机路径规划、微电网优化、状态估计、信号处理、车间调度、图像处理、通信技术、雷达追踪、智能优化算法等多个工程技术领域。每个条目以“【】”标注研究主题,并注明“Matlab代码实现”“Python代码实现”等形式,表明其为可提供技术支持与代码资源的服务项目。文档末尾频繁出现“完整资源下载:公众号——荔枝科研社”及百度网盘链接,明确体现出其作为科研辅助服务推广与引流工具的功能属性。; 适合人群:面向电气工程、自动化、控制科学与工程、计算机科学、智能制造、新能源、航空航天、通信工程及相关交叉学科的研究生、高校教师、科研人员及企业研发工程师。; 使用场景及目标:①为科研人员提供课题选题、技术路线设计与算法实现的参考范例;②辅助学生或研究人员完成课程设计、毕业论文、项目仿真与算法复现任务;③作为第三方技术服务团队的能力展示目录,便于潜在客户快速了解其在多领域提供的定制化仿真与算法开发服务范围。; 阅读建议:此文档并非传统意义上的学术论文或技术教程,而是一份高度碎片化、广告性质浓厚的资源索引清单。读者应忽略其误导性的文件名,将其视为一个综合性科研技术服务目录,重点关注自身研究方向相关的条目,并通过文末提供的公众号或网盘链接进一步获取具体代码与资料。同时,需注意甄别资源的技术质量、原创性与适用性,避免盲目依赖外部服务。

GitHub上那些值得一试的JAVA开源库

作为一名程序员,你几乎每天都会使用到GitHub上的那些著名Java第三方库,比如Apache Commons,Spring,Hibernate等等。除了这些,你可能还会fork或Star一些其他的开源库,但GitHub上的库实在太多了,以至于对于个人来说,你很难有时间去发现并了解那些不断加入的新库,而它们却往往能在一些新兴领域中给你提供帮助。 我一直使用JAVA来写后端应用,平时也会关注一...

轻耘智科技CTO 尤胜荣 的专栏 738

【Flink cdc】Data row is smaller than a column index, internal schema representation is probably xxx

翻译一下:当scan.startup.mode=EARLIEST_OFFSET时,如果在最早的offset之后表结构有过变化就无法支持。原因应该是在binlog 的earliest_offset之后,表结构被修改过。我的解决方案:source配置中使用。mysql source配置使用。,以时间戳为消费依据。

integrity 2085

程序员的量化交易之路(1)----规划开篇

其实,一直对量化交易有一定的理解和情节。早在中大读研究生的时候实验室师兄,已经去了中国平安核心投资团队,做高频交易研究的国源师兄的影响,就开始对金融世界产生了浓厚的兴趣。看了丁磊编著的《量化投资--策略与技术》和艾琳.奥尔德里奇的《高频交易》,反复的看,但是都入不了味,现在回过头来想,一个连股都不炒的人怎么可能入味呢。对一些金融的基本概念都不懂。 2013年7月出社会工作后,在10月份确

MiniMicall的专栏 1万+

MOLDFLOW 2012模流分析基础到实战视频教程

├ 1第一讲MF软件安装与界面定制及模流前期准备工作及分析流程介绍 ├ 2第二讲MF建模工具条命令讲解与图层的运用 ├ 3第三讲MF网格类型与适应范围及网格划分、诊断、修复与统计 ├ 4第四讲MF中CAD doctor 模块对导入模型的修复方法与实例 ├ 5第五讲MF中常见各种流道浇口及水路的建模方法与外部导入方法上 ├ 6第六讲MF产品模型导入CAD DOCTOR与修复 ├ 7第七讲MF分析序列设定与网格的划分与诊断及修复 ├ 8第八讲MF材料选择与成型工艺参数设定 ├ 9第九讲MF创建浇注系统:主流道、

QQ_1987083845的博客 2545

深入理解命名实体识别(NER)

命名实体识别(NER,Named Entity Recognition)是自然语言处理(NLP)中的一项重要技术,用于从文本中识别出特定类型的实体,并将这些实体分类到预定义的类别中。实体通常包括人名、地名、组织名、日期、时间、数量、货币等。例如,在句子“Barack Obama was born in Hawaii in 1961”中,NER任务的目标是识别“Barack Obama”作为人名,“Hawaii”作为地名,以及“1961”作为日期。

AngelCryToo的专栏 4641

程序员的量化交易之路(33)--QuantConnect之案例1

转载需注明:http://blog.youkuaiyun.com/minimicall ,http://cloudtrade.top/ 分析Cointrader有一定层度了,发现它毕竟不是一个产品,没有得到验证。在架构、编码等方面都非常的不规范。 想编写一个云交易平台,任道而重远。我们需要参照一些成熟的架构。 Quantopian的zipline不行,因为我就是看到它不行,所以才去分析Cointrade

MiniMicall的专栏 7596

Stata实战:DID平行趋势检验完整操作指南(附reghdfe+coefplot代码)

本文提供了一份使用Stata进行DID平行趋势检验的完整实战指南。文章详细讲解了从数据准备、生成相对时间变量,到利用reghdfe命令构建动态效应模型,以及使用coefplot命令进行结果可视化的全流程操作。核心在于通过检验政策前交互项的显著性,验证处理组与对照组是否满足平行趋势假设,为后续因果推断奠定可靠基础。

weixin_29231725的博客 1381

程序员的量化交易之路(2)----Esper文档学习之技术概览(1)

转载请注明出处:http://blog.youkuaiyun.com/minimicall/ 在接下来的20个工作日中,我将坚持翻译或者略翻译Esper的官方文档。 为什么需要学习Esper,因为我们需要理解复合事件处理 Complex Event Processing (CEP)。在量化交易系统中,CEP是必不可少的。它负责处理海量的实时事件。 关于CEP更多知识,大家可以翻阅网络相关资料。我

MiniMicall的专栏 6406

力软敏捷开发框架源码7.0.6旗舰版 JNPF开发平台3.4.5 企业版 旗舰版

JNPF作为作为一款深受用户喜爱的低代码产品,凭借雄厚的科研技术力量、丰富的软件开发项目经验、严谨的项目开发流程和高质量的售后服务,已成功帮助千家企业完成数字化项目,建立了覆盖不同行业客户和不同发展阶段的软件产品服务体系。

huoooos0的博客 1840

【阿里云大模型高级工程师ACP习题集】2.5 优化RAG应用提升问答准确度(⭐️⭐️⭐️ 重点章节!!!)

【摘要】这是我精心整理出对应的习题集,里面足足有 30 道题目,从基础概念到深度拓展,全方位覆盖章节重点、难点。不管你是想检验自己的学习成果,还是想针对薄弱环节进行强化训练,它都能完美适配!

davidkorhenn的博客 1107

程序员的量化交易(34)--QuantConnect_Lean如何定义Indicator指标2

转载需注明出处:http://blog.youkuaiyun.com/minimicall,http://cloudtrade.top/ 指标(Indicator)由三大关键组件组成: 1. 实现你指标的类 2. 在ACAlgorithm基类中的Helper方法,用于简化对你指标实现的调用。 3. 测试方法用于测试指标的表现。 为了实现一个指标,上述所有组件需要实现。下面的教程会带你浏览这些

MiniMicall的专栏 5807

【Python图像处理局部放大】输入图像,选择两处不同的区域进行放大操作,然后将原始图像、处理后的两个区域以及标记合成新图像进行展示

Python图像处理与区域放大连接标记:选择特定区域并对其进行放大操作,然后将原始图像、处理后的两个区域进行标记后的新图像保存到文件中。

qq_35831906的博客 2243

程序员的量化交易之路(10)--金融概念Stop-limit Order

转载需注明:http://blog.youkuaiyun.com/minimicall,http://cloudtrade.top Market Order: 市价订单。就是如果你下单后,基本上会马上执行的,该订单价格就是下单后的市场价格。 Limit order:限价订单。这个也容易理解,就是限定一个价格买入和卖出。比如某股票市价可能是15,你希望大跌后买入,你想设定10刀,这时候就用limit

MiniMicall的专栏 5585

2026年【江苏“信息与未来”编程思维】真题及题解(T6:桌面游戏)

2026年【江苏“信息与未来”编程思维】真题及题解(T6:桌面游戏)

王老师青少年编程 535

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

程序员的量化交易之路(3)--Esper事件Event(2)

第二章 EventPresentation 事件描述 欢迎转载学习,但转载须注明出处:http://blog.youkuaiyun.com/minimicall,尊重劳动成果,版权归我。 这一章用于说明事件描述和建模的方法。   Esper 使用event type(事件类型)来描述事件的类型信息。 你的应用可以在Esper启动时或者在运行时通过API或者EPL语法来添加事件类型。具体参见16.4节

MiniMicall的专栏 4188

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

程序员的量化交易之路(35)--Lean之DataFeed数据槽3

转载需注明出处:http://blog.youkuaiyun.com/minimicall,http://cloudtrade.top/ Lean引擎的模块划分非常的规范。其中DataFeed是数据槽,就是供应数据的模块。 1. IDataFeed 接口 模块的接口为: namespace QuantConnect.Lean.Engine.DataFeeds { /// //

MiniMicall的专栏 3484

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

程序员的量化交易之路(9)--金融系统概念basis

转载需注明出处:http://blog.youkuaiyun.com/minimicall?viewmode=contents , http://cloudtrade.top basis:基差 常见的几个概念有: Adjusted basis, the net cost of an asset after adjusting for various tax-related i

MiniMicall的专栏 3479

程序员的量化交易之路(23)--金融概念Margin保证金

转载需要注明出处:http://blog.youkuaiyun.com/minimicall?viewmode=contents,http://cloudtrade.top Margin:保证金 英文解释:http://www.investopedia.com/terms/m/margin.asp 我们把它贴上,并加上我个人的翻译。(翻译不好莫怪) DEFINITION OF 'MARGIN'(m

MiniMicall的专栏 3354

程序员的量化交易之路(39)--Lean之BacktestingRealTimeHandler回测实时时间事件处理7

转载需注明出处:http://blog.youkuaiyun.com/minimicall?viewmode=contents,http://cloudtrade.top/上一节已经说明了实时事件和处理接口。这一节需要说明回测里面的实时事件处理。主要是开启一个新的线程来处理定时事件。例如每天开市的时候的事件和每天闭市时候触发的事件。还有你可以定义任意一个给定时间的事件。下面我们通过代码来说 明问题/* *

MiniMicall的专栏 3266

程序员的量化交易之路(4)--Esper之事件(3)

欢迎转载学习,但转载须注明出处:http://blog.youkuaiyun.com/minimicall,尊重劳动成果,版权归我。 这一节中我们继续学习Esper的事件部分内容。 对应官方的文档为2.4-2.5 2.4 碎片及碎片类型(Fragment and Fragment Type) 有些情况,一个事件的某个属性本身又是一个事件。Esper对这种称作为fragment(碎片)和碎片类型

MiniMicall的专栏 3150

程序员的量化交易之路(7)--金融概念Positon

转载需说明出处:http://blog.youkuaiyun.com/minimicall?viewmode=contents Position 仓: long postion:多头 open long position :开多头仓 close long poition :  平(闭)多头仓 short positon:空头 open short position :开空头仓 close

MiniMicall的专栏 3027

程序员的量化交易之路(8)---金融概念Listing&delisting

转载需注明来源:http://blog.youkuaiyun.com/minimicall?viewmode=contents http://cloudtrade.top/ Listing:挂牌交易 Delisting:停止上市交易(退市)

MiniMicall的专栏 2913

程序员的量化交易之路(30)--Cointrader之ConfigUtil(17)

转载须注明出处:http://blog.youkuaiyun.com/minimicall?viewmode=contents,http://cloudtrade.top/ 一个完整的系统,必然会涉及到配置文件。配置文件可以是xml、属性文件等形式。大多数而言我们并不需要重写配置读取解析模块,只需要使用开源的即可,这里使用的是apapche.commons.configuration的。 我们这里要说的是

MiniMicall的专栏 2846

程序员的量化交易之路(36)--Lean之数据读取SubscriptionDataReader4

转载需注明出处:http://blog.youkuaiyun.com/minimicall?viewmode=contents, http://cloudtrade.top 数据读取需要定义一个读者。直接见下面代码: namespace QuantConnect.Lean.Engine.DataFeeds { /******************************************

MiniMicall的专栏 2835
上一篇: 程序员的量化交易之路(11)--命令参数解析库JCommonder学习
下一篇: 程序员的量化交易之路(13)--Cointrader类图(1)
minimicall
博客等级 码龄18年 407粉丝 174原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值