为什么使用异常处理显然是“安全的”码? [英] Why use exception handling in apparently "safe" code?

查看:132
本文介绍了为什么使用异常处理显然是“安全的”码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请问,有人可以解释一下,这段代码可能引起异常吗?

  function CreateBibleNames:TStrings; 
begin
结果:= TStringList.Create;
try
Result.Add('Adam');
Result.Add('Eva');
Result.Add('Kain');
Result.Add('Abel');
除了
Result.Free;
加注
结束
结束

由于我使用delphi,我使用过异常处理也许是一次。我认为上面的代码是由一个熟练的程序员编写的,我不认为异常是多余的。但是,在这个概念中使用异常处理对我来说仍然是一个谜。它似乎是一个安全的代码(没有尝试除了结束)。我已经看到很多次类似的代码片段,这就是为什么有可能有一个很好的理由以这种方式写,尽管我的经验,这没有证明是必要的。



此外,当某些事情失败时,我会收到异常描述....



Thanx

解决方案

好的,这段代码很奇怪,我同意,我完全明白为什么这样写。但是这样写是因为代码的前提是错误的。这个构造似乎很奇怪的事实应该是一个代码气味,应该告诉你,有可能没有做到最好的办法。



首先,这就是为什么在异常结构中try ... except block。该函数创建一个TStringList,但如果在填充过程中发生错误,则创建的TStringList将在堆上丢失,并且将是内存泄漏。所以原始的程序员是防御性的,并确保如果发生异常,TStringList将被释放,然后异常将再次被提升。



现在这里是坏前提部分。该函数返回一个TStrings的实例。这并不总是最好的办法。返回一个像这样的对象的实例会产生一个问题:谁将要处理我创建的这个东西?。它创建了一种情况,在呼叫方面可能很容易忘记TStrings实例已被分配。



这里的更好的练习是让函数将TStrings作为参数,然后填写现有的实例。这样一来,毫无疑问谁拥有实例(调用者),因此谁应该管理其生命周期。



所以,该函数变成一个过程,可能看起来像这个:

 程序CreateBibleNames(aStrings:TStrings); 
begin
如果aStrings<> nil then
begin
aStrings .Add('Adam');
aStrings .Add('Eva');
aStrings .Add('Kain');
aStrings .Add('Abel');
结束
结束

现在这并不是说每次返回一个对象实例是一件坏事 - 那就是例如,非常有用的工厂模式的唯一功能。但是对于像这样的更一般的功能,上述是一种更好的做事方式。


Please, may somebody explain me, what can raise an exception in this code?

function CreateBibleNames: TStrings;
begin
  Result := TStringList.Create;
  try
    Result.Add('Adam');
    Result.Add('Eva');
    Result.Add('Kain');
    Result.Add('Abel');
  except
    Result.Free;
    raise;
  end;      
end;

Since I use delphi I have used exception handling perhaps once. I consider the code above to be written by a skillfull programmer and I do not think the exceptions are redundant. But still, using exception handling in this concept remains a mystery for me. It seems to be a safe code (without try except end). I have seen many times similar code snippets like this, that's why there is probably a good reason to write it this way in spite of my experience, that did not prove it's necessity.

Moreover when something fails, I get exception description....

Thanx

解决方案

Okay, that code is strange, I agree, and I totally understand why it got written that way. But it was written that way because the premise underlying the code is wrong. The fact that the construct seems strange should be a "code smell", and should tell you that something might not be getting done the best way possible.

First, here's why the unusual construct in the try...except block. The function creates a TStringList, but if something goes wrong in the course of filling it, then the TStringList that was created will be "lost" out on the heap and will be a memory leak. So the original programmer was defensive and made sure that if an exception occurred, the TStringList would be freed and then the exception would get raised again.

Now here is the "bad premise" part. The function is returning an instance of TStrings. This isn't always the best way to go about this. Returning an instance of an object like that begs the question "Who is going to dispose of this thing I've created?". It creates a situation where it might be easy -- on the calling side -- to forget that a TStrings instance has been allocated.

A "Better Practice" here is to have the function take a TStrings as a parameter, and then fill in the existing instance. This way, there is no doubt about who owns the instance (the caller) and thus who should manage its lifetime.

So, the function becomes a procedure and might look like this:

procedure CreateBibleNames(aStrings: TStrings);
begin
  if aStrings <> nil then
  begin
    aStrings .Add('Adam');
    aStrings .Add('Eva');
    aStrings .Add('Kain');
    aStrings .Add('Abel');
  end;      
end;

Now this is not to say that returning an object instance is a bad thing every time -- that is the sole function of the very useful Factory pattern, for example. But for more "general" functions like this, the above is a "better" way of doing things.

这篇关于为什么使用异常处理显然是“安全的”码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆