我被问到的一个问题是我有一个包含以下列的数据库表
pid - unique identifier
orderid - varchar(20)
documentid - int
documentpath - varchar(250)
currentLocation - varchar(250)
newlocation - varchar(250)
status - varchar(15)
我必须编写一个c#app来将文件从currentlocation移动到newlocation并将状态列更改为“SUCCESS”或“FAILURE”。
这是我的回答
使用linq
创建一个将执行移动文件的命令对象
使用foreach,调用委托移动文件 -
使用endinvoke捕获任何异常并相应地更新数据库
有人告诉我,命令模式和代表在这里不符合要求 - 我很想思考并实施更有利的GoF模式。
不确定他们在寻找什么 - 在这个时代,候选人会保留很多关于头脑的信息,因为总有谷歌找到任何答案并提出解决方案。
答案 0 :(得分:3)
我同意Aaronaught在上面的评论。对于这样的问题,有时你可以过度思考并尝试做一些比实际需要更多的事情。
也就是说,想到的一个GoF模式是“Iterator”。在您的第一个声明中,您说您将所有记录读入List。可能有问题的一件事是,如果你有数百万这些记录。您可能希望以更连续的方式处理它们,而不是将整个列表读入内存。 Iterator模式使您能够迭代列表而无需了解底层(数据库)存储/检索机制。迭代器的底层实现可以一次检索一个,十个或一百个记录,并根据请求将它们发送到业务逻辑。这也会提供一些测试优势,因为您可以使用不同类型的底层存储(例如内存列表)测试您的其他“业务”逻辑,以便您的单元测试独立于数据库。
答案 1 :(得分:2)
对模式的深刻理解是您作为开发人员必须拥有的东西 - 您不应该去Google确定“使用”哪种模式,因为您没有足够的时间来真正理解这种模式你开始阅读它并在你应用它时。
模式主要是关于理解力量和封装变异。也就是说,力量产生某种变化,我们已经很好地理解了封装这些变化的方法。 “模式”是了解哪种力量导致哪种变化以及哪种封装方法最能解决这些问题。
我有一位正在教授模式课程的朋友,他突然想到他可以在课程书中解决每个模式中“使用”(意思是“实施封装技术”)的特定问题。它真的做得非常好,帮助推动了这样一个事实:找到合适的技术对于了解如何应用技术更为重要。
例如,Command 模式首先要了解有时我们想要在发生某些事情时改变。在这些情况下,我们希望将决定何时做出的决定与决定何时做出决定。在这个例子中,我没有看到任何迹象表明何时你的命令应该执行完全不同。
事实上,我并没有真正看到任何变化,所以可能根本没有任何模式。如果你的采访者说有,那么他们也可能有一些学习的事情。
Anywho ...我推荐Shalloway和Trott的设计模式解释。您将更深入地了解什么样的模式以及它们如何帮助您完成工作,下次当他们告诉您“正在使用”错误的模式时,您可能只是能够教育他们。这对我来说似乎相当不错......大约有20%的时间。 :)
答案 2 :(得分:0)
我宁愿说面试官希望你在这里使用(或提及)SOLID面向对象的设计原则,在这个过程中你可能会使用一些设计模式。
例如,我们可以制作一个符合SRP,OCP和DIP的设计。
internal interface IStatusRecordsToMove
{
List<IRecord> Records { get; }
}
internal interface IRecord
{
string Status { get; set; }
}
internal interface IRecordsMover
{
ITargetDb TargetDb { get; }
void Move(IStatusRecordsToMove record);
}
internal interface ITargetDb
{
void SaveAndUpdateStatus(IRecord record);
}
class ProcessTableRecordsToMove : IStatusRecordsToMove
{
public List<IRecord> Records
{
get { throw new NotImplementedException(); }
}
}
internal class ProcessRecordsMoverImpl : IRecordsMover
{
#region IRecordsMover Members
public ITargetDb TargetDb
{
get { throw new NotImplementedException(); }
}
public void Move(IStatusRecordsToMove recordsToMove)
{
foreach (IRecord item in recordsToMove.Records)
{
TargetDb.SaveAndUpdateStatus(item);
}
}
#endregion
}
internal class TargetTableBDb : ITargetDb
{
public void SaveAndUpdateStatus(IRecord record)
{
try
{
//some db object, save new record
record.Status = "Success";
}
catch(ApplicationException)
{
record.Status = "Failed";
}
finally
{
//Update IRecord Status in Db
}
}
}