【发布时间】:2019-11-15 12:24:47
【问题描述】:
我有一个看起来像这样的接口 TaxCalculator
公共接口 TaxCalculator { int DEFAULT_AMOUNT_FOR_RATE_CALCULATION = 100;
/**
*
* @param cart the cart to calculate taxes for. Right now we are only calculating using the total taxable amount, but when we implement
* charging taxes properly, we should use data from the cart like line-item amounts, and types.
* @return the tax rate to charge for this cart
*/
SalesTaxRates getSalesTaxes(ShoppingCart cart, Address address);
SalesTaxRates getSalesTaxes(ShoppingCart cart, String zipcode);
SalesTaxRates getSalesTaxes(Order order) throws Exception;
/** Since taxes ideally get calculated using information like line-item amounts, and types, you cannot get an accurate
* rate from the taxable amount alone. This is a function we want to support, however, on pages such as calculate payboo savings.
*
* @param taxableAmount the amount to calculate taxes for
* @return a quote for what taxes will likely come out to
*/
SalesTaxRates getSalesTaxes(double taxableAmount, String zipCode);
SalesTaxRates getSalesTaxes(String zipCode);
SalesTaxRates getSalesTaxes(Address address);
SalesTaxRates getSalesTaxes(double taxableAmount, Address address);
default SalesTaxRates getSalesTaxes(double taxableAmount, ZipCode zipCode){
return getSalesTaxes(taxableAmount,zipCode.getZipCode());
}
default SalesTaxRates getSalesTaxes( ZipCode zipCode){
return getSalesTaxes(zipCode.getZipCode());
}
default SalesTaxRates getSalesTaxes(ShoppingCart cart, ZipCode zipcode){
return getSalesTaxes(cart,zipcode.getZipCode());
}
我有两种计算税收的实现,一种用于 api,一种是内部系统 我有第三个实现充当代理 - 在每次调用时它都像这样有效地工作
@Override
public SalesTaxRates getSalesTaxes(ShoppingCart cart, Address address)
{
Map<String,SalesTaxRates> cache = getTaxSessionCache();
String cacheKey = generateCacheKey(cart,address);
if(cache.containsKey(cacheKey))
return cache.get(cacheKey);
TaxCallable taxCallable = new TaxCallable() {
@Override
public SalesTaxRates call() {
return this.getTaxCalculator().getSalesTaxes(cart,address);
}
};
SalesTaxRates taxRates = callTaxCalculators(taxCallable);
if(taxRates.isCacheable())
cache.put(cacheKey, taxRates);
return taxRates;
}
以及定义的方法:
private static SalesTaxRates callTaxCalculators(TaxCallable callable)
{
for (TaxCalculator taxCalculator: TaxEngine.getTaxCalculators())
{
FutureTask<SalesTaxRates> futureTask = new FutureTask<>(callable.setTaxCalculator(taxCalculator));
new Thread(futureTask).start();
try {
SalesTaxRates taxRates = futureTask.get(getTaxCalculatorTimeout(), TimeUnit.MILLISECONDS);
if(taxRates!=null && taxRates.isCalculated())
{
BHLogger.info("Used taxcalculator: " + taxRates.getTaxEngine() + "rate: " + taxRates.getTotalTaxRate());
return taxRates;
}
} catch (Exception e) {
BHLogger.error(e);
}
}
BHLogger.error("ShoppingCart.calculteSalesTax","No taxCalculator calculated taxes correctly");
return SalesTaxRates.NOT_CALCULATED;
}
它检查缓存,看看它是否在那里,然后返回它。否则它调用转发消息并缓存它 所以这对于每个重载的方法来说似乎非常重复,但是我没有一种明显的方法来调用一个方法,因为缓存是不同的 我的经理建议我使用构建器模式。创建一个 TaxRequest 对象,该对象具有任何相关字段。它可以处理自己的缓存
我猜应该是这样的
class TaxRequest{
private Order order;
private Cart cart;
private Address address;
private String zipcode;
private SalesTaxRates send(TaxCalculator tc){
//check cache
//else
tc.getSalesTaxes(this);
//handlecaching
}
}
接口只需要一个方法,Forwarding类变得很简单 我猜 ApiTaxCalculator 实现现在需要通过这样的方法来处理这个问题
SalesTaxRates getSalesTax(TaxRequest taxRequest)
{
if(taxRequest.hasOrder()
returnGetSalesTaxes(taxRequest.getOrder);
//if has address and cart... if has only address... if has just a zip...
}
基本上,建议是使用构建器模式而不是方法重载 但最后一种方法对我来说似乎很尴尬, 建议这样做的另一个原因是,内部 taxCalculator 对订单的处理与仅对邮政编码的处理没有任何不同。理想情况下,它应该考虑项目类型或折扣等因素,但事实并非如此。它只是根据邮政编码查找费率 所以该类中有很多开销只是将其转发到该方法
有什么建议吗?
【问题讨论】:
-
不确定我是否可以关注你(这是相当大的文本),但你的基本接口只能有一个
String和WithZipCode重载,而WithZipCode是一个接口,将由ZipCode、Order等仅提供 getterString getZipCode()。然后,您的可调用对象只需要接受和缓存WithZipCode类型的对象。因为WithZipCode只有一个函数可以通过String来传递原始() -> zipCodeString。如果有不清楚的地方给我提个醒,我会提供示例代码 -
您可以将缓存留给
TaxCalculator,并基于TaxRequest构建缓存键。 -
对不起,如果我不清楚。这些方法非常不同。你提供的信息越多越好。例如,给一个订单,我可以看到哪些项目是应税的,你有什么折扣,你的运费等等。我不只是深入到邮政编码,这就是其中一个实现所发生的事情。但客户不应该知道这一点
-
这是给图书馆的吗?我要理智,他们不应该知道吗?他们可以检查代码
-
知道他们不必处理调用正确的函数?
标签: java design-patterns interface coding-style builder-pattern