web-dev-qa-db-ja.com

「知りすぎ」で立ち往生

http://news.ycombinator.com/item?id=4037794 でさらに議論してください

私は比較的単純な開発タスクを持っていますが、攻撃しようとするたびに、私は深い考えにスパイラルを作ってしまいます-どうすれば将来を拡張できるのか、第2世代クライアントには何が必要になるのか、「非機能」にどのように影響するのか側面(例:パフォーマンス、承認...)、変更を許可するにはどのように設計するのが最善でしょう...

私は少し前に自分を覚えています。そのとき私がいた「私」は、それについては何も考えなかったでしょう-彼は先に進んで何かを書き、それからそれを書き直し、それからもう一度書き直しました(そしてもう一度...)。今日の「私」はもっとためらいがちで、注意深くなっています。

私は今日、実際に先に進んで自分で行うよりも、座って計画し、他の人に物事を行う方法を教える方がはるかに簡単だと思います-私はコーディングしたくないからではありません-反対です。 -しかし、キーボードに座るたびに、私は同じ同じ迷惑な場所に行き着くからです。

これは間違っていますか?これは自然な進化ですか、それとも私はわだちに追い込まれましたか?

公平な開示-以前は開発者でしたが、今日の肩書きは「システムアーキテクト」です。それが何を意味するか理解するために頑張ってください-しかし、それはタイトルです。


ワオ。私は正直に言って、この質問がそれほど多くの応答を生成することを期待していませんでした。まとめてみます。

理由:

  1. 分析麻痺/過剰エンジニアリング/金メッキ/(他の「前もって考えすぎるとあなたを傷つける可能性がある」)。
  2. 指定されたタスクの経験が多すぎます。
  3. 重要なことに焦点を当てていません。
  4. 十分な経験がない(そしてそれを実現している)。

解決策(理由と一致しない):

  1. 最初にテストします。
  2. コーディングを開始する(+楽しみ)
  3. 1つは破棄する(+ 1つのAPIは破棄する)。
  4. 時間制約を設定します。
  5. 綿毛を取り除き、原料と一緒にとどまります。
  6. 柔軟なコードを作成します(「捨てる人」とは少し反対です)。

皆さんに感謝します。ここでの主な利点は、この経験で私だけではないことを理解したことだと思います。私は実際にはすでにコーディングを始めており、あまりにも大きなもののいくつかは自然に落ちています。

この質問は締め切られたので、今日の投票でほとんどの回答を受け入れます。いつ/それが変わったら-私はフォローしようとします。

150
Ran Biron

これらのことについて考えることは間違いなく良いことですが、それがあなたの進歩を止めさせないようにしてください。

(特に反復的な開発で)非常にうまく機能する1つのアプローチは、単純なソリューションを実装し、後で必要に応じてリファクタリングすることです。これにより、コードが可能な限りシンプルになり、過剰なエンジニアリングが回避されます。あなたが考えているほとんどのパフォーマンスやアーキテクチャの変更はおそらくとにかく必要になることはないでしょうから、正式にそれらが必要になるまでそれらを書く気にしないでください。たとえば、プロファイラーからパフォーマンスを改善する時期がきたと言われるまで、パフォーマンスについて心配する必要はありません。

調整を支援するためにできることの1つは、コードを記述する前に何かについて考える時間に厳しい時間制限を設定することです。ほとんどの場合、少し考えてコードを記述し、間違いを理解してから、リファクタリングすることでコードを修正すると、コードはより良くなります。

ここで打たれるバランスがあります。頭から先に進んで結果を考えるべきではありませんが、コードを過度に設計してはいけません。

90
Oleksi

ウィキペディアはそれを "Analysis paralysis" と名付けています。レシピは、アジャイル手法に固執することです。あらゆる活動や個別の行動は、慣行や方針を確立しようとするよりもはるかに価値があることを意味します。チームのすべての貢献者は、その人の能力が建築の理想にどれだけ適合しているかに関係なく、貴重です。アジャイルでは、個人、エゴが最初で、ポリシーが最後です。

私の好きな答えは「建築は動詞」です。あなたやチームがどんなに不完全で非効率的であっても、思考をやめて行動を始めましょう。たぶん最初の行動は不適切な政策を解体することかもしれません。

48
user7071

40年前、フレッド・ブルックスはこれについて「捨てるために書いてください、とにかくあなたはそうするでしょう」と書いています。何も変わっていません........

43
mattnz

これは間違っていますか?これは自然な進化ですか、それとも私はわだちに陥りましたか?

場合によります。これは、開発者にとって一般的な一歩となる傾向があります。

  1. 一緒にがらくたを投げ始めて、それによってロバに噛まれる
  2. すべてから生きている地獄をオーバーエンジニアリングし始め、YAGNI
  3. 簡単なものが一緒に叩きつけられ、難しい/変更の可能性が高いものには、操作/変更が簡単にできるように十分なエンジニアリングが施されている、実用的な中途半端に落ち着きます。

あなたがナンバー2にとどまるならそれはわだちだけです。

38
Telastyn

私が常に心に留めておきたいことの1つは、「未来は昔のことではない」ということです。

ある程度の経験があると、将来を予測できると信じたくなりますが、予測できません。将来のクライアント/ユーザー/何でも必要な機能を思い描くのは簡単ですが、それは彼らがすぐにそれらを必要としているという意味ではありません。また、他の競合する機能よりもそれらが必要になるという意味ではありません。ですから、今日の将来の計画に費やす時間を制限する必要があります。特に、将来的にのみ使用されるものを今日構築するのに費やす時間を制限する必要があります。

私がまっすぐで狭いままでいると私が尋ねる質問は、「この機能のサポートを今構築するよりも、後でこの機能を構築する方がどれほど難しいか」です。通常、答えは、将来の取り組みは、現在の取り組みとほぼ同じか、おそらく2倍になるということです。その場合は未来が予測できないので今は作れなくても問題ありません。答えが最大で10倍以上になった場合は、来年か2年後にこれが必要になると人々が考えている可能性について人々に尋ねます。それでも、広範な合意がない限り、将来の目標を達成するために、今日行っていることを元に戻す必要がないことを確認することだけに制限します。

たとえば、後でHibernateをデータアクセスとして使用しているという事実を抽象化するために多くの時間を費やしたいくつかのプロジェクトに取り組みました。 (Hibernateに基づいて構築されたプロジェクトがその使用を停止するのを見たことがないので、そもそもそれは時間の無駄でしたが、それはさておきましょう。)後で変更したくなるかもしれないという合理的な可能性があったとしても、また、データアクセスオブジェクトパターンを使用していました。Hibernateを変更する柔軟性を組み込むと同時に、必要に応じて変更することも、最初から柔軟性を組み込むことよりも簡単でした。そのような状況に直面したとき、私は本当に必要になるまで、その柔軟性を持つことを延期しました。

大企業の戦略的な計画を立てているのでなければ、テクノロジーが急速に変化しているため、2、3年以上先にアーキテクチャの問題について考えることはほとんど意味がありません。今日作成を検討している機能は、2〜3年後にオープンソースで無料で利用できるようになる可能性があります。ほぼ間違いなく、費用便益分析は変化するでしょう。

今日必要なことを実行し、誇りに思うシステムを構築することに自分自身を制限し、次のラウンドの変更がもたらすものは何であれ、数か月で喜んで取り組むことになります。本当にそれがあなたができる最高のことです。

14
Old Pro

ここに、私の最初のバージョンではクレイジーで素晴らしいデザインを排除するための個人的なプロセスがあります。これらのデザインは(最初のバージョンでは)非現実的であり、ビジネスの観点からプロジェクトに損害を与える可能性があります。

  1. 震源地を特定する:プロジェクトをホットドッグスタンドと考えてください。震源地はホットドッグです。スタンドから他のすべてのスパイス/ドレッシング/野菜を取り出しても、ホットドッグを販売できます。ソフトウェアの主な目的は何ですか?それから他のすべての追加および/または付加価値を分離し、最初に震源地に焦点を当てます。
  2. 「後で実行することはより良いことを意味します」:自分に繰り返しを繰り返し、意味のある場所を確認し、「後で」メモを付けます。うまくできていて、その実際の使用法を考えていると、同じ設計になりますが、ロードマップでは優先順位が付けられます。
  3. Diminish-Decouple-Discard:どんなモジュール設計でも、可能な限りシンプル/必須/純粋/ユニバーサルに作成します(これは、機能の削除)。それをさらに単純化できない場合は、それ自体で生きることができ、目的を持っている可能性のある要素の分離を開始します。結局、そこにまだ脂肪が残っている場合は、それを切り離すことができます。
  4. 「製品コード」から「ライブラリコード」を分離します:再利用できないコードは常に存在しますが、設計に常にノイズを追加します。このコードは、ビジネスルールを含むコードです。いくつかのビジネスルールは、堅牢な設計よりも簡単かつ迅速に変更できる場合があります(非常に重要)。信頼できるコードを見つけ、顧客が将来変更または再実装する必要があるコードを見つけます。あなたはそれらをできるだけ分離しておくことを望みます。

ところで、ステップ0は「デザインに夢中になる」です。これは、システムからそれを取り出し、しばしば新しい影響、隠れた要件、さらには新しい機能を見つけるのに役立ちます。

リワーク から1と2を取りました。

11
dukeofgaming

テストを書きます。テストがすべて成功したときに完了します。前の段階ではなく、確かに、オーバーエンジニアリングの壮大なフェーズの期間中です。作成しているコードのテストスイートがあると、独立できる公平なオブザーバーが、いつ停止できるかを教えてくれます。

9
user4051

ソフトウェアを作成および設計する際に心に留めておく必要があるのは、保守性と正確性の2つだけです。

正確さは最も重要な短期的であり、テストによって簡単に証明できます。

保守性は開発の後半に役立ちますが、特定するのが困難です。

私の現在の戦略は、モノリシックな概念実証を最初に取得し、実行可能であると確信したら、モデルからUIを分離することです(モデルがUIについて何も認識していないことを確認します)。このステップを長く待ちすぎると、保守不能なものになります。分離したレイヤーから始めると、UIがモデルについて知る必要があることに行き詰まってしまい、始められないように見えるだけです。

4
ratchet freak

若いときはリスクは見られませんが(おそらく、下級政治家が怖い理由です)、年をとるにつれて、悪い経験はあらゆる機会にあなたを麻痺させます(おそらく上層政治家が停滞している理由です)。 Occamのかみそり ガイド付きアプローチを採用-ニーズが最も少ないソリューションを選び、そこから進化させます。

4
user49491

このような状況で立ち往生しているとき、私がエンドユーザーが仮想プログラムを使用して合理的に些細なことを行うことを頑固に想像するのに役立つことがわかりました。次に、これらのアクションをサポートするために必要なプログラムのエントリポイントに焦点を当て、システムの他の側面をできるだけ無視するように努めます。ここから、完成したシステムの機能の(小規模な)「概要」を構築し、startsを実装する非現実的なコードを書くことがしばしば可能になります。その運動の後、私は通常始められ、システムの残りの部分はより明確になり始めます。 それはすべてエントリーポイントに関するものであり、すべてのソフトウェアの圧倒的多数のエントリーポイントは、エンドユーザーによるプログラムでの最初のアクションです。

3
Jacob Oscarson

あなたがしている仕事があなたにとってあまりにも簡単なのは、シンドロームだと思います。

数年前は、与えられたタスクを実行するコードを書くのが難題でした。これはあなたの心を完全に魅了したものでした。今、あなたの心(あなたの経験など)はより効果的に働いており、同じ仕事をするのに以前必要だったエネルギーの一部しか必要としません。これが、深い思考のスパイラルで終わっている理由です。あなたの心は日常から身を守り、挑戦のために戦っています。

仕事の変更を検討すべきだと思います。多分あなたは新しいプログラミング言語を学ぶべきです。

3
Danubian Sailor

私も15年前に同じ問題を抱えていました。ソリューションを必要以上に複雑なものにする、完璧で再利用可能なユニバーサルなコードを書きたかったのです。今日私はこれを ゴールドメッキ と見なします。私を大いに助けたのは同僚のアドバイスでした:

  • 機能を改善する可能性のあるアイデアがある場合は、それをより普遍的にします...このアイデアを別のテキストファイル "ideas.txt"に書き留めますが、今は実装しないでください
  • 緊急のタスクを実装し続けます。
  • 6か月後、「ideas.txt」を確認し、これらの変更のどれがプロジェクトに本当に役立つかを分析します。
3
k3b

これは単に分析による麻痺です。それは多くの分野の多くの人々に起こります。あなたはそれを突破することができます。

答えは-ITを使うだけです;-)

私はフィットネスフォーラムに投稿し、多くの場合、人々はさまざまなルーチンについて投稿し、自分にぴったりのルーチンを見つけようとします。そのため、トレーニングを開始し、作業を進めながら作業することを伝えます。あなたは強くなりたい、いくつかの強度のエクササイズをして、それからあなたが行くにつれて物事を微調整したいです。

大規模なプログラムがあり、脳が残業している場合-最初に単純なケースをコード化するだけです。最初はプログラムを実行する必要があり、次に入力を受け取る必要があります。
あなたの課題は、後で更新やリファクタリングを簡単に行えるようにすることですが、コードは、手元のタスクを実行するために必要なものよりも複雑であってはなりません。

将来的には、新しい優先順位を満たすためにコードをリファクタリングしても問題ないことを覚えておいてください。すべてを事前に予測することはできないため、試さないでください。

次のタスクのコード-のみ。コードは単純かつ適切であるため、必要に応じて簡単にリファクタリングできます。プログラムが機能することを確認します。繰り返す。

2
Stefan

考えられるエンドユーザーのユースケースシナリオを「スタック」しているため、APIを公開する予定があり、知らない人がそのAPIを利用することを期待している場合は、ここで検討する必要があります。 APIが公開されたら、後で最初のリリースがどれほど悪いかを理解していても、APIをサポートし続けるか、APIに反対して作成した、おそらくあなたには知られていないすべての人のコードを破壊する必要があります。すべての将来の時間のために。

標準的な解決策は、ユーザーのニーズがわかり、APIの利用者が何をしているのかがわかるまで、APIはいつでも変更される可能性があるという規定で公開することです。

そのソリューションでは、私はあなた自身のソリューションだと思います。 1つまたは2つのことを行う小さなことを書いてください。おそらくそれらは問題なく、あなたが行うことは将来変更される可能性があることを理解しておきます。

デザインは本当に発見の旅なので、最初からすべてを正しくすることはできません。場合によっては、そのすべてを正しく行うこともできません。それは最後に出現するものであり、最初に完了するものではありません。

APIをすぐに設計することはできず、消費者にそれを破壊する必要はありません。あなたはそれがなぜなのかを理解します。同様に、ソフトウェアを作成することも、ソフトウェアをすべて捨てて新しいアプローチでやり直すこともできません。

創造的でない、生産的でない、または望ましくない何かに誤って進化したという意味では、問題はないと思います。私はあなたがあなたの状況に誤って誤って適用している高い基準を持っていると思います-誰もが考える一般的な間違いです。

あなたがシニカルなオールインワン、デニートイットオールにならない限り、経験はあなたに不利になることはありません、そしてそれは本当にあなたの状況の反対のように聞こえます。

大きくなったときに心に留めておく画像がいくつかあります。 1つはレゴで遊ぶことです。まとめて自由に分解します。私が作り始めたものが、私が作り終えたものではないかもしれません。私はサーフィンをしていて、自分が進むにつれて頭に浮かぶ可能性を利用し、インスピレーションの瞬間にその場で自分の目標を完全に再現します...それが創造性です。

もう1つの画像は、実際の科学を行うことを説明するアナロジーです。あなたは暗い部屋でそこにいないかもしれない黒猫を探し回っています。あなたがその猫を見つけられなかった失敗として数えた場合にのみ、それは不安になります。黒猫を見つける他の方法はありません。それが今までそれらを見つける唯一の活動です。それ以外のものは、あなたが探しているとされているものをすでに持っている何らかの形です。

1
user48910

あなたはあまり知りません。あなたは十分に知りません!そして、ごく最近になって気づきました。

「正しい」はないので、「正しい」を得なければならないものとして設計の選択を考えないでください。「間違った」はたくさんありますが、トレードオフ(実行速度、コーディングを完了する時間)もあります。タスク、拡張性など)。よく考えられた場合に作成するコードには、さまざまな長所と短所があります。

目標は、現在および将来の使用と保守のコンテキストでこれらの長所と短所を理解することが、そもそもコードを書くことよりも劇的に難しくないところまで到達することです。

したがって、深い思考を避けないでください。この種のデザインのマスターになるには、思考だけでなく経験が必要であることを忘れないでください。特定の選択に確信が持てなくなるポイントに到達するまで考え、次に、最良のものを希望するものを実装し、それを試して、それがどのように進んだかを学びます。

0
Rex Kerr