题目如下:
这是一段用于计算多个几何形状面积之和的程序
- 指出程序段存在的不妥之处,并重构代码
- 在 1 的基础上增加一种可计算的几何形状类型三角形,其面积为 底×高×1/2
public class Shape
{
public int Type { get; set; }
public int Radius { get; set; }
public int Width { get; set; }
public int Length { get; set; }
}
public class ShapeCalculator
{
public static double CalculateTotalArea(List<Shape> shapes)
{
double totalArea = 0;
if (shapes != null && shapes.Count() > 0)
{
foreach (Shape shape in shapes)
{
if (shape.Type == 1)
{
totalArea += Math.PI * shape.Radius * shape.Radius;
}
else if (shape.Type == 2)
{
totalArea += shape.Length * shape.Width;
}
}
}
return totalArea;
}
}
我的回答是这样的:
interface ICalc
{
double GetAera();
}
class Circle : ICalc
{
public int Radius { get; set; }
public double GetAera()
{
return Math.PI * Radius * Radius;
}
}
class Rectangle : ICalc
{
public int Length { get; set; }
public int Width { get; set; }
public double GetAera()
{
return Length * Width;
}
}
class Triangle : ICalc
{
public int Bottom { get; set; }
public int Height { get; set; }
public double GetAera()
{
return Bottom * Height * 0.5;
}
}
class ShapeCalculator
{
public static double CalculateTotalArea(List<ICalc> shapes)
{
double totalArea = 0;
if (shapes != null)
{
totalArea = shapes.Sum(shape => shape.GetAera());
}
return totalArea;
}
}
凭我的水平和理解能力就只有写到这种程度了……有什么更好的写法吗?
1
across 2020-09-16 21:28:51 +08:00 via Android
我猜原意不止 oop,还要你改几个细节,比如 int 应该是 float,面积 float 精度就足够。
|
2
forgottencoast 2020-09-16 23:05:26 +08:00
源代码最主要的问题就是每增加一个 Shape,都要改动 CalculateTotalArea 方法。
写法很多,你这个写法可以了。 剩下的就是细节问题了,比如#1 所说的,Width 和 Length 用 int 肯定不妥。 CalculateTotalArea 接收的参数类型要更抽象一点,List<T>肯定不好。 你定义的接口 ICalc 命名太宽,和方法名 GetArea 不够匹配。 |
3
richards64 OP @forgottencoast CalculateTotalArea(IEnumerable<ICalc> shapes) 好一点?
|
4
andrewpsy 2020-09-17 00:15:59 +08:00 via Android
上面都说的很好了,还有个可能是面试官想测你知不知道 strategy pattern 。你要是想 over engineering 可以实现一下玩玩。
|
5
richards64 OP @andrewpsy 实际情况是面试官好像对我的回答没有什么异议,对我的 C#基础还是挺满意的,但是最后拒掉了我的理由是因为这个岗位需要精通 SQL 优化,这我就不会了……
|
6
yazoox 2020-09-17 08:29:05 +08:00
这就是“十动然拒”?
奇怪,如果岗位是对 SQL 技能有特别需求,一开始知道你不会(比如:简历),那还面试啥?这不是浪费大家时间么? |
7
Rwing 2020-09-17 08:48:50 +08:00
挺好的,我觉得 HR 只是不想招人,换公司继续面吧
|
8
forgottencoast 2020-09-17 09:28:48 +08:00
@richards64 #3
是的。 越抽象的接口适用范围越广,如果你用不到更具体接口的其他成员,就应该用更抽象的接口。 IEnumerable<T>是最抽象的接口了,所有的泛型集合都实现了它,一般设计时可以考虑先用它,除非它不符合需求,再考虑更具体的接口。 |
9
yamatamain 2020-09-17 09:35:36 +08:00
@richards64 总会有一个理由。
|
10
SWALLOWW 2020-09-17 09:45:43 +08:00
第一眼 shapes.Count()有问题...
|
11
beingWH 2020-09-17 09:57:28 +08:00
感觉问题不大。
|
12
beingWH 2020-09-17 10:11:35 +08:00
```
interface ICalc { float GetAera(); } class Circle : ICalc { public float Radius { get; set; } public float GetAera() { return Math.PI * Radius * Radius; } } class Rectangle : ICalc { public float Length { get; set; } public float Width { get; set; } public float GetAera() { return Length * Width; } } class Triangle : ICalc { public float Bottom { get; set; } public float Height { get; set; } public float GetAera() { return Bottom * Height * 0.5; } } static class ShapeCalculator { public static float CalculateTotalArea(this List<ICalc> shapes) { float totalArea = 0; if (shapes != null) { totalArea = shapes.Sum(shape => shape.GetAera()); } return totalArea; } } ``` |
13
kop1989 2020-09-17 10:20:37 +08:00
我有个想法不知道对不对。
觉得可以在你的基础上再添加一个 Shape 转换为 ICalc 实现类的逻辑。 因为从实际项目的角度讲,你再怎么重构,数据源也是不变的。 你这个重构最终丢了逻辑。既你把 ICalc 的实现类抉择抛给了调用 CalculateTotalArea 的人。 原来的数据源是 List<Shape>。现在传进来的还应该是 List<Shape>。 |
14
Caskia 2020-09-17 10:55:52 +08:00
@richards64 拒绝的问题应该不在你这个回答上面,敢问这是哪家的面试题?
|
15
richards64 OP @kop1989 这个没太看明白,能具体演示一下吗
|
16
richards64 OP @Caskia 确实挺奇怪的,我看 JD 上有要求掌握 WPF 就投了简历,简历上也表示出了我只有 WPF 经历,然后就让我去面试了,去了之后发现实际的主要工作内容是.NET Core 的后端开发,只是个别项目组有少量的老旧项目涉及到 WPF
|