首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >复杂结果的计算方法

复杂结果的计算方法
EN

Software Engineering用户
提问于 2019-12-04 18:03:22
回答 3查看 264关注 0票数 2

我有一种方法,可以计算某一供应商为某一商品所获得的价格。

简化后,它检查我们是否有特定供应商的价格,如果没有,检查我们是否有该特定供应商组的价格,如果没有得到正常价格。

这里有几个可能的结果:

代码语言:javascript
复制
Success
nothing found
MultiplePricesFound = a mistake in our data 
Vendor is in multiple groups = user needs to pick the group

因此,我不只是返回一个double、null或-1来表示错误,而是构建了一个类似于下面的类。我不想输入我的结果,所以我把它变成了一个枚举。

代码语言:javascript
复制
public class PriceResult {
   double Value;
   PriceResults Result;
   Dictionary<int, double> VendorGroupPriceDictionary;
}
public enum PriceResults {NothingFound, Success, MultipleVendorGroups, MultiplePrices }

该词典包含多个供应商组及其相应的价格。

这会管用的。但是,我创建了一个新的类和一个枚举,这可能正是一个方法所使用的。我觉得这有点过分了。

我想知道这是否表明了什么?我需要简化计算方法吗?

EN

回答 3

Software Engineering用户

发布于 2019-12-05 06:26:44

但是,我创建了一个新的类和一个枚举,这可能正是一个方法所使用的。我觉得这有点过分了。

不一定。创建一个提供有用抽象的小助手类通常是一种明智的方法。这个类有时只是一个DTO,没有任何行为,这不会产生太多的开销(通常它有助于减少样板代码、长参数列表和添加注释的必要性)。

对于实际的例子:如果这个抽象是有用的,那么很难不看到代码,如果这个抽象是有用的,那么它实际上将使用PriceResult。我只能对如何简化这个问题做一些有教养的猜测。

在这里看起来可疑的是这类中的冗余,以及将计算的成功与不同类型的价格表混合在一起。

  • 如果状态为NothingFoundMultiplePrices,属性ValueVendorGroupPriceDictionary可能没有有意义的值?因此,我想在这种情况下使用PriceResult对象完全没有意义吗?因此,很可能将成功状态分离为单独的枚举,并建模类似于CalculationSuccess TryCalcPriceForVendor(供应商供应商,out PriceResult priceResult)的计算函数,其中枚举看起来像枚举CalculationSuccess { success,NothingFound,MultiplePrices} --如果成功状态评估与处理有效的PriceResult对象分开进行,则此设计是有意义的。如果情况不是这样,而且PriceResult需要元信息,说明它在不同的地方是“无效的”,最好还是坚持旧的设计。
  • 供应商可能被放入自己的供应商组中,只有一个元素,并且可能有类似于"DefaultVendor“或"NonVendor”类型的供应商ID来关联项目的“正常价格”。如果您可以这样建模您的系统,它可能允许您消除不同结果表示的情况之间的区别,一个供应商组,一个供应商或独立于供应商的价格。这将导致公共类PriceResult { Dictionary VendorGroupPriceDictionary;},其中本词典将只包含单个供应商的一个条目或“正常”价格。但是,此更改可能也会对系统的其他部分造成更改(或至少允许更改),因此再次有必要首先研究如何使用此代码来确定这是否会给您带来任何好处。
票数 2
EN

Software Engineering用户

发布于 2019-12-06 16:16:21

我会尝试找一个不同的设计。

这并不是因为它很复杂,可能是因为您有一种复杂的行为(我不能对此发表评论,因为对此还不够了解),而是因为您返回的这包数据会将所有的评估逻辑推到调用者身上。打电话的人必须知道你做什么、填写什么数据结构、它们是如何相关的复杂细节。基本上是一切。

相反,您可以做的是提供调用者真正想要的确切功能。它想要比较价格吗?它想选择价格吗?它想打印它吗?首先,隐藏结果的数据并提供与业务相关的方法。比如FindPrice(VendorSelector)FindSinglePrice()等你在另一边需要的东西。

如果调用方真的想知道这个结果对象所拥有的一切,那么调用方的内部逻辑实际上控制了您的服务的内部逻辑。换句话说,它们可能是紧密耦合的,这是不好的。

票数 0
EN

Software Engineering用户

发布于 2019-12-10 03:09:38

我的印象是你还在按程序思考。我建议以面向对象的方式来思考这个问题。您不是在调用返回数据的东西;而是创建一个名为"Quote“的数据对象,该对象包含一些逻辑。

此外,您还需要一个接口,以便您的代码可以是实心

代码语言:javascript
复制
class Quote : IQuote
{
}

首先,您需要一些方法来创建一个引用。您可以使用构造函数,如果太复杂,您可以编写一个工厂。

代码语言:javascript
复制
class Quote : IQuote
{
    public Quote(Vendor vendor, Product product)
    {
        //Compute the quote
    }
}

class QuoteFactory : IQuoteFactory
{
    public IQuote GetQuote(Vendor vendor, Product product)
    {
        return new Quote(vendor, product);
    }
}

当计算报价时,您将需要公开各种内容。这是您在接口中放置的内容,然后在类中实现。我不知道您的实现,但我可以猜测您的接口可能是什么样子:

代码语言:javascript
复制
interface IQuote
{
    bool IsPriceAvailable { get; }

    decimal Price { get; }

    bool HasMultiplePrices { get; }

    bool HasMultipleVendors { get; }

    bool IsProductAvailable { get; }
}

现在,当您需要使用这个类时,逻辑是简单易懂的:

代码语言:javascript
复制
IQuote quote = _quoteFactory.GetQuote(vendor, product);
if (quote.IsPriceAvailable)
{
    Display("The price is {0:#.00}", quote.Price);
}
else
{
    Display("Couldn't come up with a quote.");
    if (!quote.IsProductAvailable) 
    {
        Display("Product is not available to this vendor.")'
        return;
    }    
    if (quote.HasMultiplePrices) 
    {
        Display("Could not provide quote because the product is available under several price points.");
        return;
    }    
    //etc.
}
票数 0
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/402070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档