53

私は、コード レビューを行い、これまで個人的に取り組んだことのない新製品の 1 つに新機能を追加する可能性について報告するように依頼されました。他人のコードを盗むのは簡単だということはわかっていますが、(できるだけ客観的であるように努めながら) 悪い状態にあると言えます。私のコードレビューからのいくつかのハイライト:

  • スレッドの乱用: QueueUserWorkItemおよびスレッドは一般的に多く使用され、スレッドプール デリゲートにはPoolStartやなどの有益でない名前が付けられていますPoolStart2。また、スレッド間での適切な同期の欠如もあり、特に UI スレッド以外のスレッドで UI オブジェクトにアクセスしています。

  • マジック ナンバーとマジック ストリング: 一部Constの とEnumはコードで定義されていますが、コードの多くはリテラル値に依存しています。

  • グローバル変数: 多くの変数はグローバルに宣言されており、たどるコード パスと発生する順序に応じて、初期化される場合とされない場合があります。これは、コードがスレッド間でジャンプする場合にも非常に混乱します。

  • コンパイラの警告: メインのソリューション ファイルには 500 以上の警告が含まれており、その総数は不明です。Visual Studio から、これ以上警告を表示できないという警告が表示されました。

  • 中途半端なクラス: コードはあちこちに手を加えたり追加したりしたため、以前に行ったことを忘れてしまったのではないかと思われるため、一見中途半端なクラスや空のスタブがいくつかあります。

  • Not Invented Here : この製品は、データ アクセス ヘルパー、エラー ログ ヘルパー、ユーザー インターフェイス ヘルパーなど、他の製品で使用される共通ライブラリに既に存在する機能を複製しています。

  • 関心の分離: 典型的な「UI -> ビジネス レイヤー -> データ アクセス レイヤー」の 3 層アーキテクチャについて読んだときに、誰かが本を逆さまに持っていたと思います。このコードベースでは、UI レイヤーがデータベースに直接アクセスします。これは、ビジネス レイヤーが部分的に実装されているものの、十分に具体化されていないためにほとんど無視され、データ アクセス レイヤーが UI レイヤーを制御しているためです。低レベルのデータベースおよびネットワーク メソッドのほとんどは、メイン フォームへのグローバル参照で動作し、フォームを直接表示、非表示、および変更します。かなり薄いビジネス層実際に使用される場合、UI を直接制御する傾向もあります。この下位レベルのコードのほとんどは、MessageBox.Show例外が発生したときにエラーメッセージを表示し、ほとんどが元の例外を飲み込みます。もちろん、これにより、リファクタリングを試みる前に、プログラムの機能を検証するために単体テストの作成を開始することが少し複雑になります。

ここではほんの表面をなぞっているだけですが、質問は単純です。時間をかけて既存のコードベースをリファクタリングし、一度に 1 つの問題に焦点を当てた方が理にかなっているでしょうか、それともすべてをゼロから書き直すことを検討しますか?

編集:少し明確にするために、プロジェクトの元の要件があります。そのため、最初からやり直すことがオプションになる可能性があります。私の質問を別の言い方をすると、次のようになります。コードを維持するコストが、ダンプして最初からやり直すコストよりも大きくなるポイントにコードを到達させることはできますか?

4

29 に答える 29

36

攻撃を意図していなくても、コードベースをゼロから書き直すという決定は、初心者のソフトウェア開発者が犯す一般的で深刻な管理ミスです。

注意すべきデメリットがたくさんあります。

  • 書き換えは、新しい機能が何ヶ月も何年も冷静に開発されるのを防ぎます。これほど長い間立ち止まる余裕のある企業はほとんどありません。
  • ほとんどの開発スケジュールは確定するのが困難です。今回の書き直しも例外ではありません。今、開発の遅れによって前の点を増幅します。
  • 痛ましい経験を通じて既存のコードベースで修正されたバグが再導入されます。Joel Spolsky のこの記事には、さらに多くの例があります。
  • セカンドシステム効果の犠牲になる危険性-- 要約すると、「一度だけ何かを設計した人は、「前回はできなかった」ことをすべてやろうとし、プロジェクトにすべての要素を積み込みます。それらのほとんどはバージョン2でも延期されるべきであるにもかかわらず、バージョン1を作成している間に彼らが延期したもの.
  • この高価で面倒な書き換えが完了すると、新しいコードベースを継承する次のチームは、同じ言い訳を使用して別の書き換えを行う可能性があります。プログラマーは他人のコードを学ぶことを嫌います。完璧とは非常に主観的なものであるため、完璧なコードを書く人はいません。実世界のアプリケーションを見つけてください。最初から書き直しを行うための忌まわしい告発と根拠を提供できます。

最終的にゼロから書き直すかどうかに関係なく、今リファクタリング フェーズを開始することは、実際に座って問題を理解するための良い方法です。これにより、本当に必要な場合に書き直しがよりスムーズに進み、既存のコードベースに正直な外観が与えられます。書き換えが必要かどうかを実際に確認します。

于 2008-09-28T03:14:19.967 に答える
32

実際にスクラップしてやり直すには?

現在のコードがあなたが望むことを実行せず、変更するのに法外な費用がかかる場合。

Netscapeがコードを捨てるというJoelの記事と、それがいかにひどくて大きな間違いであるかについて、誰かがリンクすることになると確信しています。詳細については説明しませんが、その記事をリンクする場合は、リンクする前に、次のことを検討してください。IEエンジン、MSがIE 4、5、5.5、および6を迅速にリリースできるようにしたエンジン継承、Netscapeを完全に破壊したIEエンジン...それは新しいものでした。トライデントは、IE 3エンジンを廃棄した後の新しいエンジンでした。これは、将来の開発作業に適した基盤を提供しなかったためです。MSは、ジョエルが決してしてはいけないと言っていることをしました。MSは、Netscapeを完全に凌駕するブラウザを使用できるようにしました。だからお願いします...ジョエルをリンクする前に、その考えについて少し瞑想して、「ああ、絶対にやるべきではない、それはひどい考えだ」と言ってください。

于 2008-09-27T23:39:12.197 に答える
13

私が便利だと思った経験則は、コードベースが与えられた場合、コードを機能させるため、または新しい要件に基づいて変更するためにコードの25%以上を書き直さなければならない場合は、書き直したほうがよいということです。ゼロからそれ。

その理由は、これまでのところ、パッチを適用できるのはコード本体のみであるということです。特定のポイントを超えると、やり直すのが速くなります。

書き直されたバージョンが元のバージョンと機能的に同等であるかどうか(必要な場合)を示すメカニズム(完全なユニットテストやシステムテストなど)があるという基本的な前提があります。

于 2008-09-27T23:43:15.790 に答える
13

アプリケーション全体を書き直すよりも、コードを読んで理解するのに時間がかかる場合 (それが可能であれば)、私はそれを破棄して最初からやり直すと言います。

これには十分注意してください:

  1. あなたは怠け者で、コードを読むのに苦労しているだけではありませんか?
  2. 他の誰かが作成したゴミと比較して、あなたが書く素晴らしいコードについて傲慢ですか。
  3. テスト済みの動作するコードは、まだ書かれていない架空のコードよりもはるかに価値があることを忘れないでください

私たちの尊敬すべきホストであり大君主である Joel の言葉を借りれば、決してしてはいけないことであり、
動作するコードを放棄することが常に間違っているわけではありませんが、その理由を確認する必要があります。

于 2008-09-28T00:29:01.703 に答える
9

私は、アプリケーションが本番環境に導入されてから 2 年以内に再構築され、他のアプリケーションが異なるテクノロジ (1 つは C++ - 現在は Java) で書き直されているのを見ました。私の考えでは、両方の努力は成功しませんでした。

悪いソフトウェアに対しては、より進化的なアプローチを好みます。古いアプリを「コンポーネント化」して、新しい要件を導入し、古いコードと連携できるようにすることができれば、(ビジネスの観点から)価値のない投資を「売る」必要なく、新しい環境に簡単に慣れることができます。書き直し。

推奨されるアプローチ - 1) 期待どおりにコードが動作することを確認し、2) 古いベースで実行する可能性のあるリファクタリングのセーフティ ネットを提供する機能の単体テストを記述します。

悪いコードは当たり前です。IT 部門は、書き直しや再構築などを支持することで、ビジネスから悪い評判を得ていると思います。彼らはお金を払い、堅固で拡張可能なコードを提供するために (業界として) 私たちを「信頼」します。悲しいことに、ビジネス上のプレッシャーにより、コードの保守が困難になるショートカットが頻繁に発生します。悪いプログラマーの場合もあれば、悪い状況の場合もあります。

あなたの言い換えられた質問に答えるために...コードのメンテナンスコストが書き直しのコストを超えることはありますか...答えは明らかにイエスです。あなたの例には何も見られませんが、これがあなたのケースであると私に信じさせるものはありません。これらの問題は、テストとリファクタリングで対処できると思います。

于 2008-09-28T01:50:05.347 に答える
8

ビジネス価値の観点から言えば、コードの内部状態だけが原因で書き直しが必要になるケースは非常にまれだと思います。製品の顧客向けで、現在ライブで収益を上げている (つまり、保留中または未リリースの製品ではない) 場合は、次のことを考慮してください。

  • すでにご利用いただいているお客様がいらっしゃいます。彼らはそれに精通しており、それを中心に独自の資産を構築している可能性があります。(それに接続する他のシステム、それに基づく製品、変更が必要なプロセス、再トレーニングが必要になる可能性のあるスタッフ)。これにはすべて、顧客のお金がかかります。
  • それを書き直すことは、難しい変更や修正を行うよりも、長期的には費用がかからないかもしれません。ただし、アプリが Hello World ほど複雑でない限り、まだそれを定量化することはできません。また、書き直しとは、再テストと再展開を意味し、おそらく顧客のアップグレード パスを意味します。
  • 書き直しがもっと良くなると誰が言いますか?あなたの会社は今、きらびやかなコードを書いていると正直に言えますか? 元のコードをスパゲッティに変えたプラクティスは修正されましたか? (たとえ主犯が 1 人の開発者であったとしても、彼の同僚や経営陣はどこにいて、レビューやテストなどを通じて品質を確保していたのでしょうか?)

技術的な理由に関しては、オリジナルに問題のある技術的な依存関係がいくつかある場合は、大幅な書き直しの時期になる可能性があることをお勧めします。たとえば、現在サポートされていないサードパーティの依存関係など。

一般的には、最も賢明な方法は、1 つずつリファクタリングし (本当に悪い場合は非常に小さな部分)、内部アーキテクチャを 1 回で大幅に改善するのではなく、段階的に改善することだと思います

于 2008-10-13T21:44:39.223 に答える
7

これについての2つの考え:元の要件はありますか?元の要件が正確であると確信していますか?テスト計画や単体テストはどうですか?あなたがそれらのものを適切に持っているならば、それはより簡単かもしれません。

顧客の帽子をかぶって、システムは機能しますか、それとも不安定ですか?不安定なものがある場合は、変更する必要があります。それ以外の場合は、少しずつリファクタリングするのが最善です。

于 2008-09-27T23:37:19.143 に答える
7

砂の中の線は、基本的なメンテナンスが必要以上に25%〜50%長くかかっているときだと思います。レガシーコードの維持にコストがかかりすぎる時期が来ています。多くの要因が最終決定に貢献します。時間とコストが最も重要な要素だと思います。

于 2008-09-27T23:40:31.383 に答える
6

クリーンなインターフェイスがあり、モジュールの境界を明確に線引きできる場合は、既存の顧客をよりクリーンで安定したコードベースに移行できるようにするために、モジュールごとまたはレイヤーごとにリファクタリングする価値があるかもしれません。すべてのモジュールをリファクタリングすると、すべてが書き直されます。

しかし、コードレビューに基づくと、明確な境界があるようには思えません。

于 2008-09-28T00:29:37.240 に答える
5

廃棄して最初からやり直すことに投票する人々は、大規模なプロジェクトのリファクタリングに成功したことがあるか、または少なくとも、リファクタリングを使用できると思われる状態の悪い大規模なプロジェクトを見たことがありますか?

どちらかといえば、私は反対側に誤りがあります。書き直すのではなくリファクタリングを提唱した、混乱した4つの大きなプロジェクトを見てきました。いくつかのプロジェクトでは、元のコードがほとんど 1 行も残っておらず、主要なインターフェイスが大幅に変更されましたが、このプロセスでは、プロジェクト全体が最初のように機能しなくなることは 1 週間以上ありませんでした。(そしてトランクの上部は決して壊れませんでした)。

おそらく、リファクタリングしようとすると失敗する運命にあるほどひどく壊れているプロジェクトが存在するか、または私がリファクタリングした以前のプロジェクトの1つが「完全に書き直した」ほうがよかったかもしれませんが、よくわかりません私はそれを認識する方法を知っているだろう.

于 2008-09-30T22:09:33.697 に答える
4

私はマーティンに同意します。アプリを最初から作成するために必要な労力と、アプリの現在の状態、アプリを使用している人の数、気に入っている人などを比較検討する必要があります。多くの場合、完全に最初から始めたいと思うかもしれませんが、コストはメリットをはるかに上回ります。私はいつも醜いコードに出くわしますが、これらの「醜い」領域のいくつかは本当にバグ修正であり、プログラムを正しく動作させることにすぐに気付きます。

于 2008-09-27T23:42:24.593 に答える
4

システムのアーキテクチャを検討し、すべてをゼロから始めることなく、明確に定義された特定のコンポーネントを破棄して書き直すことが可能かどうかを確認します。

通常起こることは、それを行う (そしてそれを顧客/管理者に販売する) か、コードが非常に恐ろしく絡み合った混乱であることがわかり、書き直しが必要であるとさらに確信するようになることです。それについてより説得力のある議論があります(「正しく設計すれば、すべてを破棄して3回目の書き直しを行う必要はありません」など)。

メンテナンスが遅いと、最終的にアーキテクチャのドリフトが発生し、後で書き換えがより高価になります。

于 2008-09-28T00:25:24.473 に答える
4

古いコードを早い段階で頻繁に破棄します。迷ったら捨てる。難しいのは、技術に詳しくない人々に維持費を納得させることです。

得られた価値が運用と保守のコストを上回っているように見える限り、ソフトウェアからはプラスの価値が生まれます。これを書き直すことに関する質問は、「書き直しからさらに多くの価値が得られるでしょうか?」というものです。あるいは、「書き換えによってどれだけの価値が得られるか?」メンテナンスの工数を何時間節約できますか?

書き換え投資は一度だけです。書き換えへの投資に対するリターンは永久に続きます。 永遠に。

価値に関する質問を特定の問題に絞り込みます。あなたはそれらの束を上に挙げました。それに固執します。

  • 「使用しないが、まだ通り抜けなければならないがらくたを捨てることでコストを削減することで、より多くの価値を得ることができるでしょうか?」

  • 「信頼性が低く壊れるがらくたを落とすことで、より多くの価値が得られるでしょうか?」

  • 「文書化ではなく、チームとして構築したものに置き換えることで、それを理解した場合、より多くの価値が得られるでしょうか?」

宿題をしますか。次のショーストッパーに直面する必要があります。これらは、次のように応答する人から、エグゼクティブ フードチェーンのどこかで発生します。

  • 「壊れてる?」そして、「それ自体はクラッシュしていません」と言うと、彼らは「壊れていないので直さないでください」と言うでしょう。

  • 「コード分析を行い、それを理解したので、もう修正する必要はありません。」

彼らへのあなたの答えは何ですか?

それは最初のハードルにすぎません。考えられる最悪の状況がここにあります。これは常に発生するわけではありませんが、驚くべき頻度で発生します。

あなたのエグゼクティブフードチェーンの誰かがこの考えを持っているでしょう:

  • 「書き直しても価値は生まれない。ただ書き直すのではなく、広げていこう」その正当な理由は、十分な価値を生み出すことで、ユーザーがリライトに賛同する可能性が高くなるからです。

人為的に範囲を拡大して価値を付加するプロジェクトは、通常、失敗に終わります。

代わりに、できる限り最小限の書き直しを行って、くそったれを置き換えます。次に、実際のニーズに合わせて拡張し、価値を追加します。

于 2008-09-28T00:33:37.293 に答える
3

アプリケーションがどのように機能するかを完全に知っている場合 (つまり、アプリケーションがどのように機能するかについての一般的な考えを持っているだけでなく)、多かれ少なかれ正確にそれを作成する方法を知っている場合にのみ、書き換えに明確な「はい」を与えることができます。より良い。それ以外の場合は、暗闇でのショットであり、あまりにも多くのことに依存しています。可能であれば、段階的なリファクタリングの方が安全かもしれません。

于 2008-09-27T23:44:44.603 に答える
2

可能であれば、ベースラインをリファクタリングする必要がある場合は、通常、コードの小さな部分を時間の経過とともに書き直したいと思います。通常、マジックナンバー、コメントの不足など、コードが実際よりも見栄えが悪くなる傾向のある小さな問題が多数あります。したがって、ベースラインがひどい場合を除いて、コードを保持し、コードを維持すると同時に改善を行うだけです。

リファクタリングに多くの作業が必要な場合は、ベースラインをより良い状態にするために、作業するもののリストを提供する小さな再設計計画/ToDoリストをレイアウトすることをお勧めします。ゼロから始めることは常に危険な動きであり、終了したときにコードが改善されるとは限りません。この手法を使用すると、時間の経過とともに改善されるシステムが常に機能します。

于 2008-09-28T01:25:24.377 に答える
2

循環的複雑度が非常に高いコード(多数のモジュールで100を超えるなど)は、良い手がかりになります。また、/ KLOCにはいくつのバグがありますか?バグはどれほど重大ですか?バグ修正が行われたときにバグが発生する頻度。あなたの答えがたくさんある場合(私は今のところ規範を思い出せません)、書き直しが必要です。

于 2008-09-28T01:28:00.237 に答える
2

できるだけ早期に。あなたのコードがゆっくりと醜い獣に変わり、あなたの魂を消耗させ、頭を悩ませる可能性が非常に高いという予感を得て、問題がコードの根底にある構造にあることを知っているときはいつでも(したがって、修正はハックになります.たとえば、グローバル変数を導入する)、最初からやり直す時が来ました。

いくつかの理由で、人々は貴重なコードを捨てることを好みませんが、最初からやり直したほうがよいと感じているのであれば、それはおそらく正しいことです。自分の本能を信じて、時間の無駄ではなかったことを思い出してください。問題に近づかないためのもう 1 つの方法を教えてくれました。あなたの赤ちゃんが本当に迷子になることは決してないので、常にバージョン管理システムを使用できます(すべきです)。

于 2008-09-28T08:57:52.293 に答える
1

生産コードを破棄して最初からやり直すのはいつですか?

これを行う必要はありませんでしたが、論理的には、新しい機能を追加するよりも、既存のコードベースの再作業とバグ修正に多くの時間を費やすという変曲点を過ぎると、破棄する時が来ると (とにかく私には) 指示されます。古いものを捨てて、新たなスタートを切りましょう。

于 2008-10-13T21:53:51.420 に答える
1

ルールは…だったと思います。

  • 最初のバージョンは常に使い捨てです

したがって、自分の教訓、または彼/彼女の教訓を学んだ場合は、問題のドメインをよりよく理解したので、先に進んで新しく書き直すことができます。

保管できる/保管すべき部品がないわけではありません。テスト済みのコードは最も価値のあるコードであるため、スタイル以外の点で実際に欠陥がなければ、すべてを捨てる理由はありません。

于 2008-09-28T02:55:33.193 に答える
1

私自身、これにメトリクスを使用した経験はありませんが、記事 「Software Maintainability Metrics Models in Practice」では、ここで行った 2 つのケース スタディについて、多かれ少なかれ同じ質問について説明しています。それは、次の編集者のメモから始まります。

以前は、保守担当者が新しいコードを受け取ったときの経験則は、「他の人のコードの 40% 以上を変更する必要がある場合は、それを破棄して最初からやり直す」というものでした。ここで取り上げる保守性指標 [MI] は、「破棄して最初からやり直す」時期を決定するためのはるかに定量化可能な方法を提供します。この作業は、米国空軍情報戦センターと米国エネルギー省 [DOE]、アイダホ フィールド オフィス、DOE 契約番号 DE-AC07-94ID13223 によって後援されました。)

于 2008-09-28T02:06:00.643 に答える
0

はい、それは完全に起こる可能性があります。私はそれをすることによってお金が節約されるのを見てきました。

これは技術的な決定ではなく、ビジネス上の決定です。コードの書き換えは長期的な利益ですが、「完全に壊れていない場合は...」は短期的な利益です。あなたが製品を戸外に出すことに焦点を合わせている1年目のスタートアップにいるなら、答えは通常それと一緒に暮らすことです。あなたが確立された会社にいる場合、または現在のシステムのエラーがより多くのワークロードを引き起こしている場合、そのためより多くの会社のお金が..彼らはそれのために行くかもしれません。

GMにできる限り問題を提示し、可能な場合はドルの値を使用します。「私はそれに対処するのが好きではありません」は何の意味もありません。「これが修正されるまで、すべてを行うのに2倍の時間がかかります」というのは多くのことを意味します。

于 2008-09-28T01:15:49.110 に答える
0

ここには、あなたがどこにいるかに大きく依存する多くの問題があると思います。

ソフトウェアは顧客の観点からうまく機能していますか?(はいの場合、変更には十分注意してください)。システムが機能している場合は、機能セットを拡張しない限り、再確認する必要はほとんどないと思います。また、ソフトウェアの機能と顧客ベースを拡大することを計画していますか?もしそうなら、あなたは変更するはるかに多くの理由があります。

うまく書かれていても、他の人のコードを理解しようとすることは難しいかもしれませんが、ひどく書かれていると、ほとんど不可能だと思います。あなたが説明することは、拡張するのが非常に難しいもののように聞こえます。

于 2008-09-28T01:21:41.360 に答える
0

私は以前、最初から書き直すだけだと信じていましたが、それは間違っています。

http://www.joelonsoftware.com/articles/fog0000000069.html

気が変わった。

私が提案したのは、コードを適切にリファクタリングする方法を見つけることです。既存のすべての機能を保持し、実行しながらテストします。私たちは皆、恐ろしいコードベースを見てきましたが、アプリケーションが持っている知識を長期にわたって維持することが重要です。

于 2009-03-16T20:48:32.317 に答える
0

アプリケーション全体を書き直すよりも、コードを読んで理解するのに時間がかかる場合 (それが可能であれば)、私はそれを破棄して最初からやり直すと言います。

于 2008-09-28T00:12:41.977 に答える
0

コードがもはや保守または拡張できないポイントに達したとき。短期的なハッキーな修正がいっぱいです。カップリングが多いです。長い (100 行以上) メソッドがあります。UI でデータベースにアクセスできます。多くのランダムでデバッグ不可能なエラーが生成されます。

結論: 維持する場合は、書き直すよりも費用がかかります (つまり、時間がかかります)。

于 2008-10-03T19:02:55.870 に答える
0

アプリケーションが意図したとおりに機能するかどうか、変更を加える必要があるかどうか、アプリケーションが使用されるすべてのシナリオで完全にテストされていることを確信しているかどうかを考慮します.

アプリに変更が必要ない場合は、時間を投資しないでください。ただし、それが必要に応じて機能せず、修正に費やす時間と時間を制御する必要がある場合は、それを廃棄して、チームがサポートできる標準に合わせて書き直してください。サポート/解読しなければならないが、それでも対処しなければならない恐ろしいコードほど悪いものはありません。マーフィーの法則によれば、物事を機能させなければならないのは夜の 10 時であり、それは決して生産的ではありません。

于 2008-09-28T01:36:03.993 に答える
0

リファクタリングに関する議論を見るたびに、この本を投稿するつもりです。Michael Feathers の「レガシー コードを効果的に使用する」を読む必要があります。私はそれが優れた本であることを発見しました.

于 2008-09-30T03:07:47.780 に答える
0

製品コードには常に何らかの価値があります。私が本当にすべてを捨ててやり直す唯一のケースは、知的財産が取り返しのつかないほど汚染されていると判断した場合です。たとえば、誰かが以前の雇用主から大量のコードを持ち込んだ場合や、コードの大部分が GPLd コードベースから取り出された場合などです。

于 2008-09-28T02:21:29.857 に答える
0

コードを完全に捨てたことはありません。foxpro システムから ac# システムに移行する場合でも。

古いシステムが機能していたのなら、なぜそれを捨ててしまうのでしょうか?

私はいくつかの本当に悪いシステムに出くわしました。必要のないところでスレッドが使用されています。インターフェイスの恐ろしい継承と悪用。

古いコードが何をしているのか、なぜそれをしているのかを理解することが最善です。次に、混乱しないように変更します。

もちろん、古いコードが機能しない場合。つまり、コンパイルすらできません。そうすれば、最初からやり直すことが正当化されるかもしれません。しかし、それは実際にどのくらいの頻度で起こりますか?

于 2008-09-28T00:43:44.977 に答える