一般的なプログラミングに対する認識をチームメンバーに広めるにはどうすればよいですか?


20

私は人々が信じる環境にとどまっています:

  1. Javaジェネリックは、実際のコーディングではなく、ライブラリの書き込み専用に使用される機能です。
  2. C ++はオブジェクト指向プログラミング言語です。templateオプションで回避可能な機能です

ただし、これらの人々は、汎用プログラミング(STL、Javaコンテナーなど)を使用して作成されたライブラリーに大きく依存しています。templatesまたはを使用してコードを記述する場合generics、コードレビューアはそれを拒否する可能性が高く、「適切/理解可能/エレガント」な方法でそれを記述するようコメントします。

このような考え方は、通常のプログラマーから上級管理職まで適用できます。90%の時間、これらの人々はロビー活動をしているため、逃げ道はありません。

それらを説明する最良の方法(のどを切らない)、OOと汎用プログラミングの両方を同時に構成するコードを記述する実際的なアプローチは何ですか?


11
私はあなたに最高の幸運を願っていますが、おそらくあなたがあなたの方法をしたい場合ままにする必要があるとしている...
マフィンマン

3
@TheMuffinMan、あなたは正しい。私はその職場を去り、今では自分の会社を持っています。ここで、コーディングを完全に制御できます!
iammilind 14年

回答:


14

世界の人々はまだありいけないに使用javeのジェネリックを「普通のコーディングは。」私はC ++テンプレートでそれを信じることができますが、ジェネリックですか?学ぶことも使うことも難しくありません。真剣にJavaとC ++の最高の機能はそれぞれジェネリックとテンプレートです。

人々に物事を納得させる最善の方法は、説得力のある議論を行い、脅迫的でなく、正しいことです。

プログラミング言語としてテンプレートを使用するようなことをしていない限り、パラメトリック多相性(ジェネリック/テンプレート)はほぼ間違いなく優れています。

1.コードの重複を回避します。

これは明らかですが、多態性コードは一般的なコードです。それがジェネリックと呼ばれる理由です。

2.より良い静的チェックをサポートします。

パラメトリック多型がなければ、あなたは、のようなものを書いて終わるpublic Object clone()か、public boolean equals(object b)単に憎むべきものではありませんこれは、彼らが何をすべきかについての情報を提供しないタイプがあり、常にあらゆる場所に例外をスローに終わります。パラメトリック多型の代替は、あちこちにキャストされます

3.非パラメトリック多相性OOPコードは、基本的に「バイナリメソッド」を正しい方法で処理できません。

これらを頻繁に使用します。

4.ベストプラクティスです

Javaでは、ジェネリックの使用がベストプラクティスと見なされます(Josh BlochによるEffective Javaを参照)。SutterやAlexandrescuなどの主要なC ++思想家も、さまざまな問題を解決するためにテンプレートの使用を奨励しています。

5. OOパラダイムに適合します。

人々はしばしばこれに気付かないが、サブタイピングとジェネリックの組み合わせは、それらのうちの1つだけを備えたどのシステムよりもはるかに強力で表現力豊かでオブジェクト指向のシステムを生み出す。

Scalaのミックスインを検討してください。これらは、コンポーネントパーツからオブジェクトをまとめることができる便利な機能です。ジェネリックとテンプレートは、これらの利点の一部をシミュレートできます。たとえば、オブジェクトの1つがデータベースを使用しているとします。優れた設計では、データベースアクセスを別のクラスに抽象化する必要があります。これを正しく行うと、データストアをモックできるようになるだけでなく(テスト容易性の鍵)、新しいno-sqlデータベースなどの代替実装を追加できるようになります。ただし、ここで問題が発生する可能性があります。使用する実装に関係なく、ビジネスオブジェクトのさまざまな機能を取得できます。

ジェネリック医薬品の救助!

   public class Business<S extends Datastore>{
      private S store; ...
   }

これで、Businessデータベース固有の機能を使用する能力に基づいて、オブジェクトの静的な差別化を開始できます。いくつかのランタイムチェックとキャストが必要ですが、より優れたコードの構築を開始できます。

そして

6.通常のコードは存在しません。

プログラミングの世界には3つのことしかありません。

  1. ライブラリ、
  2. 構成、および
  3. 悪いコード。

コードをライブラリのように考えないと、プロジェクトの要件が変わったときに深刻な問題に直面します。アーキテクチャは(ほぼ間違いなく)優れたAPIを設計する技術です。

この態度は素晴らしいと思います。パラメーター化された型を使用したプログラミングに慣れた後、それらを使用しないと、すべてが苦痛になります。また、JavaとC ++には、改善に役立つ大まかなスポットがたくさんあります。


7
私の概念のようなnormal code存在せず、わずか3種類があること:librariesconfigurationsbad code。あなたは理想主義者ではないかもしれませんが、同僚に説明する必要がありますが、理想主義的な推論です。ただし、パラメータ化された型を使用するのは、いったん慣れてしまえば、驚くばかりです。
スポーク

3
ちなみに、テンプレートメタプログラミングの目的で使用しないのであれば、C ++テンプレートでさえそれほど難しくありません。:-)
インシリコ

-1は、ジェネリックを使用しないことを決定したすべての人が、機能がどのように機能するかを知らないという理由だけでそれを行うことを示唆しているためです。
tp1

誤用の可能性を考えると、ジェネリック/テンプレートを制限する/使用しないことは、クレジットを与えるより良い決定になると思います。
リャサル

大規模なソフトウェアエンジニアリングにジェネリック/テンプレートを使用することを拒否する人は、誤って「必然的に」「第2言語」を構築します。en.wikipedia.org/wiki/Inner-platform_effect
rwong 14

16

これは、「より優れた技術/物事の作り方を上司にどのように説得してもらうか」というより一般的な質問の特殊な形式です。

残念ながら、私はあなたができるとは思いませんし、あなたがすべきだとは思いません。彼らはあなたが好きな方法ではなく、彼らが選んだ特定の方法で物事をするためにあなたにお金を払っているので、定義によって彼らの選択です。あなたができる最善のことは、この技術が世に出ており、多くの人々がそれを使用していることを示唆することであり、それは未来の道のようです。もちろん、彼らがすでに知っているべきである事実に言及したいかもしれません:人々が彼らのスキルを停滞させないことが最善であるということです。しかし、それだけです。もし彼らがそれを買わなければ、あなたにできることは何もありません。

あなたは彼らのレベルで考えていないので、彼らはあなたが持っていない他の考慮事項を持っているかもしれません。あなたはエンジニアとして考えています。彼らはビジネス用語や人事用語でもっと考えているかもしれません。

  • ジェネリック医薬品(またはその他)は、製品の価値を向上させますか?おそらくない。

  • ジェネリック(または何でも)は、すでに雇用した人々が仕事をするのを難しくしますか?はい。

  • ジェネリックは市場投入までの時間を改善しますか?唯一のエンジニアがあなたなら、多分。しかし、家の中で別のコード行を書く前に、多くのエンジニアがジェネリックについて教育する必要がある場合、いいえ。

ですから、あなたはただ転職することを検討したいと思うかもしれません。私の最後の仕事で、私はJavaでジェネリックを最初に使用しましたが、幸いなことにJavaには問題がありませんでした。彼らはジェネリックがコードを「読みにくくする」という懸念を表明しましたが、彼らは私に道を譲らせました。そのような仕事を見つけてください。


9

レビューの前にジェネリックのメリットをコードレビュー担当者や他の同僚にブロードキャストします。

1)ジェネリッククラスまたはメソッドによって処理される型を指定できるようにすることで、ジェネリック機能は型安全性の負担をユーザーからコンパイラーに移します。コンパイル時に実行されるため、正しいデータ型をテストするためのコードを記述する必要はありません。型キャストの必要性と実行時エラーの可能性が減少します。

2)ジェネリックは、複数の実装のオーバーヘッドなしで型の安全性を提供します。

したがって、[1]と[2]はコードのエラーのリスクを減らします。これにより、開発者の時間が節約されるため、会社のお金を節約できます。

読みやすさが問題である場合、ジェネリック型を使用することの厄介さが損なわれる可能性があります。これは、コーディングガイドラインを拡張したい理由の1つです。これは、ライブラリを拡張するためだけでなく、稼働中のコンテキストで実行できます(ただし、後で簡単に認識できるように、コード内でライブラリの可能な候補メソッドをマークして、リファクタリングすることをお勧めします)。したがって、平日のコンテキストでそれらを使用しない理由はありません。

他のプログラマーがジェネリックに関する問題を抱えていないことについて、いくつかのステートメントを追加します。ジェネリックは、JavaおよびC#などの他の多くの言語で広く使用されています。真面目なプログラマーであれば、そのようなタイプセーフなビルディングブロックがないと、人生が困難になるでしょう。

それでも、一部の開発者はスクラッチに慣れていない可能性があることを考慮する必要があります。経営陣は、過去にプロジェクトを保護するために意識的な決定を下し、それによってこれらのチャップを危険な領域から遠ざけることができたでしょう。ここでは、十分な分析やミクロ管理が行われることはめったにないため、通常、罪のない人と罪のある人の両方が責任を負います。

良いケースを提起し、見返りに理由のある回答が得られない場合は、プログラミングを真剣に考えている別の会社を密かに探し始めます。


7

あなたがアーキテクト/技術リーダーでない限り、ジェネリック/テンプレートを使用することを義務付けることは困難です。コードレビューのかなり前、できれば実装を開始する前に、ジェネリック/テンプレートソリューションを提案する必要があります。

できることは、ある場合にジェネリックを使用する理由を示すことです。メリットを実証できれば、同僚も同意するかもしれません。ジェネリック/テンプレートを使用する理由として考えられるものは次のとおりです。

  • 反復的なタスクのためのコードの記述を少なくする必要があります
  • プログラマーの仕事が楽になる
  • ソリューションアーキテクトが設定したパターンを適用します
  • 共通の機能をカプセル化するため、プログラマーはコードをコピーアンドペーストする必要がなくなります(つまり、二重のメンテナンスの問題を回避します)。
  • それは合理的に将来あなたのコードを証明します(この道は推論するのが難しいですが)

それはいくつかの基本的な事柄を満たしているため、最近のJavaプロジェクトでは私は正常にいくつかの一般的な抽象クラスを追加しました:それは、チーム内の他の人のために簡単なものを作った建築家が既に提案されているというパターンを施行し、プログラマがする必要がなかったことを、いくつかの共通のコードを持っていましたコピーアンドペースト。(実際のシステムが複雑であるため)合理的に有能な人々がまだ間違っていると建築家が書いた単純なパターンでしたが、ジェネリックはどのクラスがどこに行くかを示しています。

明らかに、秘密保持契約に違反しない限り、実際の例を誇示することはできません。しかし、私がしたことの例としては、戦略パターンを実行し、ジェネリックでそれを強制することです。これが戦略パターンです:

ここに画像の説明を入力してください

そして、プログラマーがこのパターンを実施するために、タイプContextを持つものを使用する必要がある汎用タイプを追加できますStrategy。コード的には、Javaでは次のようになります。

// declare the generic Context class that has a type "S" 
// that is an upper bound class of Strategy
public class Context <S extends Strategy> {
    S strategy;

    // Constructor with an initial strategy
    public Context(S initialStrategy) {
        this.strategy = initialStrategy;
    }

    public void doSomething() {
      strategy.execute(); // assumes that Strategy has an execute() method.
    }

    public void setStrategy(S strategy) {
        this.strategy = strategy;
    }
}

私の知る限り、これはほとんどどのパターンでも実行できます。コードデザインに自信を持つために、単体テストでジェネリック/テンプレートデザインをテストして、それが機能することを確認してください。

同僚がそのアイデアを好まない場合、個人的にそれを受け入れない場合、あなたが思ったほど簡単に対処できる解決策になっていなかったかもしれません。そのため、実装を開始する前にジェネリック/テンプレートソリューションを提案する必要があります。同僚と協力して、実際の問題を別の方法で解決する必要があります。


図が大好き!どのツールを使用しましたか?
ヤニス

@YannisRizos テキスト入力から図を作成するyuml.meを使用しました。ただし、現時点ではベータサービスは少しバグがあります(ただし、生成されたリンクを使用して、生成された画像を投稿にアップロードできます)。
スポイケ

ブックマーク済み、共有していただきありがとうございます。私はまだ別の構文を学びたくはありませんが、単純ですが、見た目はクールで、ある時点で試してみます。
ヤニス

@YannisRizosああ、私は常に構文を忘れてしまいました。それが便利なサンプルページある理由です。Visioを使用するよりも、ymlで簡単なクラス図を作成する方が速いことがわかりました。
スポーク

@YannisRizos yUmlはクールなツールです。以下に、それを使ってできることの例をいくつか示します。carnotaurus.philipcarney.com
tagged

4

同じことを行うには、常にいくつかの方法があります。テンプレートの使用がテンプレートの誤用である場合、コードレビューに失敗するはずです。

ただし、テンプレートを理解していないためにコードがレビューに失敗した場合、問題の種類は異なります。その場合は、テンプレートを学習するよう(良い方法で)アドバイスしてください。


4

ここで扱っているのは、バイアスのコレクションです。人々は現状を好み、グループ思考が発展し、人々が自分の信念に固執するように議論が数回繰り広げられてきました。

ここで最も効果的な戦略の1つは、小さな勝利に集中することです。私は本の中で次の例を読みまし。著者は堅実な非Appleユーザーでした。彼女はそれらが好きではなかった、と彼女は彼らとは何の関係も望んでいませんでした。彼女は親アップルの姿勢を持つ人々と多くの議論を交わし、それぞれが彼女のかかとをより深く押し込んだ。それから誰かが彼女にiPod shuffleを買って、そのように、彼女の偏見は消えました。Apple製品だけを買いたくはなかったが、堅固で定着した反Appleの姿勢は、よりバランスのとれた視点に置き換えられた。妥協の余地があり、結局彼女はゆっくりと完全にアップルに転向することになりました。

したがって、全員を一度に説得しようとしないでください。逆の効果があります。一つの小さなことに集中すれば、残りは自然に起こります。人々が一度にすべてではなく、ビットごとに渡ることができるように、引数の両側の性質を取り除くだけです。

焦点を当てるべき特定のポイントは状況によって異なりますが、ここに1つのアイデアがあります。ライブラリと「実際のコード」の間でスケッチする区分は非常に不自然に思えます。私の見解では、アプリケーションを作成するプログラマーは、作成するアプリケーションの種類のライブラリーに時間の80%を費やし、そのライブラリーを使用してアプリケーションをビルドするのに20%を費やすべきです。保持する価値のあるすべてのコードは、ライブラリと見なされる必要があります。上司に、コードの一部を社内ライブラリに一般化することをお勧めします(まだ行っていない場合)。独自のロジックにより、このためにジェネリックを使用する必要があります。上記の見積もりでは、コードの80%がライブラリ内に収まる可能性があります。反対側からジェネリックを使用しているすべての人を取得したら、彼らはそれに慣れる必要があり、バイアスがフェードする必要があります。


ピーターのおかげで、非常に洞察に満ちた答えでした。あなたの考えは、私の質問だけでなく、日常生活の一般的な哲学にも当てはまります。
iammilind

2

「理解可能」に注意してください。コードレビュアーがジェネリックの利点を<<<>>>認識しない場合、すべての-stuffは不必要な理解できないノイズです。

ジェネリックを使用することで回避できたバグデータベースに含まれる実際の現在のバグ(未解決または最近修正されたバグ)を確認することをお勧めします。ClassCastExceptionsを探します。

また、ジェネリックを使用することで回避できたバグがない場合、同僚にはそれらを必要としないという点があることに注意してください。


2

これについては簡単に説明します。数年前にJava 1.4から1.6に移行しましたが、ジェネリックは本当に衝撃的でした。いくつかのコレクション、マップ、その他の構造をジャグリングしようとしている場合、それは簡単で非常に役立ちます。ただし、汎用データをパラメーターとして受け取り、それらを操作し、それらを他のクラスに渡すクラスを作成すると、すぐに混乱を招きます。すべてを機能させることで大きな満足を得ることができましたが、追加の時間と労力を費やすだけの価値はあったのでしょうか。また、かなりの数のJavaプログラマーが実際にそれを理解することは決してないかもしれません。

これまでの私の一般的な旅からのいくつかのランダムな考え:

  • ClassCastExceptionsは実行時に発生しますが、通常は最初の数回の実行で表示され、簡単に修正できます。
  • 私がジェネリックについて読んだすべての記事は、時には機能しないことがあり、@SuppressWarnings(value="unchecked")ときどき使用する必要があると述べています。ジェネリック医薬品の限界を超えているのか、それともただ愚かで、よりよく考える必要があるのか​​をどうやって知るのですか?
  • @SuppressWarnings(value="unchecked")1行だけに適用するのは難しい場合があります。
  • クラスの1つに派手なジェネリックを追加しました。私はクラスを一般化する前にクラスを強化できたプログラマーを何人か知っていました。

Genericsは私のコードをクリーンアップし、何度もトラブルを警告して拒否しましたが、開発時間の増加、トレーニングに余分な時間を費やし、JavaプログラマーがC#、C、およびVisual Basicでの作業を余儀なくされました。 ..またはJava 1.4。あなたの同僚が理解できるコードを書くことに焦点を当てます。わかりやすいジェネリックを入れることができたら、すばらしいです。Javaジェネリックは、まだ解明されていない機会/問題であると考えています。

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