谁能为我提供一些小建议?我真的很想知道我的缺点是什么以及我该如何改善。
面试问题在这里,我的答案在这里。
我只在这里引用一些内容我的源代码。
Program.cs
class Program
{
static void Main(string[] args)
{
////////////////////////////////////////////////////////////////////////////////
// Story 1. As a donor
Console.WriteLine("-------------------------------------- Story1\r\n");
//1.1. Craete Tax Calculator
decimal taxRate = 20;
ITaxCalculator taxCalculator = new TaxCalculator(taxRate);
//1.2. Display GiftAid
Console.WriteLine("Please enter donation amount:");
decimal Amount = decimal.Parse(Console.ReadLine());
Console.WriteLine("=> Your Gift Aid is: {0} \r\n\r\n", taxCalculator.GetGiftAid(Amount));
////////////////////////////////////////////////////////////////////////////////
// Story 2. As a site administrator
Console.WriteLine("-------------------------------------- Story2\r\n");
//2.1. Create using factory pattern
taxCalculator = new TaxCalculatorFactory().GetObject(new TaxRepository());
Console.WriteLine("Please enter donation amount:");
Amount = decimal.Parse(Console.ReadLine());
//2.2. Display GiftAid
Console.WriteLine("=> Your Gift Aid is: {0} \r\n\r\n", taxCalculator.GetGiftAid(Amount));
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
}
计算器类
interface ITaxCalculatorFactory
{
ITaxCalculator GetObject(decimal taxRate);
ITaxCalculator GetObject(ITaxRepository taxRepo);
}
public class TaxCalculatorFactory
{
public TaxCalculatorFactory()
{
}
public ITaxCalculator GetObject(decimal dAmount)
{
return new TaxCalculator(dAmount);
}
public ITaxCalculator GetObject(ITaxRepository taxRepo)
{
return new TaxCalculatorByData(taxRepo);
}
}
public interface ITaxCalculator
{
decimal GetGiftAid(decimal dAmount);
}
public class TaxCalculator : ITaxCalculator
{
private readonly decimal _taxRate;
public TaxCalculator(decimal taxRate)
{
_taxRate = taxRate;
}
public decimal GetGiftAid(decimal dAmount)
{
var gaRatio = _taxRate / (100 - _taxRate);
return dAmount * gaRatio;
}
}
public class TaxCalculatorByData : ITaxCalculator
{
private readonly ITaxRepository _taxRepo;
public TaxCalculatorByData(ITaxRepository taxRepo)
{
_taxRepo = taxRepo;
}
public decimal GetGiftAid(decimal dAmount)
{
var gaRatio = _taxRepo.GetTaxRate() / (100 - _taxRepo.GetTaxRate());
return dAmount * gaRatio;
}
}
/>测试代码
[TestFixture]
public class GetAidTest
{
////////////////////////////////////////////////////////////////////////////////
// Story 1. As a donor
[Test]
public void Story1_Should_Return_TwentyFive_From_GiftAid()
{
/////////////////////////////////////////////////////////////
// Setup
decimal taxRate = 20;
decimal donationAmount = 100;
decimal valueExpected = 25;
var taxCalculator = new TaxCalculator(taxRate);
/////////////////////////////////////////////////////////////
// Action
var result = taxCalculator.GetGiftAid(donationAmount);
/////////////////////////////////////////////////////////////
// Verify the result
Assert.AreEqual(valueExpected, result, "Should return 25");
}
////////////////////////////////////////////////////////////////////////////////
// Story 2. As a administrator
[Test]
public void Story2_Should_Store_TaxRate_Fourty_And_Return_GiftAid()
{
/////////////////////////////////////////////////////////////
// Setup
decimal taxRate = 40;
decimal donationAmount = 100;
decimal valueExpected = 66.67m;
var repository = new Mock<ITaxRepository>();
repository.Setup(r => r.GetTaxRate()).Returns(taxRate);
repository.Setup(r => r.Save(It.IsAny<decimal>())).Verifiable();
ITaxCalculator taxCalculator = new TaxCalculatorFactory().GetObject(repository.Object);
/////////////////////////////////////////////////////////////
// Action
var result = decimal.Round(taxCalculator.GetGiftAid(donationAmount), 2, MidpointRounding.AwayFromZero);
/////////////////////////////////////////////////////////////
// Verify the result
Assert.AreEqual(valueExpected, result, "Should return 25");
}
}
#1 楼
访谈定义了4个用户案例,但据我所知,您实际上只实现了2个。
故事3表示,该数量应四舍五入到小数点后两位。您可以通过将舍入作为结果(作为单元测试的一部分)对结果进行舍入来完成,而单元测试会遗漏故事的重点(恕我直言)。这个故事说了一些有关“应该四舍五入到小数点后两位”的内容,因此它可能需要一个税务计算器视图,该视图根据要求显示结果。
您应该避免使用两种方法来创建
TaxCalculator
对象。如果您有工厂,那么通常不希望用户通过new
实例化新对象。如果我要使用您的班级,我将不知道该使用哪种方法,以及是否存在差异。 br />在工厂中,我希望使用dAmount
而不是Create
作为方法名称。 删除
GetObject
工厂方法-您可以在单元测试中传递模拟存储库,该存储库始终返回固定金额。#2 楼
TaxCalculator
和TaxCalculatorByDB
包含相同的逻辑:仅用于测试。这是一种测试气味:生产中的测试逻辑。我将使用模拟代替它。代码本身:
var gaRatio = _taxRepo.GetTaxRate() / (100 - _taxRepo.GetTaxRate());
return dAmount * gaRatio;
尝试解释为什么可行。为什么要返回25?否则只是噪音。
每个故事可以编写多个测试。例如,在无效输入上会发生什么或应该发生什么?
我认为
TaxCalculator
应该只包含一件事:获取捐赠金额并打印答案。故事1-4的要求应该结合起来。我认为实现故事4意味着程序
应该询问事件类型,或者
为每种事件类型打印结果。
我找不到针对Story 3和Story 4的任何测试。
我现在无法进行测试(我没有使用C#编译器),但我认为故事4的值也应四舍五入。
GetObject(decimal taxRate)
方法似乎不必要。故事2尚不清楚,但是由于没有关于管理员如何更改税率的任何细节,我想他们是用SQL命令(例如)而不是通过程序来实现的。#3 楼
除了以前的出色文章,而且可能会挑剔,但为什么要添加大量评论?////////////////////////////////////////////////////////////////////////////////
似乎不必要,如果我正在审查,那肯定会让我失望
注释中有错别字,同样,错别字也可能是挑剔的,但我肯定会认为“在编写代码时要特别注意”(我接受因为面试的情况不是正常的工作环境,所以可能有点苛刻!)。
我也建议不要使用两种方法来创建计算器。该示例似乎不需要工厂。
我想当您只有一个税率计算器要处理时,将其放进工厂可能会违反YAGNI原则。
编辑:
进一步挑剔!
您有一个块级变量'Amount'用大写A表示,这是我不希望的,这与其余变量不一致。
评论
\ $ \ begingroup \ $
+1在“在家做”测试中,没有任何理由可以格式化不一致或错别字。当他们给您时间时,将其擦亮。 :)
\ $ \ endgroup \ $
– David Harkness
2014-2-17在13:35
\ $ \ begingroup \ $
是的,在商业环境中,当人们将某些东西一推出功能就推出时,实际上这是相当普遍的,而不是花更多的时间重新阅读并确保将其清理干净。我个人发现您对代码的了解在功能正常运行之后已达到最大程度,这是重构和清理的最佳时间。
\ $ \ endgroup \ $
– Dougajmcdonald
17年1月14日在9:03
评论
您是否从公共仓库提交了拉取请求? “如果您有一个付费的GitHub帐户,请随时创建一个私人仓库...并向我们发送请求请求。” [他们的重点]“这项作业平均需要30分钟左右。” 30分钟内有4个用户故事。他们必须有非常好的程序员。