インターフェイスを使用するコードを検討してください。
public function doSomething(MyInterface $my) { ... }
実装の 1 つでも例外をスローできる場合は、例外の可能性を確実に処理する必要があります。
ですから、はい、文書化する必要があります。
例外をスローする実装が 1 つだけの場合でも、例外処理を適切に行う必要があります。もちろん、これはすべてのメソッドに @throws を適用する必要があるという意味ではありません。適切な場合にのみ使用する必要があります (実装が正当に例外をスローする必要があると予想される場合)。
より具体的な例として、次のことを検討してください。
interface LogWriter
{
/**
* @throws LogWriterException
*/
public function write($entry);
}
class DbLogWriter
{
public function __construct(PDO $db)
{
//store $db somewhere
}
public function write($entry)
{
try {
//store $entry in the database
} catch (PDOException $e) {
throw new LogWriterException(...);
}
}
}
class NullLogWriter
{
public function write($entry) { }
}
データベースへの書き込み時に例外が発生する可能性を下げるために、特定のことを行うことができますが、結局のところ、それは例外に対して安全な操作ではありません。したがって、DbLogWriter::write
例外がスローされることが予想されます。
ただし、エントリを破棄するだけの null ライターを考えてみましょう。そこでは間違いが起こる可能性はまったくないので、例外は必要ありません。
$log
しかし、それが の実装であるということだけを知っている場合はどうなるでしょうかLogWriter
。例外がスローされず、誤って 1 つのバブルが発生する可能性があると思いますか、それとも をスローできると思いますLogWriterException
か? 私は安全側にとどまり、LogWriterException をスローできると想定します。
ユーザーが知っているの$log
は LogWriter であるということだけで、DbLogWriter だけが例外をスローすると文書化されている場合、ユーザーはそれが例外をスローできることに気付かない$log->write(...)
可能性があります。また、後で FileLogWriter が作成されたときに、その実装がスローできる例外とスローする可能性のある例外の期待値が既に設定されていることを意味します ( が をスローするとは誰も期待しませんFileLogWriter
) RandomNewException
。