web-dev-qa-db-ja.com

OOPに関する背景/考え方が混在するチームで効果的に協力するにはどうすればよいですか?

私は最近、自分自身を「主にC/C++プログラマー」と呼んでいる他の3人と一緒に、新しい高性能C++プロジェクト(ファイナンス)に割り当てられました。つまり、私たち全員もJavaやその他のものは、私たち全員が同等の経験(8〜10年)を持ち、他のプロジェクト(C/C++ではない)の作成に協力して成功しています。

私たちの「マザープログラミングタン」については、プロジェクトが適切に提供されるだけでなく、チームやオフィスの全般的な健康にもリスクがあるという考え方が異なることに気づきました。具体的には:

それらは、電気工学/自動化/ポリテクニックタイプの背景から来ているため、その理由は、ハードウェアの動作、バイトの動き方、プロセッサの動作、命令のキャッシュ、一般に下位層のすべてに密接に関連しています。彼らは組み込みプログラミング、ARMプログラミングを行いました(私はそれらが何であるかほとんど知りません)。私はすぐに、彼らの実践的な経験がC++ではなくほとんどCであることがわかりました。彼らはOOPではなく、手続き的に考えます。

一方、私は再利用可能なモジュール式ソフトウェアを作成するために、カプセル化、低結合/高凝集などの原則を適用するように、より抽象的な方法で考えるように自分自身を訓練しました。私の専門はC++プログラミング言語で、高速で再利用可能な汎用コードの両方を手に入れるのに役立つ言語構造にアクセントがあります。デザインパターン、イディオム、コンセプトだと思います。 9年間のソフトウェア開発を通じて、私は一貫して、ソフトウェアシステムの保守性の悪さがチームの最大の負担であることを目の当たりにしました。私は寛大に私のコードを文書化し、注意深いインターフェースを書きます。高速で再利用可能な製品を入手する方法として、テンプレートメタプログラミングを採用しています。新しいC++ 11標準機能を採用しています。

再利用性と疎結合を見ると、「複雑さ」が見えます。彼らは「すべてをそこに見たい」と思っています。インターフェースメソッドの一部のバッファクラスではなく、char*を確認したいと考えています。ある時点で、「実装が複雑に見えても、インターフェースがどれほど単純であるかは気にしません」とさえ言った。問題は、モノリシックスタイルのシステムから再利用可能なシステムへの移行を実際に試みていることです。ライブラリを作成しています。それでも、Cスタイルの構造体がテンプレート化されたメソッド、typedef、およびc-torで汚染されていることを望んでいません。また、static_assert(std :: is_pod <...>)も見たくありません。彼らはmemcpyとポインタを愛し、一般的に参照から離れています。彼らはtypedefがどういうわけか悪いと思う傾向があります。

私は本当に彼らにそれが何であるかについての抽象化を見せるようにしようとしました。それはそれが操作するデータと一緒のコードです。必要に応じて、ライブラリーは、ユーザーがそれをより大きな製品にプラグインできるように、いくつかのインターフェースを定義する必要があります。彼らはこれらのインターフェイスを私のコードの方法と見なす傾向があります彼らのコードは私が望むように動作/見せる必要があり、彼らが自分のやり方で行うことを許可しません、しかし実際に彼らにできる特定の機能を伝えることなく取得しません。

間違いなく、私はパフォーマンスに関して無知ではありません。キャッシュライン、分岐予測、メソッド仮想化のオーバーヘッド、ヒープ割り当て、ハッシュルックアップについて知っています。アルゴリズムの複雑さ(ここではそれほど重要ではありませんが)、データ構造、インライン化、およびRVOなどのその他のコンパイラーの最適化が得意です。最新のコンパイラーを使用すると、再利用可能なレイヤー化されたOOP C++製品は、注意深く記述して最適化すると、Cのみのモノリシック製品のパフォーマンスの10%以内に収まると考えています。

私は正直に言って、私たちの考えでお互いを補完し合うと信じていました。

あなたの考えは何ですか?私たちがこの仕事をする必要があるので、厳しすぎないでください。

16
haelix

わかりました。まだ誰も行っていないので、ここで説明します。

私の経験はおそらく多少似ています。私は1年ほど前にソフトウェア部門から職場の組み込みソフトウェア部門に異動しましたが、あなたがここで表現している感情の響きは間違いなく聞きました。

ここにあなたがここにリストしたものに沿って私が行ったいくつかの観察があります。これらは、さまざまなグループの視点を表しています。

  • 組み込みプログラマは、スタックとRAIIが大好きです。スマートポインタなどが必要ないのに、なぜそれを使うのか。ヒープは悪です。彼らは実際にこれについて一種正しいです。
  • ソフトウェアプログラマーは、抽象化がもたらすパワーを理解しているため、インターフェースを愛する傾向があります。情報を隠す方が良い場合もあります。依存関係の逆転により、テスト容易性が向上します。
  • 多くの場合、組み込みプログラマは機能テストをよりよく行い、ソフトウェアプログラマはユニットテストをより良く行います。

私の持ち帰り?多くの場合、組み込み/ EEのバックグラウンドは、アーキテクト(特に大規模なシステム)の能力が低下し、ソフトウェアのバックグラウンドは、重要ではない事柄にとげとげしがちで、測定や理論よりも理論上のパフォーマンスの向上に重点を置く傾向があります。それを改善します。あなたのマイレージは異なる場合があります。

チームビルディングの観点からは、相互の視点を尊重することの尊重が重要であることがわかりました。それは私の目標であり、かなりの方法でなくなっていると思います。

C++の使用法の観点から、いくつかの、おそらく苦痛な提案をしたいと思います。これらすべてを、私がソフトウェアと組み込みソフトウェアのアプローチで異なることに気付いたものの観点から見てください。スタイルに関する単なる炎に値する論説としてではありません。

  • パフォーマンスは重要ですが、これが組み込みデバイスで発生することはほとんどありません。つまり、最新のコンピューターを扱っている場合、一般的な組み込みトリックの多くはまったく適用されません。とはいえ、一部の人はまだやっているので、チームと話し合って自分が何をしていると思うかを確認するのが良いでしょう。これらの事前知識を理解することは、それらを念頭に置いて設計できることを意味します。
  • メタプログラミングと単純な再利用可能なインターフェースのような光沢のあるものには違いがあります。率直に言って、再利用性の観点から、良識のあるインターフェースを最大限に活用することができます。これは戦う価値があります...しかし...
  • 私はいくつかのテンプレートメタプログラミングのファンですが、おそらくそれを疑わしいインジケータとして「採用」するという声明を見つけがちです...本当にメタプログラミングをプッシュする必要がありますか?またはおそらく特性?それともラムダ?またはほとんどC++ 11の機能?これらはあなたのお気に入りのツールの一部であると理解していますが、彼らは本当に戦いを選ぶ価値がありますか?これらの増加再利用性がそれほど大きくなることを率直に言って販売していません。プログラマの生産性などが向上しますが、妥協が必要な場合があるようです。
  • 単純な古いデータ用の場所とnotブリット可能なクラス用の場所があります。一般的に言えば、構造体とクラスのような単純な規則に固執し、それを適切に呼び出します。このようなことをする場合、is_podは本当に必要ですか?
  • 特に、多くのスタックベースのプログラミングをしている場合は、参照がプッシュする価値があると主張します(あなたは正しいですか?RAIIとすべて?)。以前は、制限と正しい使用法を適切に理解していないため、参照も悪だと思っていました。コードの適切なチャンクのためにNULLポインターについて心配する必要がないことを示すだけで、おそらく彼らは同意するでしょう。
  • スレッド化について前もって話したいと思うかもしれません。多くの場合、組み込みプログラムはスケジューラを使用して単一のスレッドで多くの作業を行いますが、高レベルのソフトウェアは多くのスレッドを選択します。間違いなく、スケジューラの方法は特定の点で高速です(特に複数のスレッドと組み合わせる場合)が、私がこれを持ち出した理由は、作業がどのようにスライスされるかです。どっちに行くかによって劇的に変わるかもしれません。スケジュールされた作業は水平スライスで、スレッド作業は垂直スライスで発生する傾向があります。また、埋め込まれた側でロックするためのアプローチが少し弱いことがよくあります。これは、スレッドが1つしかないことが多いためです。これも再確認する価値があります。
  • 多くの場合、テンプレートは優れている場合があります(STLの略です!)が、ここには間違いなく複雑な構文があります。私はtypenameキーワードを探しています。また、.h/.hppなどの規則が明確に記述されていることを確認してください。私は組み込みプログラマーから、テンプレートについての意見が混じり合っているのを見てきました。チームメイトが触れないコードを書かないようにしてください。
  • 私はtypedefsについて引き裂かれています。一方で、型を抽象化し、いくつかのことを簡単にするのに役立ちます。しかし、多くのtypedefが含まれているコードを見てきたので、取得して読み取るのは非常に困難でした。私がそれらを効果的に使用していると思われる4つの場所は、1)ハードウェア関連の型を抽象化するためのパブリックスコープ、2)sizeofを実行できるようにヘッダーフィールドのタイプをプライベートスコープ、それでも問題ない、3)イテレータのプライベートスコープです、4)関数ポインタのスコープが公になっている。これらを超えた使用例では、慎重に行わないとしても、多くの場合、相互に目を向け始めました。

もちろん、あなたは2人のプログラマーを部屋に入れ、3つの意見を得ます。気付いた。しかし、組み込みソフトウェアとソフトウェアの境界では、これらは私が気付いたことです。お役に立てば幸いです。 (ただし念のため、耐熱スーツを先制しました。)

そして最後にもう一つ。相互の尊敬と賞賛を築く方向に沿って、彼らに途中で会って、おそらく テンプレートベースのレジスタアクセス のようなものを見て、このようなものについて友好的な議論を始めることは害がないかもしれません。

11
J Trana