プロのソフトウェア開発チームは、重要なプロジェクトの複雑な設計にどのように対処しますか?


9

まず、私はこの質問が多少長く漠然としていることを理解しており、お詫び申し上げます。これはおそらく、「理解した」人にとっては短い名前の基本的な問題ですが、私はこの点について欠けていると思うので、問題を説明する際はご容赦ください。

私は11歳の頃から、この方法でプログラミングを行ってきました。これは、私が最初から自分にすべてを教えていたことを意味します。私は技術教育を受けましたが、厳密にはコンピュータサイエンスではありませんでした(私はフォトニックエンジニアリングの学位を取得して卒業しています)。もちろんプログラミングコースもありましたが、これは私にとっては基本的なもので、新しいことはあまり学びませんでした。私はその喜びのために自分自身を教育し続けており、プログラミングのキャリアを追求することを常に知っていましたが、その当時の私のプロジェクトはすべて非常に小規模でした。私はそれらを私の心に留め、維持するのに問題はありませんでした。

現在、私はチームでリードしていますが、企業環境ではありません-私は大学でエンジニアリングアプリケーション用の科学ソフトウェア(C ++)を開発しています。突然、プロジェクトは(比較的)大きくなり、ほとんどの場合、私はそれを心に抱くことができなくなりました。主に次の2つのことに多くの時間と労力を費やしています。

  1. しばらく作業していなかったコードのセクションに戻る必要がある場合、それがどのように機能したかを思い出すことが困難です。私は、関連するクラスのヘッダーファイルを確認し、途中でソースファイルに配置したコメントを読むのに多くの時間を費やしています。私が垣間見ることができ、より簡単に画像を取り戻すことができる何らかの「回路図」があるといいのですが。
  2. 変更を導入するとき、私がやろうとしていることが他の場所で何かを壊してしまうことの中間点に気付くことがあります(さらに悪いことに、それは実行時にのみ驚きとして現れます)。私は元に戻して別の方法で始めましたが、他のコンポーネントへの影響を無視したことがわかりました。何かが行われる方法、他のコンポーネントに影響を与える方法、変更を実装する前に詳細に計画する方法を確認できる「アーキテクチャダイアグラム」があったらいいのにと思います。

私が一緒に仕事をする人のほとんどは私と同じようなストーリーを持っています-強力な技術的志向と時には素晴らしいスキルですが、彼らの仕事を整理する方法がありません。しかし、彼らのプロジェクトは通常私のプロジェクトよりもはるかに小さいので、彼らはどういうわけか対処します。とにかく、それが私にとって何を意味するかというと、私は一人でいるので、良い実践を学ぶ人がいないということです。

ITの管理に関する大学院のコースを受講しましたが、ITの管理は非常に満足できるものであると感じましたが、主に非プログラマーを対象としており、プロジェクト管理の方法論、予算/スケジュールの見積もり、エンタープライズアーキテクチャなどについて説明しており、ソフトウェアの設計や計画などは担当していません。それは大丈夫です、私もそのことを学ぼうとしています。もちろん、いくつかのツール(UMLなど)とソフトウェア開発プロセスのタイプ(カスケード、反復、アジャイル...)が導入されましたが、明らかにそれほど詳細ではなく、何を選択して使用するかを決めるのに苦労しました(とどの程度)。

私はSOのソフトウェア設計について多くの質問と回答を読んでいます-これまたはその特定のツールまたは方法論を使用してそれを行うことについては多くあります。UMLのドキュメントが私の問題を解決すると確信している場合-私はそれをピックアップし、それを使い始める。しかし、それを誓う人もいれば、役に立たないと言う人もいます。抽象化のより高いレベルでの答えを探しています-私が抱えている2つの問題を解決する方法はありますか。おそらく1つの特定のツールに縛られることなく、それを実行できるようにするには何を学ばなければなりませんか?これらは時々流行から脱却し、プロジェクトの種類によって適用性が異なると思います。

読んでくれてありがとう、私はもっと簡潔に言うことができませんでした(ソフトウェア設計の経験と語彙が不足しています)。


2
あなたが話している困難への最も一般的な専門家の反応は、「Fuck it」であり、その後に管理、製品、またはその他のランダムなSOBを非難します。
エドワードストレンジ

回答:


9

しばらく作業していなかったコードのセクションに戻る必要がある場合、それがどのように機能したかを思い出すことが困難です。私は、関連するクラスのヘッダーファイルを確認し、途中でソースファイルに配置したコメントを読むのに多くの時間を費やしています。

あなたの後に来る貧しい人がどのように感じるか想像してみてください-彼はあなたのコードがどのように機能するかを一度知っていたという利点さえ持っていません。コードを解読しようとする代わりに、問題のモジュール用に作成したドキュメントを確認する必要があります。そのドキュメントは、モジュールが何をするのかについて、かなり正確な見解を提供するはずです。「モジュールは、トリプルforループを使用して3つの配列を初期化することから始まります」ではなく、「このモジュールは、Fabulotronのメインセンサーによって収集されたデータを取得し、それを標準のネオポリタン(チョコレート、バニラ、イチゴ)形式に再配置します。分析モジュールに配信します。」

完璧な世界では、システムのさまざまなモジュールを説明し、それぞれの責任を説明する設計ドキュメントがあり、各モジュールはそのドキュメントを参照して、その機能を説明することができます。「このモジュールは、設計ドキュメントのセクション4.8で説明するようにFabulotronデータ収集サービス:http://fabulotron.org/design/section4-8.html「。そのようなものがない場合は、作業するときに各モジュールの概要を書き留めてください。あなたは本を書く必要はありません-いくつかの段落はあなたを方向付けるのに十分です。

変更を導入するとき、私がやろうとしていることが他の場所で何かを壊してしまうことの中間点に気付くことがあります(さらに悪いことに、それは実行時にのみ驚きとして現れます)。私は元に戻して別の方法で始めましたが、他のコンポーネントへの影響を無視したことがわかりました。

これは、モジュールが相互接続されていることを示している可能性があります。モジュール/クラス/ユニットをより独立させることができるほど、この種の問題に遭遇する可能性は低くなります。モジュール間のインターフェースをできるだけ明示的にして、それらをそこに必要なものだけに制限するようにしてください。インターフェースはコントラクトです-一部のモジュールがインターフェースで指定された義務を果たしていることがわかっている場合は、それについて他に何も知る必要はありません。これにより、作業中のモジュールの変更が他のモジュールに影響するのを防ぐことができます。

私は物事がどのように行われるかを見ることができるいくつかの「アーキテクチャ図」があればいいのに

この点で、標準部品を使用すると役立ちます。C ++は、標準テンプレートライブラリの形式で標準部品を提供し、必要に応じてそれらの部品を使用すると、より高い抽象化レベルで作業できます。リストなどのデータ構造を管理するための独自のコードを作成した場合、あなたとそれに続く人は常にソースを読んで何が起こっているのかを理解する必要があります。代わりにSTLによって提供される標準部品を使用する場合、C ++プログラマーは、データ管理ルーチンを掘り下げることなく、コードが何をしているかをすばやく知ることができます。

別の種類の標準部品は、デザインパターンに由来します。これらは、2つのオブジェクト間の関係がどのように機能するかを説明するための省略表現として使用できる標準的な概念です。


答えてくれてありがとう。もちろん私は長年STLを使用してきましたが、プログラムが不自然な計算を実行するために実行する一連のステップは、その使用方法を使用しても全体を把握することが難しい場合があります。モジュールについても同様です。私は1つを変更すると別の問題が発生するのではなく、どこかを変更するとグリッチが発生することを意味します。たとえば、ユーザーがGUIで標準以外のことを行うと、複雑なシーケンスが、それを完了するために実行する予測できない手順の順序によってさらに複雑になります。
neuviemeporte

5

私は短期間だけプロの開発者であり、これを最初に始めたとき、これを行う方法について多くの苦労をしました。私は大学を通してさえ、主に独学でした。幸いなことに、私と一緒に働いた人々は多くの経験を持ち、大規模なプロジェクトを管理および作業する方法について私を教育することができました。

私が最初にやったことの1つは、座ってきれいなコードを読むことでした。これは、私が戻ったときに理解できる、または他の誰かが理解できるコードの記述方法を理解するのに役立つ素晴らしい本です。

2つ目は、ユニット、統合、受け入れという良質のテストを書くことでした。コードが十分にテストされていれば、何かが壊れたときがすぐにわかり、問題をすばやく診断できます。インターネットには多くの優れたテストリソースがあり、どれがあなたに提案するのが最善かわかりません。

私の重要なポイントは、テストとコードのクリーンアップです。


提案をありがとう、私は必ず本をチェックアウトします(サブタイトルの「アジャイル」はそれがその方法論に主に関連していることを示しているようですが)。私はテストを行っており、多くのコーディングスタイルブック(Pragmatic Programmerなど)を読んでいますが、常にクリーンで適切に分離されたインターフェイスを作成するよう努めていますが、1つの自動テストではアプリケーションのGUI部分が難しく、それでもまだありません。より大規模な全体的な設計を行うための方法。これは、比較的小さなコードのチャンクに「クリーン」プラクティスを実装するだけではありません。
neuviemeporte

2

大規模なソフトウェアシステムを編成するための高レベルのアイデアをいくつか示します。私の経験のほとんどはインターネットシステムに関するものですが、これらのアイデアはエンジニアリングソフトウェアにも当てはまると思います。

  • 機能を比較的分離されたモジュラーブロックに分離します。たとえば、ソフトウェアが提供する計算のファミリごとにモジュールがある場合があります。
  • MVCデザインパターンがある場合は、ユーザーインターフェイスに適用します。明確に定義された境界でインターフェースとモデルを分離してください。
  • レイヤーを使用してモジュールをグループ化することを検討してください。抽象化レイヤーを使用するアプリケーションでは、各レイヤーはその下のレイヤーにのみ依存します。
  • ドキュメントを書くときは、実装の詳細をすべて忘れてしまうことを想定してください。この仮定の下で多くのドキュメントを作成します。おそらくコードの半分ほどがコメントになるでしょうが、後で混乱することはほとんどありません。
  • 自動化された単体テスト、統合テスト、受け入れテストは、一部の分野では優れていますが、C ++開発者はそれらについて複雑な感情を持っているようです。
  • デザインパターンに重点を置きます。一般的に良いアイデアであることに加えて、デザインパターンはソフトウェアエンジニアリングにおける一般的な語彙を提供します。クラスをWidgetFactoryと呼ぶことは、それがウィジェットを作成するために存在するクラスであることを伝える簡潔な方法です。

私がエンジニアリングソフトウェアを使用してから長い時間が経過しているため、これらの提案によって走行距離が異なる場合があります。幸運を!


1

答えはソフトウェア工学です。

これは、大規模なプロジェクトの場合、実際のコーディングが行われるずっと前に、一連の要件収集、プロセス定義、仕様などに従うものです。

環境や文化に応じてさまざまな方法論が使用されます。エンタープライズタイプのビジネスは、「Rational Unified Process」または同様のプロセスに従う傾向があり、技術系の新興企業は通常、アジャイルや政府部門の過労ウォーターフォール手法にいくつかのバリエーションを加えます。

すべての場合において、このプロセスは、あなたが何をしているかを正確に定義するのに役立ち、プロジェクトの終わりに近づくと、あなたがそれを行ったことを証明することができます。


要件が変わらないと仮定すると(多くの場合、非現実的な仮定ですが)、コーディングの前にすべてを指定し、仕様に沿って大きな変更を加えずに仕様から実用的なソフトウェアを作成することは実際に可能ですか?描けないだけです。感じに入るにはコーディングを始めなければなりません。少し微調整したり、さらに微調整したりします...
neuviemeporte

これは小規模なプロジェクトでは機能しますが、大規模なプロジェクトでは、まず要件を把握する必要があります。また、RUPの重要な部分は、提案されたシステムをUMLおよびシーケンス図でモデル化することです。実際のコードよりもモデルの調整とリファクタリングがはるかに簡単です。
Jamesアンダーソン、

@neuviemeporte:場合によります。開発中に要件が変更されたり、新しい要件が発見されたりすることがあります。要件は最初から非常に明確であり、開発中に変更されるのはごく一部の詳細だけですが、全体的なアーキテクチャは同じままです。
ジョルジョ

1

無料ではありませんが、アカデミック価格を提供しているEnterprise Architectをぜひお試しください。マクロとミクロの両方のレベルでプロジェクトを図式化するための優れたツールです。また、ソースファイルをクラスダイアグラムにリバースエンジニアリングすることもできます。これは、アプリケーションがどのように連携するかを文書化して再編成するための良い出発点になるでしょう。

@Kleeの2番目の推奨事項も紹介します。想定される「アジャイル」ツールに気を取られないでください。これらは本当にベストプラクティスのアイテムであり、アジャイルプロセスに従っている場合(必須ではない場合)にも便利です。ただし、継続的インテグレーション(たとえば)は、どのような方法論でも重要です。さらに、単体テスト(cppUnit?)はあなたの友達です。UIを直接テストするのではなく、UIによって呼び出されるロジッククラスをテストする場合、ユニットテストは非常に実行可能でなければなりません。UIテストの自動化に役立つツールもありますが、私は最初にバックエンドのものをまとめるようにしています。

幸運を!


1

あなたの問題には3つの側面があると思います

  1. プログラマー指向
  2. プログラム指向
  3. プログラムのメンテナンス-指向

最初の問題に関しては、プログラムの機能の概念を理解していないプログラマーがいる可能性があります(これは多くの場合、企業のセットアップで発生します)。しかし、あなたの質問とあなたがいるドメインによって、あなたとあなたのチームはプログラムが何をするかを制御しているようですが、それをすぐに実用的なプログラムに変換することはできません(例を引用すると、私は人々について聞いたことがあります物理学の博士号を取得していて、プログラミングの指針を理解するのに問題があり、物理学はC ++よりもはるかに難しいと確信しています。それが事実である場合、問題はほとんどプログラム中心です(あなたは周りの人があなたのプログラムが何をしているかを理解し、それを理解できるほど幸運に感じる必要があります)。

プログラム中心の問題の場合、私のとんでもない提案の1つは、新しい言語をPythonまたはHaskellとして学習するなど、C ++よりも高いレベルの抽象化に移行することです(Pythonは非常に簡単に習得でき、優れた数学者がいる場合、ハスケルは素晴らしいです)。抽象化のレベルを上げると、コードサイズが小さくなり、理解しやすく、長期的に維持しやすくなり、変更を迅速に反映できます。したがって、元の50行のコードの代わりに10行のコードを使用できます。また、コンピュータプログラミングの専門知識を持つ人がいることは間違いなく役立ちます。大学に所属している場合は、GUIとインターフェースに数人の学生を参加させて、機能により集中できるようにすることもできます。John Lakosによる本「Large-Scale C ++ Software Design」もお勧めします(それはかなり大きな本です。あなたは本を読むのにかかる時間に熟練したPythonプログラマーになることができます)

問題の最初の2つの次元を整理すると、3番目は自動的に解決されます。私はあなたが単一の大きなプロジェクトに取り組んでいると信じているので、あなたがそれを手に入れるためのまともなプロジェクト管理ソフトウェア。事前の計画が必要です。すぐにコーディングを開始すると、全体像を忘れてしまうほどプログラムに関与しすぎる可能性があります。事を念頭に置いておけば、大きなプロジェクトではうまくいきません。すべてを紙(またはコンピュータ)に入れます。wikiを使用して情報を共有します。方法論に関しては、私はアジャイル方法論を好む(単純に、アジャイルはインクリメンタルソフトウェア開発のスタイリッシュな名前です)。また、コアプログラムに集中できるように、この分野の専門知識を持つ人を雇って彼がこれらの面倒を見るように依頼することもお勧めします。ここでの結論は、すべてのプロジェクト管理方法論はプログラムの成功を確実にするための単なる方法であるということです。そのため、誰かが最高のものを推奨するものを選択する代わりに、あなたとあなたのチームに合った人を選ぶことができます。また、次のソフトウェアも役立ちます

  • 無料マインド-マインドマッピングソフトウェア
  • Trac-迅速で簡単なソフトウェアバグプログラムとwiki
  • MoinMoin-プログラムに関する知識の共有を可能にするクイックWiki

上記のヒントは、ある程度の学習曲線を必要としますが、長期的にはそれだけの価値があります。そして最後に、プログラミングはフォトニックエンジニアリングよりも簡単です(ただしC ++プログラミングではありません)。


0

あなたの質問のように、あなたにとって役立つどんな答えも非常に長く曖昧になります-しかし、短い答えは「ソフトウェアエンジニアリング」です

ソフトウェア開発のキャリアに真剣に取り組んでいる場合は、可能な限り時間を空けて、Steve McConnellsサイトにアクセスすることから始めることをお勧めします。プログラミングは簡単で、学期に教えることができますが、ソフトウェアエンジニアリングは桁違いに複雑であり、学ぶにはもっと長い時間が必要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.