我有一种方法,可以计算某一供应商为某一商品所获得的价格。
简化后,它检查我们是否有特定供应商的价格,如果没有,检查我们是否有该特定供应商组的价格,如果没有得到正常价格。
这里有几个可能的结果:
Success
nothing found
MultiplePricesFound = a mistake in our data
Vendor is in multiple groups = user needs to pick the group因此,我不只是返回一个double、null或-1来表示错误,而是构建了一个类似于下面的类。我不想输入我的结果,所以我把它变成了一个枚举。
public class PriceResult {
double Value;
PriceResults Result;
Dictionary<int, double> VendorGroupPriceDictionary;
}
public enum PriceResults {NothingFound, Success, MultipleVendorGroups, MultiplePrices }该词典包含多个供应商组及其相应的价格。
这会管用的。但是,我创建了一个新的类和一个枚举,这可能正是一个方法所使用的。我觉得这有点过分了。
我想知道这是否表明了什么?我需要简化计算方法吗?
发布于 2019-12-05 06:26:44
但是,我创建了一个新的类和一个枚举,这可能正是一个方法所使用的。我觉得这有点过分了。
不一定。创建一个提供有用抽象的小助手类通常是一种明智的方法。这个类有时只是一个DTO,没有任何行为,这不会产生太多的开销(通常它有助于减少样板代码、长参数列表和添加注释的必要性)。
对于实际的例子:如果这个抽象是有用的,那么很难不看到代码,如果这个抽象是有用的,那么它实际上将使用PriceResult。我只能对如何简化这个问题做一些有教养的猜测。
在这里看起来可疑的是这类中的冗余,以及将计算的成功与不同类型的价格表混合在一起。
NothingFound或MultiplePrices,属性Value和VendorGroupPriceDictionary可能没有有意义的值?因此,我想在这种情况下使用PriceResult对象完全没有意义吗?因此,很可能将成功状态分离为单独的枚举,并建模类似于CalculationSuccess TryCalcPriceForVendor(供应商供应商,out PriceResult priceResult)的计算函数,其中枚举看起来像枚举CalculationSuccess { success,NothingFound,MultiplePrices} --如果成功状态评估与处理有效的PriceResult对象分开进行,则此设计是有意义的。如果情况不是这样,而且PriceResult需要元信息,说明它在不同的地方是“无效的”,最好还是坚持旧的设计。发布于 2019-12-06 16:16:21
我会尝试找一个不同的设计。
这并不是因为它很复杂,可能是因为您有一种复杂的行为(我不能对此发表评论,因为对此还不够了解),而是因为您返回的这包数据会将所有的评估逻辑推到调用者身上。打电话的人必须知道你做什么、填写什么数据结构、它们是如何相关的复杂细节。基本上是一切。
相反,您可以做的是提供调用者真正想要的确切功能。它想要比较价格吗?它想选择价格吗?它想打印它吗?首先,隐藏结果的数据并提供与业务相关的方法。比如FindPrice(VendorSelector),FindSinglePrice()等你在另一边需要的东西。
如果调用方真的想知道这个结果对象所拥有的一切,那么调用方的内部逻辑实际上控制了您的服务的内部逻辑。换句话说,它们可能是紧密耦合的,这是不好的。
发布于 2019-12-10 03:09:38
我的印象是你还在按程序思考。我建议以面向对象的方式来思考这个问题。您不是在调用返回数据的东西;而是创建一个名为"Quote“的数据对象,该对象包含一些逻辑。
此外,您还需要一个接口,以便您的代码可以是实心。
class Quote : IQuote
{
}首先,您需要一些方法来创建一个引用。您可以使用构造函数,如果太复杂,您可以编写一个工厂。
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);
}
}当计算报价时,您将需要公开各种内容。这是您在接口中放置的内容,然后在类中实现。我不知道您的实现,但我可以猜测您的接口可能是什么样子:
interface IQuote
{
bool IsPriceAvailable { get; }
decimal Price { get; }
bool HasMultiplePrices { get; }
bool HasMultipleVendors { get; }
bool IsProductAvailable { get; }
}现在,当您需要使用这个类时,逻辑是简单易懂的:
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.
}https://softwareengineering.stackexchange.com/questions/402070
复制相似问题