web-dev-qa-db-ja.com

過剰設計の具体的な症状

私は最近、メンテナンスとマイナーな機能の追加を支援するために、会社が採用したい2人の候補者に書いた(社内)アプリケーションを説明する立場にあることに気付きました。

これは私が作成した最初の「本番」アプリケーションであり、45,000のLOCがあり、ほぼ2年間の「ソロ」開発に費やしました。私はかなり若く(18)、会社を辞めた元開発者の代理として契約されている間、アプリケーションを最初から作成しました。このサイズのアプリケーションの設計に不慣れだったので、一般的なアーキテクチャパターンとデザインパターンを使用しようとしました。

今日、私はいくつかの深刻なオーバーエンジニアリングを行ったことを知っています。選択したORMがすでに実装している作業単位パターンの代わりに、切断された変更追跡アーキテクチャを使用します。私はおそらく「本物の」3つの層に行く必要はないでしょう。

どちらの候補者も、関連するプラットフォームを使用した社内アプリケーション開発で10年以上の経験があります。彼らの半分の年齢であり、経験がほとんどないので、私は彼らの意見を尊重します。私が彼らにアプリケーションアーキテクチャを説明していたとき、コメントは次のようなものでした。

  • うわあ、誰も私にそのようなことをするためにお金を払うことはありません、私は物事を成し遂げなければなりません
  • フレームワークの機能に固執し、派手なライブラリ/テクノロジーを使用しないでください
  • フレームワークコードをラップしないでください。チームでは、とにかく誰もが自分のラッパーコードを作成します。
  • .NET 3.5を使用していますか?さて、2.0を使用しています。
  • そのLINQのものは私に何を買いますか?このクエリの構成と投影はすべて複雑すぎるようです。

今私は自分自身に問いかけています:
私は 建築宇宙飛行士 ?アーキテクチャが行き過ぎていることをどうやって知ることができますか?オーバーエンジニアリングの一般的な症状は何ですか?

45

オーバーエンジニアリングの一般的な症状は何ですか?

あなたが持っていない問題を解決するコード。

122
Jeff Sternal

オーバーエンジニアリングの非常に強い警告サインの1つは、すべてが非常に多くの間接参照を通過するため、具体的なドメインレベルの機能を実際に実装するコードを見つけるのが難しい場合です。ほとんどの関数が具体的な作業をほとんど行わず、他の仮想関数を呼び出すだけの場合は、問題が発生している可能性があります。

25
dsimcha

退屈

Boredomは、過剰に設計されたコードの優れた前兆です。私が最初の仕事に就いたとき、私はとても十分に活用されていないと感じたことを認めます。私はただ退屈しました。そして、退屈したとき、私はコードを書きました。コードだけではありません-コードの大聖堂。

真面目な話ではありませんが、金色の突き出た尖塔のある大きな塔、ガラスのオニキスのフライングバットレス、美しい幾何学模様をトッピングしたアーチ型のドームで支えられた素晴らしい金庫など、コードと抽象化のイメージがありました。

パターンが一緒に機能するのを見るのは本当に魅力的でしたが、振り返ってみると、私が残した不敬虔な混乱を完全に恥じています。

刺激の少ない仕事をしている間に独自のフレームワークとDSLコードを書いている場合は、やめてください。読む時間は Wards Wiki 、または書く オープンソースの本 、または単に経営陣にもっと仕事を依頼したい場合があります。

18
Juliet

あなたが建築宇宙飛行士であるかどうかについての質問について:あなたが多くの人々の前にあなたを置く危険性を知っているかどうか。あなたは牛の飼い主の邪魔をしたくありません、彼らの何人かは無愛想な古い泣き言になっているようです。

オーバーエンジニアリングは、システムの一部が注目を集めすぎる結果となった優先順位付けの問題の結果です。したがって、過剰設計の最も明らかな症状は、注意力の欠如のために傷ついているシステムの他の部分の周りをすべて見ることができるということです。

(複雑さが増し、オーバーエンジニアリングの側面を決定する際にエラーが発生しやすい憶測が増えるため、システムが設計不良のリスクにさらされる傾向もありますが、コメントが指摘しているように、それは自動的には続きません。)

11
Nathan Hughes

独自のフレームワークの作成

たぶん、誰かがすでにそれをしている。それ以上に、彼らはすでにあなたがこれまでにできたよりも1000倍良くそれをしました。それ以上に、彼らが行ったことはおそらくすでに業界標準であるため、テクノロジーを学ぶことで他の仕事での競争力が高まります。

私が働いていた最後の会社では、プログラマーは彼の在職期間のほとんどの間、彼のプロジェクトに単独で取り組んでいました。彼は会社で最も人気のあるアプリの1つを作成し、チームで最高と広く見なされていましたが、私の意見では、彼は必要なものすべてを最初から作成するという厄介な習慣を持っていました。

彼は、独自の依存性注入フレームワーク、独自のORM、ユニットテストフレームワーク(不可解なことに、NUnitと非常によく似た外観と動作をしました。なぜ、NUnitを使用しなかったのですか?)、ファクトリオブジェクトを作成するためのフレームワーク( " 工場工場 "私はそれを呼ぶでしょう)。

念のために言っておきますが、コードは実際には注目に値するものでしたが、ポイントは何でしたか?

より良いコアライブラリを書く

私の現在の会社では、プログラマーが.NETFrameworkにすでに存在する機能を複製するために無駄な量のコードを書いているように見えました。

とりわけ、彼らは書いた:

  • ASP.NET Webフォームでのフォーム認証用のActiveDirectoryフレームワーク-ASP.NETにはこの機能が組み込まれているため、説明できません。
  • Webサイトのホットスワップ可能なテーマとスキン-コードは組み込みのASP.NETテーマよりも機能が低く、1000%多くの膨張が必要だったため、これも説明できません。
  • 彼らは不可解にも独自の型付きデータセットとデータアダプタを作成しました。これらのオブジェクトは、VSが自動生成する型付きデータセットよりも機能が少なく、同時にNHibernateドメインオブジェクトよりも多くの定型コードを必要とします。

彼らはフレームワークをよく知らないか、それが悪名高いほど不十分だと考えています。

再実装されたライブラリが元のライブラリよりも優れていると私が考えることができる例はごくわずかです( Jane Street Core LibraryC5 Generic Collections for .NET 、-を参照してください。 実際の通貨クラス )ですが、より良い標準ライブラリを作成することはできません。

11
Juliet

ほとんどの社内ビジネスアプリケーションの場合、コードのほとんどは、ビジネスに関係のない技術的な懸念(「切断された変更追跡アーキテクチャ」など)ではなく、ビジネス上の懸念の実装に関係している必要があります。現在利用可能なフレームワークはかなり成熟しており、最も一般的なユースケースをサポートしています。新しいテクノロジーを発明している場合、または(ビジネスアプリケーション開発のコンテキストで)ラップするためだけに他の既存のフレームワークまたはライブラリをラップしている場合は、おそらく間違っています。理想的には、構築するすべてのアーキテクチャは、ビジネス要件までさかのぼることができます。複雑にしないでおく。

10
Ken Liu

オーバーエンジニアリングはテクノロジーに関するものではないため、アプリケーションについて寄せられたコメントのほとんどは、実際にはオーバーエンジニアリングに関するものではありません。それは建築についてです。新しいテクノロジーは、妥当な時間で学習および理解できます。過剰に設計されたアプリケーションを理解することは、通常、はるかに困難であり、時には不可能ですらあります。これにより、ポイント2、4、および5が無効になります。最初のポイントは、アプリケーションをそのまま作成することで明らかに報酬を得ており、それが機能する場合はここで問題がないため、実際には有効ではありません。

これは、アプリケーションが過剰に設計されているかどうかを確認するための私の「クイックテスト」です傾向

  • 「すべて」のラッパー:ラッパーは便利ですが、やりすぎるのは簡単です。本当にラップする必要があるものだけをラップするかどうかを確認してください。 (私は基本的に自分のラッパーを一度ラップしました。私が話していることを知っています;-)。)
  • 車輪の再発明:クラシック。これは非常に一般的であり、あなたはすでにそれについて言及しました。 望んでいた必要したため、いくつかの機能を実装しましたか?あなたのフレームワークは、他の利用可能なライブラリが実行しないことを何をしますか?
  • "Feels" over-engineered:これは最も重要なポイントですが、最も見にくいポイントでもあります。コードを見て、どの部分が過度に複雑に感じられるかを見てください。それを実装する簡単な方法があるかどうか、そしてなぜこの方法を選択しなかったのかを自問してください。良い答えが得られない場合、この部分はおそらく過剰に設計されています。

これらは、私がアプリケーションに使用する簡単なヒントです。それらは、「オーバーエンジニアリング検出」のすべてであり、すべてであるとは限りません。

9
Albic

同僚のコンピュータが、過去6時間、ばかげたフレームワークを使用しておかしなダイアログボックスを表示しようとして失敗したために頭を通り過ぎて飛んでくると、それは非常に具体的な症状です。

9
Paul D. Waite

[〜#〜] yagni [〜#〜][〜#〜] dry [〜#〜] 、および [〜# 〜] kiss [〜#〜] 過剰に設計されたものを見るときに頭に浮かぶ。部分的に完了しているように見える部分が多く、コードの多くの部分に「これが発生した場合はどうなりますか?それが発生した場合はどうなりますか?」それを感じてください、それは別のポイントでしょう。 OO設計 または SOLIDの原則 の優れた原則)を無視することは別の注意点です。完璧なコードを書いたと思うなら、それは誰かが何らかの方法で改善できない何かを書くことは非常にまれなので、問題の別の兆候です。

IMO、コードベースの一部として、特定の方法で物事を好む人が関与する可能性があるため、一部の人はあなたの作業に過度に批判的である可能性があることに注意してください。メソッド、テスト、変数の命名規則。仕方ないよ。さて、あなたが理解しなければならないかもしれないのは、 conflictpersuasion/influence のような、助けになるツールがあるような状況で人々をどのように扱うかです。

8
JB King

アプリに固有の機能を提供するプラグイン

それに直面しましょう、プラグ可能なアーキテクチャはとてもセクシーで書くのが楽しいです。ただし、これは、「本当にこのようにする必要があるのか​​」と自問する必要がある領域の1つです。

アプリケーションにアドホックな追加を行う必要がなく、サードパーティの拡張機能を誰かが作成することを期待せず、アプリケーションの範囲がかなり明確に定義されている場合は、プラグ可能なアーキテクチャは必要ありません。

アプリの固有の機能をサポートするプラグインを作成しないでください。ペイントプログラムを書いていたとしましょう。ファイルを複数の形式で保存するプラグインをおそらくサポートしますが、プラグイン可能な元に戻すマネージャーやファイル参照ダイアログは必要ありません。

6
Juliet

あなたは建築宇宙飛行士ではありません。 LINQは非常にシンプルで基本的で、便利です。同じことが.NET3.5にも当てはまります。

同時に、あなたはチームの初心者であり、たとえ彼らがあなたのしたことを気に入っていたとしても、ある種のリブを手に入れようとしています。

一粒の塩でそれをすべて取りなさい。彼らの批判を受け入れてうなずき、その後ビールを飲みましょう。

彼らがあなたにそれを変えるように頼んだら、あなたのコメントは「うわあ..私はそれを間違えたのは知っているが、それはうまくいくし、変えるのは大変なことになるだろう」です。

5
Larry Watanabe

コードの予想される寿命にわたって作業を最小限に抑えるための作業を行ったかどうかを評価してみてください。これには、開発だけでなくメンテナンスも含まれます。

コードのライフサイクルでは、コードの寿命はアプリケーションの寿命と同じではないことに注意してください。最初に簡単なプロトタイプを作成し、ドメインをよりよく理解した後でリエンジニアリング/リファクタリングする方がよいでしょう。この状況では、ライフサイクルが非常に短いため、シンプルに保ちます。

さらに、アプリケーションが異なれば、必要なエンジニアリングの量も異なります。このアプリケーションが失敗した場合、人命が犠牲になりますか?つまり人工心臓用のコントローラーですか、それともスペースシャトルのナビゲーションロケット用のコントローラーですか?それとも退屈な10代の連絡先リストですか?

3
Larry Watanabe

より一般的で高レベルのアプローチでは、

I feel that when there's a gap between the complexity of the problem and
the complexity of the solution, then you have a clear case of overengineering. 

それを達成する方法は何ですか?あなたが持っていない問題を解決し、問題が実際よりも複雑であることを確認し、将来を予測しすぎたり、一般的すぎるものを構築したりします。

3
Tony

妥当な時間枠内にプロジェクトを実装しましたか?今は機能していますか?もしそうなら、おそらく少しリラックスすることができます。オーバーエンジニアリングの最悪の問題の1つは、実際に何か有用なことを行うことは決してないからです。

あなたが話した人たちにも良い提案があるかもしれませんが、それは彼らが言うことすべてを福音として受け入れる必要があるという意味ではありません。たとえば、新しいプロジェクトで最新バージョンの.NETを使用しても、心配する必要はありません。彼らは本当にそれについて不平を言っていますか?

2
Peter Recore

その半分は、彼らが知っている実証済みの真の蒸気エンジンに固執している老人(私は彼らのリーグにいます)です。残りの半分は真実ですが、実際には何も新しいことを教えてくれません。

それ以外は、ジェフ・スターナルの答えは素晴らしいです。

2
just somebody

別の見方をしたいのですが、この用語を削除して、より適切な説明に置き換える必要があると思います。 「オーバーエンジニアリング」と呼ばれるものの多くが正反対の性質を持っている場合(エンジニアリングが多すぎる、またはそれを真剣に受け止めているかのように)、それは何よりも単純さと保守性と実用性に関する「エンジニアリング」に汚名を着せます、最も複雑なソリューションを生成することになっています)。たとえば、過剰なエンジニアリングと不十分なテスト手順の相関関係を確認することは一般的です(少なくとも、これら2つが密接に関連しているのをよく見ました)。また、エンジニアリングのどのような過剰が最小限の正式なテストを実行するかを確認します。 ?

私は、ソフトウェアマネージャーや、SEに精通していない恐竜が、システムのメンテナンスコストを削減したり、より適切なテスト手順を提案したりしようとしている人にこの用語を投げかけるのをよく耳にするという観点から言っています。安全基準。素人にとって、サウンドエンジニアリング、テスト、およびスプリントのようなスナップスナップスナップペースでコードを生成しないことに真剣に取り組むことは「オーバーエンジニアリング」であると考えるのは簡単です。

「オーバーエンジニアリング」の本当の匂いを真に認識する人はたくさんいますが、この用語は少なくとも間違いなく誤解を招くものです。

症状に関しては、すでに提供されている優れた症状に加えて、目の前の作業を適切に評価および再評価できることの盲点です。プログラマーは想像力で世界を構築し、そびえ立つ概念に夢中になり、夢中になります。それは退屈で一般的な答えのようなものですが、それは私たちの目の前で実際の問題や優先順位を見ることができなくなる危険につながる可能性があります。あまりにも深く概念化することは、私たちの目の前にあるものについての盲点を開発すること、問題を過度に複雑にすること、現実と実際のユーザーエンドのニーズとの接触を失うことです。私にとって、注意すべき最大の症状は心理学を中心に展開しています。

制作を中心に展開するあらゆる種類の職業は、概念に執着しすぎた結果として解決すべき実際の差し迫った問題を見失うというこの基本的な傾向に対して脆弱です(例:映画監督)。一般的なプログラミングでは、それと戦う方法は、わかりやすさ、シンプルさ、実用性、コーディングを優先してから、何かをn度まで概念化することです(アイデアに深く夢中になる前に、再評価する時間を増やします)。これらの理想を受け入れることは間違いありませんが、私にとっての鍵は、自分の仕事を適切に評価することができないようなブラインドスポットの開発を避けることです。過剰に設計されたコードベースは一夜にして実現しません。それを生み出すには、間違った方向に向けて大量の専用作業が必要です。私にとって、それに関する最大の予防可能な問題は、先見性に関連するものではありませんが、適切な後知恵を開発するのが遅すぎることがよくあります。

0
Dragon Energy

24年間プロとしてソフトウェアを開発してきた人として、私が言えるのは、この問題(特定の問題に必要な抽象化のレベルで電話をかけること)は最も難しい私の毎日のデザインとプログラミング作業の一部。

「昔」には、エンジニアリング不足が蔓延し、それがすべての構造化された方法論と実践につながりました。さて、私たちは逆の方向に進んだようです。簡単な答えはありません。時には、後知恵;)で設計されているかどうかしかわかりません。

「これほど複雑にならなかったらいいのに」と自分に言い聞かせた後知恵の経験は何度もありましたが、「頭の後ろの小さな声を聞いて、もう少し作ったらここでジェネリック」。

私はまだ電話をかけるための絶対的なルールを蒸留していません...

過剰に設計されやすいのではないかと思うので、この写真をPCの壁紙にしました。 

0
Cornel Masson