我正在编写的代码(MyService)包括每个客户在处理过程中的特定点插入自己的计算器的能力。这是为了允许自定义业务规则。在计算的时候,我们知道了各种各样的事情,其中一些可能与计算有关。将为一组特定的输入参数创建MyService并运行一次。
我的计划是使用依赖注入在构造函数中为MyService提供一个calculator。这允许不同的用户插入他们自己的calculator。calculator将退还一笔金额,表示对这一特定MyService运行的附加费。其他人将实现各种计算器,我需要能够更新我的代码而不破坏他们的代码。即。保持向后的可兼容性。
我遇到的问题是,不同的计算器实现需要不同的参数。在创建MyService时,不能将这些参数注入计算器中,因为它们在MyService中发生了某些处理。
在MyService的特定实例化中,将只调用一次计算器。因此,在一个极端情况下,所有参数都可以在构造函数中传递,并且有一个没有返回答案的参数的方法。另一方面,所有参数都在方法调用中传递。
AlwaysZeroCalculator可能只是return 0,所以不需要参数。PercentageCalculator需要amount才能应用百分比。一个更复杂的问题需要amount和customerNumber。我们可以假设calculator可能需要的任何东西都是MyService在运行时知道的(或者它本身可以被注入到calculator实现中,比如hibernate会话)。
我如何实现这一点?
以下是一些选择和问题:
ICalculator、ICalculatorWithAmount、ICalculatorWithAmountAndCustomerNumber等)。MyService将需要查看它实现的calculator接口,将其转换到该接口,然后调用适当的calculate(..)方法。calculator也依赖于一切。MyService,这些接口都需要这些接口之一。calculatorFactory而不是calculator。工厂将接受所有可能的参数,并创建一个只有正确的计算器。这似乎只是把问题转移到其他地方,而没有解决它。有更好的办法吗?
发布于 2011-04-06 08:09:22
这是两个问题:
第一个是简单的--所有的计算器都做同样的事情,可以有相同的界面.后者是要解决的问题,因为它需要为每个计算器实例提供不同的参数。
从你的名单上看,工厂是最好的解决方案。它并没有把问题转移到其他地方,而是解决了问题。每个工厂都知道它的计算器,并且知道它需要什么参数。所以工厂依靠计算器。使用工厂创建计算器只会创建一个依赖于创建计算器,而不是它的参数或计算器本身,它可以是所有工厂实现的工厂接口的一部分。
为工厂提供参数可以通过属性注入来解决,使用您选择的任何方法-- Spring在这方面肯定不错。
反过来,应用程序只知道如何使用计算器,因此取决于通用计算器接口,而不是任何特定的计算器实现。
发布于 2011-04-06 06:09:49
假设你在用弹簧..。也许bean标记的工厂bean和工厂方法属性可能是有用的。
伪码..。
<bean id="calculator1"
factory-bean="calculatorFactory"
factory-method="getAlwaysZeroCalculator">
<!--AlwaysZeroCalculator args go here -->
</bean>
<bean id="calculator2"
factory-bean="calculatorFactory"
factory-method="getPercentageCalculator ">
<!--PercentageCalculator args go here -->
</bean>发布于 2015-09-03 10:52:43
我总是很难让运行时依赖以一种优雅的方式使用依赖项注入。
但是,我会对您的“制作不同的接口”计划进行修改。
每个计算器都会定义自己的接口,比如IAlwaysZeroCalculatorParameters、IPercentageCalculatorParameters等等。
然后,您的MyService类可以实现所有这些接口,然后将自己传递给每个计算器。
实现这一目标的框架开销非常小,这意味着每个计算器都简明地表达了它所需要的内容。在类似的情况下,它非常适合我,尽管在您的特定情况下(在您无法控制插件的情况下),这意味着每次有人实现一个新的计算器(以便它可以实现新的接口)时,您都必须释放MyService。如果需要的话,我可能会用鸭子的打字来解决这个问题。
https://stackoverflow.com/questions/5562051
复制相似问题