web-dev-qa-db-ja.com

200K行のスパゲッティコードを継承しました。

これが一般的すぎる質問ではないことを願っています。私は本当にいくつかの熟練したアドバイスを使うことができました。

私は、過去10〜20年間、膨大なコードベースを一緒に作成しているかなり小さな科学者の店で、唯一の「SWエンジニア」として新しく採用されました。 (それは事実上時代遅れの言語で書かれました: G2 -Pascalとグラフィックスを考えてください)。プログラム自体は、複雑な化学処理プラントの物理モデルです。それを書いたチームは、信じられないほど深いドメイン知識を持っていますが、プログラミングの基礎に関する正式なトレーニングはほとんどまたはまったくありません。彼らは最近、存在しない構成管理の結果についていくつかの難しい教訓を学びました。また、コード自体に文書化されていない「スラッジ」が大量に蓄積されているため、保守作業も大幅に妨げられています。私はあなたに状況の「政治」を惜しみません(は常にあります政治!)と言っても十分です、何についての意見のコンセンサスはありません先の道に必要です。

彼らは私に、現代のソフトウェア開発の原則のいくつかをチームに提示し始めるように頼みました。彼らは私に、コーディング規約、ライフサイクル管理、高レベルの設計パターン、およびソース管理に関する業界標準のプラクティスと戦略のいくつかを紹介してほしいと思っています。率直に言って、これはかなり困難な作業であり、どこから始めればよいかわかりません。

最初は、 The Pragmatic Programmer の中心的な概念のいくつかでそれらを個別指導する傾向がありますまたはFowler's Refactoring ( "Code Smells"など)。また、アジャイル手法をいくつか紹介したいと思います。しかし、最終的には、効果的にするために、5〜7の基本的な基礎に焦点を当てる必要があると思います。言い換えれば、彼らが現実的に実装を開始できる最も重要な原則または実践は何であり、それは彼らに彼らに最も多くの「出費」を与えるでしょう。

それが私の質問です。あなたは、スパゲッティをまっすぐにするのに役立つ(そして将来それを防ぐ)のに最も効果的な戦略のリストに何を含めますか?

468
kmote

序文

これは確かに困難な作業であり、カバーするべき多くの根拠があります。したがって、適切なツールと教育資料へのポインタを含む、これをチームのやや包括的なガイドとして控えめに提案します。

覚えています:これらはガイドラインであり、状況に応じて採用、適応、または削除されることを意図しています。

注意:チームでこれらすべてを一度にダンプすると失敗する可能性が最も高くなります。汗に負けない最高の要素を選択し、1つずつゆっくりと導入してください。

注:これらすべてがG2のようなビジュアルプログラミングシステムに直接適用されるわけではありません。これらの対処方法の詳細については、末尾の補遺セクションを参照してください。


せっかちな人のためのエグゼクティブサマリー

  • 固定プロジェクト構造を次のように定義します:
    • プロジェクトテンプレート
    • コーディング規約
    • 使い慣れたビルドシステム
    • インフラストラクチャとツールの使用ガイドラインのセット。
  • 良い[〜#〜] scm [〜#〜]をインストールし、彼らがそれをどのように使うかを知っていることを確認してください。
  • 彼らに彼らの技術に適したIDEを示し、彼らがそれらの使い方を知っていることを確認してください。
  • ビルドシステムにコード品質チェッカーおよび自動レポートを実装します。
  • ビルドシステムを継続的インテグレーションおよび継続的検査システムに結合します。
  • 上記の助けを借りて、code quality "hotspots"およびrefactorを特定します。

さて、長いバージョンについて...注意してください。


剛性は(よく)良い

これは物議を醸す意見です。硬直はしばしばあなたに対して働く力と見なされます。これは、一部のプロジェクトの一部のフェーズに当てはまります。しかし、それを構造的なサポート、つまり、推測作業を排除するフレームワークと見なすと、無駄な時間と労力を大幅に削減できます。それはあなたに対してではなく、あなたのために働くようにします。

剛性=プロセス/手順

ソフトウェア開発には、化学プラントや工場がマニュアル、手順、ドリル、緊急ガイドラインを持っているのとまったく同じ理由で、適切なプロセスと手順が必要です。悪い結果の防止、予測可能性の向上、生産性の最大化...

剛性は適度ですが、!

プロジェクト構造の厳格さ

各プロジェクトに独自の構造が含まれている場合、あなた(および新規参入者)は失われ、プロジェクトを開くたびにゼロからピックアップする必要があります。専門のソフトウェアショップではこれを望んでおらず、ラボでもこれを望んでいません。

ビルドシステムの剛性

各プロジェクトが外観異なる場合は、それらも異なるビルドである可能性が高くなります。ビルドは、多くの研究や過度の推測を必要とするべきではありません。あなたは標準的なことをすることができて、詳細について心配する必要がないことを望みます:configure; make installantmvn installなど...

同じビルドシステムを再利用し、時間とともに進化させることで、一貫したレベルの品質も保証されます。

プロジェクトの詳細を示すための簡単なREADMEが必要であり、ユーザー/開発者/研究者がいる場合はそれを適切にガイドします。

これにより、ビルドインフラストラクチャの他の部分、つまり次のことも大幅に容易になります。

したがって、(プロジェクトのように)ビルドを最新の状態に保ちますが、時間の経過とともにビルドをより厳格にし、違反や不正行為の報告をより効率的にします。

ホイールを再発明せず、すでに実行したことを再利用しないでください。

推奨読書:

プログラミング言語の選択における剛性

特に研究環境では、すべてのチーム(さらにはすべての開発者にさえ)が同じ言語とテクノロジスタックを使用することは期待できません。ただし、「公式にサポートされている」ツールのセットを識別して、それらの使用を奨励することができます。残りは、適切な理論的根拠なしに、(プロトタイピングを除いて)許可されるべきではありません。

技術スタックをシンプルにし、必要なスキルのメンテナンスと幅を最小限に抑えます。それは強力なコアです。

コーディング規約とガイドラインの厳格さ

コーディング規約とガイドラインは、チームとしてのアイデンティティと共有の専門用語の両方を開発できるようにするものです。ソースファイルを開くたびにterra incognitaに誤りを犯したくありません。

1つの単純な違反に基づいてコミットが拒否される限り、人生を困難にする、または明示的にアクションを禁止する無意味なルールは負担になります。しかしながら:

  • よく考え抜かれた基本ルールセットは、多くの愚痴や思考を取り除きます:nobodyは、いかなる状況下でも破られるべきではありません。

  • 一連の推奨ルールは追加のガイダンスを提供します。

パーソナルアプローチ:コーディング規約に関しては積極的です。naziと言う人もいます。lingua franca私のチーム。がらくたコードがチェックインされると、ハリウッドスターの顔面のヘルペスのように目立ちます。レビューとアクションが自動的にトリガーされます。事実、私はときどき、不適合のコミットを拒否するためにコミット前フックの使用を主張することまで行ってきました。言及したように、それは過度に狂ってはならず、生産性の邪魔になってはいけません。それはそれを推進するはずです。これらをゆっくり、特に最初に紹介してください。しかし、本当の問題に取り組むことができないほどの欠陥のあるコードを修正するのに多くの時間を費やすよりもずっと望ましい方法です。

一部の言語では、これを設計で実施しています。

  • Javaは、Javaで書くことができる鈍いがらくたの量を減らすことを目的としていました(間違いなく、多くの人がなんとかやってのけています)。
  • インデントによるPythonのブロック構造は、この意味で別のアイデアです。

  • gofmtツールを使用して、スタイルに固有の議論と労力(and ego !!)を完全に取り除きます。コミットする前にgofmtを実行します。

code rotが抜けないことを確認してください。 コード規約継続的インテグレーションおよび継続的検査ペアプログラミングおよびコードレビューは、この悪魔に対する武器です。

さらに、以下に示すように、コードはドキュメントです。これは、規則が読みやすさと明確さを促進するもう1つの領域です。

ドキュメントの厳格さ

ドキュメントはコードと密接に関連しています。コード自体はドキュメントです。しかし、物事を構築、使用、維持する方法についての明確な指示がなければなりません。

ドキュメント(WikiWikiやDMSなど)の単一制御点を使用することは良いことです。プロジェクトのためのスペース、よりランダムなバンターと実験のためのスペースを作成します。すべてのスペースで共通の規則と規則を再利用します。チームスピリットの一部にするようにしてください。

コードとツールに適用されるアドバイスのほとんどは、ドキュメントにも適用されます。

コードコメントの剛性

上記のコードコメントもドキュメントです。開発者は、自分のコードについての気持ちを表現するのが好きです(私に尋ねると、ほとんどがプライドとフラストレーションです)。したがって、コメント(またはコード)で不明確な言葉でこれらを表現することは珍しいことではありません。楽しさと歴史的な理由から、いくつかを試してみても問題ありません。これは、チームカルチャーの開発の一部でもあります。しかし、許容できるものと許容できないものを誰もが知っていることが非常に重要であり、そのコメントノイズはnoiseです。

コミットログの剛性

コミットログは、SCMのライフサイクルの面倒で無意味な「ステップ」ではありません。時間どおりに帰宅したり、次のタスクに進んだり、昼食に出かけた仲間に追いついたりするために、ログをスキップしないでください。それらは重要であり、(ほとんどの)良いワインと同様に、時間が経過するほどそれらはより価値のあるものになります。ですから、正しく実行してください。同僚が巨大なコミットや自明ではないハックのためのワンライナーを書いているのを見たとき、私は驚きます。

コミットは何らかの理由で行われます。その理由は、コードと入力したコミットログの1行で常にISNが明確に表されているわけではありません。それだけではありません。

コードの各行にはストーリー履歴があります。差分はその歴史を語ることができますが、あなたはその物語を書かなければなりません。

なぜこの行を更新したのですか? ->インターフェースが変更されたため。

インターフェースが変更されたのはなぜですか? ->それを定義するライブラリL1が更新されたため。

ライブラリが更新されたのはなぜですか? ->機能Fに必要なライブラリL2は、ライブラリL1に依存していたためです。

そして、機能Xとは何ですか? -> Issue Trackerのタスク3456を参照してください。

これは私のSCMの選択ではないため、ラボにとっても最適ではないかもしれません。しかしGitはこれを正しく行い、short logslong logsを使用して、他のほとんどのSCMシステムよりも優れたログを書き込むように強制します。タスクID(はい、必要です)をリンクし、shortlogの一般的な要約を残して、長いログを展開します:変更セットのストーリーを書きます。

ログです:更新を追跡および記録するためにここにあります。

経験則:後でこの変更について何かを探していた場合、ログが質問に答える可能性はありますか?

プロジェクト、ドキュメンテーション、コードは生きています

それらを同期させてください。そうしないと、それらはその共生エンティティを形成しなくなります。あなたが持っているとき、それは不思議に働きます:

  • clearは、SCMのログをコミットします。課題トラッカーのタスクIDへのリンクがあります。
  • このトラッカーのチケット自体がSCMのチェンジセット(およびおそらくCIシステムのビルド)にリンクしている場所
  • そして、これらすべてにリンクするドキュメンテーションシステム。

コードとドキュメントはまとまりがある必要があります

テストの剛性

経験則:

  • 新しいコードには(少なくとも)単体テストが付属しています。
  • リファクタリングされたレガシーコードにはユニットテストが付属しています。

もちろん、これらは必要です:

  • 貴重なものを実際にテストする(またはそれらは時間とエネルギーの浪費です)、
  • よく書かれ、コメントされていること(チェックインする他のコードと同じように)。

これらもドキュメントであり、コードの契約の概要を説明するのに役立ちます。特に [〜#〜] tdd [〜#〜] を使用する場合。あなたがそうしなくても、あなたはあなたの心の平和のためにそれらを必要とします。これらは、新しいコード(メンテナンスまたは機能)を組み込むときの安全策であり、監視塔はコードの腐敗や環境障害から保護します。

もちろん、さらに進んで、修正する再現可能なバグごとに 統合テスト回帰テスト を用意する必要があります。

ツールの使用における剛性

時折開発者/科学者がソースで新しい静的チェッカーを試したり、別のものを使用してグラフやモデルを生成したり、DSLを使用して新しいモジュールを実装したりすることは問題ありません。ただし、allチームメンバーが知って使用することが期待される正規のツールセットがある場合に最適です。

それを超えて、メンバーがすべてである限り、メンバーが望むものを使用できるようにします。

  • 生産的
  • 定期的に支援を必要としない
  • 一般的なインフラストラクチャに定期的に適応しない
  • インフラストラクチャを混乱させない(コード、ビルドシステム、ドキュメントなどの一般的な領域を変更することにより...)、
  • 他人の仕事には影響しません
  • 要求されたタスクをタイムリーに実行できる

そうでない場合は、デフォルトにフォールバックするように強制します。


剛性vs汎用性、適応性、プロトタイピング、緊急性

柔軟性が良い場合があります。誰かが時々ハック、素早い、またはお気に入りのペットツールを使用して仕事を終わらせることを許可することは問題ありません。 [〜#〜]決して[〜#〜]それを習慣にし、[〜#〜]決して[〜#〜]このコードを実際のコードベースにして、サポートする。


チームスピリットマターズ

コードベースに誇りの感覚を養う

  • コードでプライドを育てる
    • ウォールボードを使う
      • 継続的インテグレーションゲームのリーダーボード
      • 問題管理と欠陥カウントのためのウォールボード
    • issue tracker / bug tracker を使用します

非難ゲームを避ける

  • 継続的インテグレーション/継続的インスペクションゲームを使用してください:礼儀正しく、 生産的な競争 を促進します。
  • 欠陥を追跡する:それはただのハウスキーピングです。
  • DO 根本原因を特定する:これは単なる将来を保証するプロセスです。
  • しかし、しないでください 非難を割り当て :それは逆効果です。

それは開発者ではなく、コードについてです

開発者にコードの品質を意識させますが、非難されることのない拡張ではなく、分離されたエンティティとしてコードを見るようにします。

それはパラドックスです:健康な職場では ego-less programming を奨励する必要がありますが、やる気を起こさせる目的でエゴに依存する必要があります。


科学者からプログラマーへ

コードを重視せず、誇りを持たない人々は、良いコードを生み出しません。この特性が出現するためには、彼らはそれがどれほど価値があり、楽しいかを発見する必要があります。純粋なプロ意識と良いことをしたいという願望だけでは十分ではありません。情熱が必要です。したがって、科学者をプログラマ(広い意味で)に変える必要があります。

誰かがコメントで主張したのは、プロジェクトとそのコードに10〜20年かかった後は、だれでも愛着を感じるだろうということです。たぶん私は間違っているかもしれませんが、彼らはコード自体やコードを書く行為ではなく、コードの結果と仕事とその遺産に誇りを持っていると思います。

経験から、ほとんどの研究者はコーディングを必要であると考えています。彼らはそれが機能することを望んでいます。すでにかなりの知識があり、プログラミングに興味がある人は、ベストプラクティスの採用とテクノロジーの切り替えを説得する方がはるかに簡単です。途中で入手する必要があります。


コードの保守は研究作業の一部です

だらしない研究論文を読む人はいません。だからこそ、彼らは査読、校正、改良、書き直し、そして出版の準備ができていると見なされるまで何度も何度も承認されます。同じことが論文にも当てはまりますand codebase!

コードベースの継続的なリファクタリングと更新により、コードの腐敗を防ぎ、技術的負債を減らし、他のプロジェクトでの作業の再利用と適応を容易にすることを明確にします。


なぜこれなの??!

上記のすべてに悩むのはなぜですか? code qualityの場合。それとも品質コード...ですか?

これらのガイドラインは、チームをこの目標に向けて推進することを目的としています。いくつかの側面では、単に方法を示してそれを実行させるだけです(これははるかに優れています)。また、他の側面では、それらを手で受け止めます(ただし、人々を教育し、習慣を身に付ける方法です)。

目標が手の届くところにあることをどのようにして知っていますか?

品質は測定可能です

必ずしも定量的ではありませんが、それはは測定可能です。先に述べたように、あなたはチームに誇りの感覚を養う必要があり、進歩と良い結果を示すことが鍵となります。コードの品質を定期的に測定し、間隔間の進捗状況とそれがどのように重要であるかを示します。過去にさかのぼって、何が行われたか、それがどのように状況を改善または悪化させたかを振り返ります。

継続検査には優れたツールがあります。 ソナー Java世界で人気のあるものですが、あらゆるテクノロジーに適応できます。他にもたくさんあります。コードを顕微鏡の下に置いて、これらを探してください厄介な迷惑なバグや微生物。


しかし、私のコードがすでにクラップである場合はどうなりますか?

上記のすべては、Never Landへの旅行のように楽しくてかわいいですが、すでに(高温多湿の)がらくたコードがあり、チームが変更に消極的である場合、それは簡単ではありません。

ここに秘密があります:どこかから始める必要があります

個人の逸話:プロジェクトでは、元々650,000+ Java LOC、200,000 +行のJSP、40,000 + JavaScript LOC、および400+ MBバイナリ依存関係。

約18か月後、500,000 Java LOC (MOSTLY CLEAN)、150,000行のJSP、および38,000 JavaScript LOCになり、依存関係はわずか100MBになります(これらはSCMでもう!).

どうやったの?上記のすべてをやった。または頑張った。

これはチームの努力ですが、製品の心拍数を監視するためのプロセス規制とツールをゆっくりと注入しながら、急いでスラッシングして「脂肪」を排除します:がらくたコード、役に立たない依存関係...これを行うためにすべての開発を停止したわけではありません。コードベースに夢中になって、それを切り離すことができる比較的穏やかな期間が時々ありますが、ほとんどの場合、デフォルトですべてを行います。ビルド中、ランチ中、バグ修正スプリント中、金曜日の午後など、あらゆる機会に「レビューとリファクタリング」モードに切り替えてください...

いくつかの大きな「成果」がありました... 8500以上のXML LOCの巨大なAntビルドからマルチモジュールのMavenビルドへのビルドシステムの切り替えは、その1つでした。次に、

  • 明確なモジュール(または少なくともそれはすでにはるかに優れていて、私たちはまだ将来のための大きな計画を持っています)、
  • 自動依存関係管理(メンテナンスと更新を容易にし、不要な依存関係を削除するため)
  • より速く、より簡単で、再現可能なビルド、
  • 品質に関する毎日のレポート。

もう1つは、依存関係を減らすことを試みていたにもかかわらず、「ユーティリティツールベルト」の注入でした。GoogleGuavaとApache Commonsはコードをスリム化し、yourコードのバグの表面を大幅に減らします。

また、新しいツール(JIRA、Fisheye、Crucible、Confluence、Jenkins)を使用する方が適切なツールよりも優れているとIT部門を説得しました。軽視したもの(QC、Sharepoint、SupportWorksなど)にも対処する必要がありましたが、全体的には改善され、余地がいくつか残っています。

そして、毎日、修正とリファクタリングのみを処理する1〜数十のコミットのトリクルがあります。私たちは時々物事を壊します(ユニットテストが必要で、それらを書くほうがよいですbefore物事をリファクタリングします)。一度にコード品質のパーセンテージの1分の1が得られます。 そして、それが増えるのを見るのは楽しいです!!!

注:繰り返しますが、新しくてより良いもののための余地を作るために、剛性を振る必要があります。私の逸話では、私たちのIT部門はsomeのことを私たちに課そうとすることは部分的に正しく、他の人には間違っています。または、多分それらはかつては正しいでした。状況は変わります。それらがあなたの生産性を高めるためのより良い方法であることを証明してください。 試運転とプロトタイプはここにあります。


極上の品質のための超秘密のインクリメンタルスパゲッティコードリファクタリングサイクル

       +-----------------+      +-----------------+
       |  A N A L Y Z E  +----->| I D E N T I F Y |
       +-----------------+      +---------+-------+
                ^                           |
                |                           v
       +--------+--------+      +-----------------+
       |    C L E A N    +<-----|      F I X      |
       +-----------------+      +-----------------+

Toolbeltにいくつかの高品質なツールが揃ったら、

  1. 分析コード品質チェッカーを使用したコード。

    リンター、スタティックアナライザーなど。

  2. 特定クリティカルホットスポットAND 低ぶら下げフルーツ

    違反には重大度レベルがあり、重大度の高いクラスが多数ある大きなクラスは大きな問題です。そのため、ビューのラジエーター/ヒートマップタイプでは「ホットスポット」として表示されます。

  3. 修正最初にホットスポット。

    ビジネス価値が最も高いため、短期間で効果を最大化できます。理想的には、重大な違反は、潜在的なセキュリティの脆弱性またはクラッシュの原因であり、法的責任を誘発するリスクが高いため(そしてあなたの場合、ラボのパフォーマンスが悪い場合)、発生したらすぐに対処する必要があります。

  4. クリーン自動コードベーススイープによる低レベル違反。

    それは信号対雑音比を改善するので、レーダーに重大な違反が現れたときにそれを見ることができます。多くの場合、最初は軽微な違反の大規模な集団が存在し、それらが対処されず、コードベースが自然のままに放置されていた場合です。それらは実際の「リスク」を示すものではありませんが、コードの可読性と保守性を損ないます。タスクの作業中に遭遇したときに修正するか、可能であれば自動コードスイープを使用した大規模なクエストクエストによって修正します。十分なテストスイートと統合システムがない場合は、大きな自動スイープに注意してください。煩わしさを最小限に抑えるために、適切なタイミングで同僚に同意してください。

  5. 満足するまで繰り返し

    これは、理想的には、これがまだアクティブな製品である場合、決してそうであってはなりません。進化し続けます。

良い家を保つための簡単なヒント

  • hotfix-modeの場合、カスタマーサポートリクエストに基づく:

    • 不本意に新しい問題を導入する可能性があるため、他の問題を修正することは、[〜#〜]しない[〜#〜]が通常はベストプラクティスです。
    • それに行くSEALスタイル:入り、バグを殺し、抜け出すして、パッチを出荷してください。それは外科的かつ戦術的なストライキです。
  • ただし、他のすべての場合、ファイルを開く場合は、次のことを義務付けます。

    • 間違いなく:レビューそれ(メモを取り、問題報告をファイルする)、
    • 多分:clean it(スタイルのクリーンアップと軽微な違反)、
    • 理想的には:refactor it(大きなセクションとその隣を再編成します)。

ファイル間で1週間を費やして、複数の機能やモジュールに及ぶ何千もの修正の大規模な変更セットになってしまうのを避けてください。将来の追跡が困難になります。コードの1つの問題=トラッカーの1つのチケット。時々、チェンジセットは複数のチケットに影響を与える可能性があります。しかし、それが頻繁に発生する場合は、おそらく何かが間違っています。


補遺:ビジュアルプログラミング環境の管理

特注のプログラミングシステムの壁に囲まれた庭園

OPのG2のような複数のプログラミングシステムは別の獣です...

  • ソース "コード"なし

    多くの場合、これらはソース「コード」のテキスト表現へのアクセスを提供しません。それは独自のバイナリ形式で格納されるか、またはテキスト形式で格納されても、それらをあなたから隠している可能性があります。特注のグラフィカルプログラミングシステムは、反復的なデータ処理ワークフローの自動化を簡素化するため、実際の研究室では珍しくありません。

  • 工具なし

    自分のものは別として、それは。あなたはしばしば彼らのプログラミング環境、彼ら自身のデバッガー、彼ら自身のインタープリター、彼ら自身のドキュメンテーションツールとフォーマットに制約されています。それらは壁に囲まれた庭園ですが、ライセンスが許可する場合、最終的にフォーマットをリバースエンジニアリングして外部ツールを構築するのに十分な動機を持つ誰かの関心を捕らえます。

  • ドキュメントの欠如

    多くの場合、これらはかなり閉じた環境で使用されるニッチなプログラミングシステムです。それらを使用する人々は頻繁にNDAに署名し、彼らが何をするかについて決して話しません。それらのプログラミングコミュニティはまれです。したがって、リソースは不足しています。あなたはあなたの公式リファレンスで立ち往生しています、そしてそれだけです。

皮肉な(そしてしばしば苛立たしい)ビットは、これらのシステムが行うすべてのことは明らかに主流および汎用のプログラミング言語を使用することによって、そしておそらくもっと効率的に達成することができるということです。しかし、それにはプログラミングについての深い知識が必要ですが、生物学者、化学者、または物理学者(数名を挙げれば)がプログラミングについて十分に知っていることは期待できず、実装(および維持)のための時間(および欲求)を持っていることさえ期待できません。複雑なシステム、それは長寿命かもしれないし、そうでないかもしれません。私たちがDSLを使用するのと同じ理由で、これらのオーダーメイドのプログラミングシステムがあります。

個人の逸話2:実際、私は自分でこれらの1つに取り組みました。私はOPのリクエストとはリンクしていませんでしたが、私のプロジェクトは、相互接続された一連のデータ処理およびデータストレージソフトウェアのセットでした(主に、バイオインフォマティクスの研究、ヘルスケア、化粧品、およびビジネス用)インテリジェンス、またはあらゆる種類の大量の研究データの追跡、およびデータ処理ワークフローとETLの準備を意味するドメイン。これらのアプリケーションの1つは、非常に単純に、通常のベルとホイッスルを使用したビジュアルIDE:ドラッグアンドドロップインターフェイス、バージョン管理されたプロジェクトワークスペース(メタデータストレージにテキストファイルとXMLファイルを使用)、異種データソースへのプラグイン可能なドライバー、およびNデータソースからのデータを処理して最終的にM変換出力を生成するパイプラインを設計するビジュアルキャンバス、および可能な光沢のある視覚化と複雑な(およびインタラクティブな)オンラインレポートです。ユーザーのニーズに合わせてシステムを設計するというふりをしたNIH症候群のビット。

そして、ご想像のとおり、それはニースシステムであり、ニーズに非常に柔軟ですが、「コマンドラインツールを使用しないのはなぜですか?」さまざまな「ベスト」プラクティスでそれを使用している多くのさまざまな人々に大規模なプロジェクトに取り組んでいるチーム。

すばらしい、私たちは運命にあります! -私たちはそれについて何をしますか?

結局のところ、上記のすべてがまだ成り立っています。このシステムからほとんどのプログラミングを抽出して、より多くの主流のツールや言語を使用することができない場合は、システムの制約にそれを適合させるだけでよいのです。

バージョン管理とストレージについて

最後に、最も制約された壁に囲まれた環境であっても、ほとんど常にバージョンのことができます。ほとんどの場合、これらのシステムにはまだ独自のバージョン管理が付属しています(残念ながら、これは基本的にかなり基本的なものであり、以前のスナップショットを保持するだけで、あまり可視性がなく、以前のバージョンに戻すことができます)。選択したSCMのように差分チェンジセットを正確に使用しているわけではなく、複数のユーザーが同時に変更を送信するのには適していません。

それでも、それらがそのような機能を提供する場合、おそらくあなたの解決策は上記の私たちの愛する業界標準のガイドラインに従い、それらをこのプログラミングシステムに置き換えることです。

ストレージシステムがデータベースの場合、おそらくエクスポート機能が公開されるか、ファイルシステムレベルでバックアップできます。カスタムバイナリ形式を使用している場合は、バイナリデータを適切にサポートしているVCSでバージョン管理を試してみてください。きめ細かく制御することはできませんが、少なくとも、大惨事に対してある程度の対策を講じることができ、ある程度のディザスタリカバリに準拠できます。

テストについて

プラットフォーム自体にテストを実装し、外部ツールとバックグラウンドジョブを使用して定期的なバックアップを設定します。おそらく、これらのテストは、このプログラミングシステムで開発されたプログラムを起動するのと同じように起動します。

確かに、それはハックジョブであり、「通常の」プログラミングに一般的なものの標準には絶対に達していませんが、アイデアは、専門的なソフトウェア開発プロセスの類似性を維持しようとしながらシステムに適応することです。

道は長くて険しい...

いつもニッチな環境と特注のプログラミングシステムの場合と同様に、上記で説明したように、奇妙なフォーマット、限られた(またはまったく存在しない)可能性のあるツールのセット、およびコミュニティの代わりに空を扱います。

推奨:上記のガイドラインは、可能な限りカスタムプログラミングシステムの外部で実装するようにしてください。これにより、適切なサポートとコミュニティ主導の「一般的な」ツールを信頼できるようになります。

回避策:これがオプションではない場合は、このグローバルフレームワークを「ボックス」に組み込んでみてください。アイデアは、この業界標準のベストプラクティスの青写真をプログラミングシステムの上に重ね、それを最大限に活用することです。アドバイスは引き続き適用されます。構造とベストプラクティスを定義し、準拠を奨励します。

残念ながら、これはあなたが飛び込み、途方もない量の脚の仕事をする必要があるかもしれないことを意味します。そう...

有名な最後の言葉、そして謙虚な要求:

  • ドキュメントすべてのこと。
  • シェアあなたの体験。
  • オープンソースあなたが書いたツール。

これをすべて行うことにより、次のことができます。

  • 同じような状況で人々からサポートを受けるチャンスを増やすだけでなく、
  • また、他の人に助けを提供し、テクノロジースタックに関する議論を促進します。

誰が知っているか、あなたはあいまいな言語Xの新しい活気に満ちたコミュニティの最初にいる可能性があります。ない場合は、開始してください。

  • Stack Overflow について質問する
  • Area 51 に新しいStackExchangeサイトの提案を書くこともできます。

多分それは内部で美しいかもしれません、しかし誰も手がかりを持っていないなので、この醜い壁を倒す他の人に覗き見させてください!

464
haylem

最初のステップは、バージョン管理システムの導入(SVN 、Git、Mercurial、TFSなど)。これは、リファクタリングを行うプロジェクトに必要です。

VSCに関する編集:-すべてのソース管理パッケージはバイナリを管理できますが、いくつかの制限があります。市場に出回っているほとんどのツールには、カスタムの差分ビューアーとエディターを使用する機能があります。この機能を使用してください。 バイナリソースファイルは、バージョン管理を使用しない言い訳にはなりません

レガシーコードで対処する方法について同様の投稿があります、それは従うのに良い参考になるかもしれません- レガシーコードでの作業に関するアドバイス

101
Yusubov

スパゲッティコードで作業する必要がある場合、最初に作業するのはmodularizationです。線を引き、コードベースの独立した部分を(多かれ少なかれ)抽出できる場所を見つけます。相互接続性と結合性が高いため、おそらくそれほど小さくはありませんが、探すといくつかのモジュール行が表示されます。

モジュールを作成したら、面倒なプログラム全体をクリーンアップするという困難な作業に直面することはもうありません。代わりに、クリーンアップするいくつかの小さな独立した乱雑なモジュールがあります。次に、モジュールを選択して、小規模で繰り返します。大きな関数を小さな関数またはクラス(G2がサポートしている場合)に抽出できる場所を見つけます。

言語が十分に強力な型システムを持っている場合、これはコンパイラーに多くの手間のかかる作業を行わせることができるので、すべてはるかに簡単です。 (意図的に)互換性を損なう場所に変更を加えてから、コンパイルを試みます。コンパイルエラーが発生すると、変更が必要な場所に直接移動し、エラーが発生しなくなったら、すべてが見つかります。 次に、プログラムを実行してすべてをテストします!リファクタリングを行う場合、継続的なテストが非常に重要です。

43
Mason Wheeler

これがあなたにとって選択肢であるかどうかはわかりませんが、私はそれらをプロの開発者を雇うに説得しようと試み始めます。このようにして、ドメインの問題に集中することができます(十分な量があるはずです)。

彼らはとても賢い人だと思いますが、良い開発者になるには多くの時間が必要です。彼らは主な業務ではない活動に多くの時間を費やす準備ができていますか?私見、これは最良の結果を達成する方法ではありません。

22
Gilney

ワオ。あなたはあなたの前に本当に大きな挑戦をしているように聞こえます!私は次の行に沿って何かをします:

  • まず第一に:Prioritize。最初に何を達成したいですか?プロジェクトの現在の状態で最も重要なものは何ですか?何を最大限に活用するか、そこに到達するまでの時間。
  • バージョン管理システムがあることを確認してください。 Git または Mercurial たとえば。
  • ある種の継続的インテグレーションシステム(例 Jenkins )を稼働させます。
  • バグ追跡システムを稼働させます。 Mantis は、私の意見ではかなりいいです。
  • 静的コード分析を調べます(現在使用している言語で何か利用できる場合)。
  • 変数の名前付けから一般的なコードの規則やコードベースのガイドラインまで、あらゆる一貫性を達成するようにしてください。
  • テスト中のシステムを取得します。これは、私の考えでは、このような大きなレガシーシステムにとって非常に重要です。 テストケースを使用して、既存の動作をドキュメント化します。動作が奇妙に感じられるかどうかは関係ありません(通常、コードがなぜ特定のように見えるのか、良いか悪いかには理由があります。または両方; P)。 マイケルフェザーがレガシーコードで効果的に機能する は、このための優れたリソースです。
20

彼らは、問題を解決する最初のステップは、あなたが問題を抱えていることを認めることだと言っています。これを念頭に置いて、まず、現在のコードベースである広大なもつれを示す依存関係グラフを生成することから始めます。 依存関係図を生成するのに適したツールですか? は数年前のものですが、このようなグラフの作成に役立つツールへのポインタが含まれています。私はポイントを家に帰すためにできるだけ多くを示す1つの大きくて醜いグラフを使います。相互依存が多すぎるために発生する可能性がある問題について話します Buckaroo Banzaiからの行

解剖学的構造を必要に応じて確認できます。正常な変動があったとしても、それが頭の内側にあると、すべて同じように見えます。いいえ、いいえ、いいえ、それを引っ張ってはいけません。あなたはそれが何に付けられるかもしれないか決して知りません。

そこから、混乱を矯正し始める計画を​​紹介します。コードを可能な限り自己完結型のモジュールに分割します。それを行う方法についての提案を受け入れるようにしてください-あなたが話している人々は、あなたが行うよりも、コードの歴史と機能をよりよく知っています。ただし、目標は1つの大きな問題を取り、それをいくつかの小さな問題に変えて、優先順位を付けてクリーンアップを開始できるようにすることです。

注目すべきいくつかのこと:

  • モジュール間にクリーンなインターフェースを作成し、それらを使い始めます。古いコードは、必要に応じて、しばらくの間これらのニースの新しいインターフェイスを使用しない可能性があります。これが解決し始めている問題です。ただし、今後は新しいインターフェースのみを使用することに同意してもらいます。必要なものがインターフェースにない場合は、インターフェースを修正し、回避しないでください。

  • 同じ機能が繰り返されているケースを探します。統一に向けて努力する。

  • これらの変更は人生をより簡単にするためのものであり、難しくはないことを時々思い出してください。移行は痛みを伴う可能性がありますが、それは良い目的のためであり、誰もが参加するほど、メリットは早くなります。

10
Caleb

Gensym G2 を少し調べたところ、この問題に取り組む方法は、次のようにコードベースの量に大きく依存しているように見えます。

enter image description here

またはこれ:

enter image description here

これと対比 99ボトルのビール

beer-bottles()

i:integer =99;
j:integer;
constant:integer =-1;

begin
for i=99 down to 1
    do
    j = (i+constant);
        if (i=1) then begin
            post"[i] bottle of beer on the wall";
            post" [i] bottle of beer";
            post" Take one down and pass it around ";
            post" No bottle of beer on the wall"; 
        end 
        else begin
            post"[i] bottles of beer on the wall";
            post" [i] bottles of beer";
            post" Take one down and pass it around ";
            if (i=2) then 
                post" [j] bottle of beer on the wall"
           else
                post" [j] bottles of beer on the wall"; 
           end
    end
end

後者の場合、事実上既知の量であるソースコードを使用しており、他のいくつかの回答は、それを処理するために非常に 賢明なアドバイス を提供しています。

ほとんどのコードベースが後者である場合、またはかなりの量のチャンクである場合でも、非常に特殊化されているためにリファクタリングできない可能性のあるコード、またはさらに悪いことに、次のような問題が発生します。それは取り外し可能かもしれませんが、適切に文書化されていない限り、そうではないように見える重要なコード( スクラム操作 の行に沿って何かを考える)を削除しているかどうかわかりません一見。

ElYusubov と指摘されているように、オンラインで何らかのバージョン管理を行うことが最優先事項であることは明らかですが、バージョン管理がサポートされているようです バージョン8.3以降 。 G2は2つの異なる言語方法論の組み合わせであるため、他のものを見つけて機能させるのではなく、G2で提供されるバージョン管理を使用するのが最も効果的であると思われるでしょう。

次に、リファクタリングを始めることを主張する人もいるでしょうが、私は、特にコードによって作成されたコードやビジュアルダイアグラムを扱う場合は、コードに触れ始める前に、使用しているシステムを完全に理解していることを確認することを強く主張しています。ソフトウェアエンジニアリング方法論の正式なトレーニング(またはバックグラウンド)を受けていない開発者。これにはいくつかの理由がありますが、最も明白な理由は、100人年以上の作業量が含まれる可能性のあるアプリケーションを使用していて、実際にそれが何を実行しているかを確認する必要があることです。そこにドキュメントがあります。システムがどの業界に展開されているかについては触れていませんが、G2について読んでいることからすると、生命の安全性にも影響を与える可能性があるミッションクリティカルなアプリケーションである可能性が高いと考えるのが安全です。 。したがって、それが何をしているかを正確に理解することは非常に重要です。文書化されていないコードがあり、チームの他のメンバーと協力して、コードが何をするかを人々が確実に判断できるように文書化されていることを確認します。

次に、できる限り多くのコードベースとビジュアルダイアグラムをユニットテストでラップします。 G2でこれを行う方法については、ある程度の無知を認めなければなりませんが、これを実現するために独自のテストフレームワークを作成する価値はほとんどありません。これは、チームの他のメンバーを紹介して、コードの品質に関連するより厳密なエンジニアリング手法のいくつかを利用してもらうための理想的な時間でもあります(つまり、すべてのコードにユニットテストとドキュメントが必要です)。

相当量のコードでユニットテストを実施したら、 haylem ;で提案されているような方法でリファクタリングに取り組み始めることができます。ただし、エキスパートシステムの開発を目的としたものを扱っており、それをリファクタリングするのは困難な作業になる可能性があることに注意してください。これは実際には、非常に一般的なコードを書くことではないと言われることがある環境です。

最後に、他のチームメンバーの発言に注意を払うようにしてください。コードとダイアグラムの品質が最高ではないからといって、必ずしもチームメンバーに反映されているとは限りません。結局のところ、当分の間、彼らはあなたよりもアプリケーションが何をするのかについてより多くを知っている可能性が高いので、あなたが座って、抜本的な変更を加える前にそれが何をするのかを理解することはより重要です。

9
rjzii

通常、前もって聞いた苦情は重要な問題とは関係ありません。結局のところ、すべてのソフトウェアプロジェクトでこれらの苦情を聞くことは完全に正常です。

コードを理解するのは難しいですか?小切手。大規模なコードベース?小切手。

本当の問題は人々が去ることであり、新しい人が組織に加わると、典型的な見当識障害があります。さらに、非現実的な期待とコード品質の問題があります。

これが私が取り組むことです、順番に:

  1. サーバーとローカルバージョンの両方のバックアップ
  2. バグトラッカーを設定する
  3. バージョン管理システムをセットアップする
  4. FAQ/Wikiを設定する
  5. すべての科学者/プログラマーの最初の報告会
    • 80/20ルールを思い出させます。バグの20%が問題の80%を担っています。
    • 最大の問題に焦点を当て、機能強化のリクエストなどはオフのままにします。
    • ここでの目的は、大きなリストで人々を怖がらせることではなく、達成可能な小さな勝利のリストです。結局のところ、あなたもあなたの価値を証明する必要があります。
  6. ビルドシステムを設定する
    • 信頼性の高いビルドを取得する作業を開始します(これにはしばらく時間がかかる場合があります)
    • すべてのプロジェクトを識別して名前を付ける
    • 循環依存関係を特定する
    • いくつかのオープンソースプロジェクトからのバイナリがある場合は、ソースを入手してください
  7. G2コードをモジュール化する方法を特定します。 API、サービス
  8. ドキュメント化されたG2コードのテスト方法を特定します。
  9. コードレビューシステムのセットアップ
  10. 2回目の報告
  11. 優れたプログラマーのクラックチームを特定し、彼らと協力してモジュールをラップします。
  12. コミュニケーションとドキュメントを改善するために、この段階ではコードレビューがあります。この段階では簡単にしてください。プロセスの問題を整理します。
  13. システムを他のプログラマーにロールアウトします。クラックチームのメンバーが残りのメンバーの仲間になることができます。ここではスケーリングが問題であることを覚えておいてください。あなたは実質的に管理職にいます。
9
Chui Tey

このような質問が Software Carpentry プロジェクトが存在する全体の理由です。

過去14年間、私たちは科学者とエンジニアに基本的なソフトウェア開発スキル(バージョン管理、テスト、コードのモジュール化方法など)を教えてきました。すべての資料はクリエイティブ・コモンズライセンスの下で無料で利用できます。また、私たちは毎年数十の無料の2日間のワークショップを開催して、人々が始めるのを支援しています。

これに基づいて、最良の出発点はおそらくRobert Glassの優れた(短い)本ソフトウェアエンジニアリングの事実と誤り:根拠に基づくアプローチ優れたプログラミング実践について私たちが彼らに伝えていることは単なる意見以上のものであることを科学者に納得させる良い方法です。
特定のプラクティスに関して、人々が最も積極的に採用する2つは、バージョン管理と単体テストです。それらが配置されると、Michael Feathersがレガシーコードで効果的に動作するで説明するような体系的なリファクタリングに取り組むことができます。
私はもはや推奨しませんThe Pragmatic Programmer(たくさんの勧め、初心者が実践するのは難しい)、そしてマックコンネルのコード完了は、最初は多すぎます(基本を習得したら、6か月または1年後に与えるのは素晴らしいことです) 。

Paul Duboisの優れた論文「科学プログラムの正確性の維持」Computing in Science&Engineering、May- 2005年6月)は、論理的かつ一貫した方法で12の異なるプラクティスを組み合わせた「多層防御」アプローチについて説明しています。

9
Greg Wilson

私はまずあなたがあなたの状況をクリアする必要があると思います。彼らはあなたに何を求めていますか?

  • これが行き止まりになっているため、古代言語の学習を望んでいる可能性は非常に低いです。G2を知っているか、G2を学習したい人を見つける機会が減り、そのため知識は折りたたまれたコードのヒープに埋もれます。現在の科学者たちは去るか、すべてのパッチを適用したコードはますます失敗します。
  • 科学者(またはその一部)は、新しい言語と多くのプログラミングパラダイムを学ぶ準備ができていますか?または、彼らはプログラミングと科学活動を長期的に分離し、必要に応じてさらにプログラマーを雇いたいのでしょうか?これは、専門知識の合理的で効率的な分離のようです。

ここでの核となる要件は「システムに知識を保存する」ことだと思うので、あなたはそれを発掘しなければなりません!

最初のタスクはドキュメントを書くことです。

これが新しいタスクであるかのように、しかし既存のシステムの助けを借りて、構造と要件を分析します。最初に教えるのではなく尋ねるので、彼らは喜ぶでしょう-そして、あなたはすぐに十分ですが、プログラマーの観点からより組織化された背景知識を得るでしょう:「ここで何が起こっているのですか?」ドキュメント(システムの静的な構造、ワークフロー、コンポーネント、問題)はすぐに価値があり、おそらくあなたよりも関連性の高い情報が表示されます(一部の人は "AHA!"を持っている可能性があり、すぐにいくつかのコードの修正を開始します) )...

次に、彼らはどこに行きたいのか尋ねる必要がありますか?

G2から離れる準備ができている場合、どのシステムを確認したいですか(プラットフォーム、言語、インターフェース、一般的な構造)?可能な場合はシステムの外部ラッパーの作成を開始し、ターゲット構造を保持しながら、元のコンポーネントは保持するため、このターゲット環境に新しいコンポーネントを実装できる一種のフレームワークをゆっくりと開始できます。コアサービス(永続的なデータ接続と「ツールキット」:コア計算、描画、...ライブラリ)を見つける必要があるため、新しいプラットフォームと言語で使い慣れた環境を提供し、ユーザーまたはユーザーのいずれかが移行できるようにします。それら:古いコードを1つずつ取得して、新しい環境で再実装(およびクリーン!)します。それが準備できたら、彼らは新しい言語を知っています。そして、サービスレイヤー(ほとんどの場合はご自身で作成)は、新しいコンポーネントをホストする準備ができています。

それらが動かない場合、あなたはG2を学び、そこにモジュラーフレームワークを作成し、そこにあなたまたは彼らがコンポーネントを移動する必要があります(クリーニング付き) 。とにかく、言語はデータとアルゴリズムツリーの単なるシリアル化です...

ドキュメントの分析と作成中に、GoFデザインパターンを読み取り、使用し、宣伝します! :-)

...私の2セント

7
Lorand Kedves

ロバートマーティンのSOLID同僚のための原則)に関する一連のプレゼンテーションを行ったところです。これらの原則がG2にどれほどうまく適用できるかはわかりませんが、5を探しているので-7の基本的な要素は、これらは最初から確立されたセットのようです。7に切り上げたい場合は、DRYで始めて、Fail-Fastを投入します。

4

「プログラム自体は複雑な化学処理プラントの物理モデルです...」

「G2はコードではなく、なんらかの恐ろしいGUIで記述された自動化コードなので...」– Erik Reppen

ソフトウェアの主な目標が、complex化学プラント、またはその一部をシミュレートする(おそらく最適化し、パラメータ推定を実行する)と仮定すると、その後、私はdかなり異なる提案を捨てたい:

高レベルの数学的モデリング言語を使用して、本質的な数学的モデルであるエッセンスを抽出することを検討することをお勧めしますout of手動でコード化されたソフトウェア。

モデリング言語が行うことは、問題の解決に使用されるアルゴリズムから問題の説明を切り離すことです。これらのアルゴリズムは一般に、特定のクラス(化学プロセスなど)のほとんどのシミュレーション/最適化に適用できます。その場合、それらを実際に再発明して社内で維持することはできません。

業界で広く使用されている3つの商用パッケージは、gPROMS、Aspen Custom Modeller、および(モデルに空間領域に沿って分布する現象が含まれていない場合)DymolaなどのModelicaベースのソフトウェアパッケージです。

これらのパッケージはすべて、何らかの方法で「拡張子」をサポートしているため、カスタムプログラミングを必要とするモデルの一部がある場合、それらはオブジェクト(.DLLなど)にカプセル化され、モデル。一方、モデルの大部分は簡潔なままで、科学者が直接読みやすい形式で記述されています。これは、会社の知識とIPを取得するためのはるかに優れた方法です。

これらのプログラムのほとんどは、外部から呼び出されることにより、モノリシックコードの小さな部分(サブモデル)を「小さなものから始めて」それらの形式に移植できるようにする必要もあります。これは、稼働中のシステムを維持し、一度に1つずつ検証するのに適した方法です。

完全な免責事項:私は、gPROMSの後ろの会社でソフトウェアエンジニアとして8年間働いていました。その頃、小さくて整頓されていて、いくつかの巧妙なソリューションまたはアルゴリズムを実装していたカスタムソフトウェア(例:アカデミアからのもの)の例を見ました(そして、時折組み込まれていました)。それをきれいに保つソフトウェアエンジニア。 (私は学際的なチームの大ファンです。)

したがって、ソフトウェアやソフトウェアの開発の早い段階で不十分な特定の重要な選択(言語やキーライブラリなど)は、長く付きまとう傾向があり、長い間痛みを引き起こす傾向があったと言えます。それらの周りのソフトウェア。ここでは、何年にもわたる純粋なコードクリーニングに直面しているように思えます。 (私は数値を使用するのをためらっていますが、G2からEclipse/Javaクイックスマートのような優れた自動リファクタリングツールをサポートするものにコードを移植できない場合は、おそらく10人以上の年を考えています。)

私のデフォルトのステータスは「リファクタリングして稼働中のシステムを維持する」ですが、問題が「大きすぎる」になると、全体的な変更/再書き込みがより速くなると思います。 (そして、より新しいテクノロジーにジャンプするなどの追加の利点をもたらす可能性があります。)新しいソフトウェアプラットフォームへの移植の経験があると私は言いますが、私が収集したものから、数学的モデリングパッケージへの移植でそれはさらに劇的です。

いくつかの視点を与えるために、あなたはサイズの縮小にかなり驚かれるかもしれません。例えば。 200,000 LoCは、実際には5,000行の方程式のようなもので表すことができます(OKだと思いますが、ここではビジネスの友人から実際の証言を得ることができます)。さらに、Cのようなもので記述されたいくつかの比較的小さな関数モジュール(たとえば、物理特性の計算-化学プロセスによっては、既成のパッケージが存在する場合もあります)。これは、文字通りアルゴリズム解のコードを捨てて、数学ソルバーの汎用「スタック」にハードワークを任せるためです。シミュレーションを実行すると、コード行を変更することなく、プロセスの最適化など、シミュレーションをさらに実行できます。

最後に私は言います:さまざまな数学モデル(およびアルゴリズム)の唯一の信頼できるドキュメンテーションがコード自体である場合、科学者や原作者の助けを借りて、これらのモデルをできるだけ早く抽出してください。それらのいくつかは先に進んだ可能性があります。彼らは、数学的モデリング言語がそれらのモデルをキャプチャする非常に自然な方法であることを発見するはずです-彼らはそれを(衝撃的な)ホラーで書いても(再)楽しむかもしれません。


最後に、私の答えが適切ではない可能性があるため、ここですでに参照されている優れた本のリストに、もう1冊の本を追加したいと思います。RobertMartinによるClean Codeです。簡単に習得して適用できるシンプルな(そして正当化された)ヒントが満載ですが、会社で新しいコードを開発している人々に世界を変える可能性があります。

3
Luke Usherwood

唯一の運用上の問題は、変更管理の問題のように聞こえます。それが事実であり、ソフトウェアがそれ以外の目的でそれを実行する場合、私が与える最初のアドバイスは、あまりにも早く実行したいという衝動に抵抗することです。

ソース管理、リファクタリング、より訓練された開発者はすべて良い提案ですが、これが初めてこの種の問題に対処しなければならず、制御された変更を加えることは十分に強調することができません。

混乱を一掃する衝動は時々素晴らしいでしょうが、十分にリバースエンジニアリングして、代替バージョンを適切にテストできることがわかるまでは、非常に注意する必要があります。

3
Bill

このような状況で作業するための最も重要な原則は次のとおりです。

  1. 我慢して。ディグに20年を要した穴は、数週間で埋められることはありません。

  2. ポジティブになれ。文句を言うと不平を言う誘惑に抵抗します。

  3. 実用的である。今日、あなたが1日で達成できる前向きな変化を見て、それを実行してください。まだバージョン管理システムを持っていますか?それを実装し、人々を訓練してください。次に、テスト(ユニットテストなど)を自動化できるかどうかを確認します。リンス。繰り返す。

  4. モデルになります。アジャイルになることでアジャイルがどのように機能するかを人々に示します(ただ教えないでください)。上記の最初の3つのポイントは、効果的なアジャイル男になる前身であるグッドガイになるための鍵です。私の意見では、立派な開発者である人々はスマートであるだけでなく、優秀で、従業員や同僚のモデルでもあります。

  5. 自分の領土をマッピングします。私は巨大なレガシーコードベースをマッピングする技術を持っています。リポジトリのクローンを作成し、作業用コピーを作成してから、何かを変更して、他に何が壊れるかを確認します。結合を調査し(グローバルな状態、壊れたAPI、または一貫したAPIの欠如、またはプログラムに対する抽象化またはインターフェースの欠如)、物事を変更したときに壊れるコードを読むことによって、私は不備を発見し、チームの他のメンバーからの洞察(5年前にBoss Xが要求していたので、これは機能しませんでした!)時間が経つにつれて、領土の精神的な地図を取得します。大きさがわかったら、地図を作成して家に帰るのに十分な知識が身につきます。巨大なコードベースの領域をマッピングし、チームの技術的知識を構築するように他の人を励ましてください。 「ドキュメント」は俊敏ではないため、一部の人々はそれをためらっています。なんでも。私も科学的環境で働いています。ドキュメントは私にとって王様です。アジャイルマニフェストはのろわれます。

  6. 小さなアプリを作成します。レガシーコードベースで作業しているとき、私は根っからのことに気づきました。小さなヘルパーアプリを作成することで、精神を取り戻します。たぶんそれらのアプリは、巨大なG2コードベースを読んで理解し、修正するのに役立つでしょう。多分あなたはあなたの環境で働くのを助けるミニIDEまたはパーサーツールを作ることができます。メタプログラミングとツール構築があなたが巨人から抜け出すのを助けるだけではない多くの場合がありますレガシーコードベースがあなたに課しているデッドロック、それらはまたあなたの脳にあなたのG2言語によって制限されずに飛ぶ能力を与えます。あなたにとって最も速くそして最も得意などんな言語であなたのツールとヘルパーを書いてください。私にとって、それらの言語はPythonとDelphiを含みます。Perlを使用している場合、または実際にC++またはC#でのプログラミングが好きな場合は、その言語でヘルパーツールを記述します。チームの残りのメンバーに、小さなヘルパーアプリとツール、および「コンポーネント」を構築するように教えると、結局のところ、レガシーコードベースがそれほど難しくないことがわかります。

3
Warren P
  1. 改訂管理:ドメインの専門家に、元に戻したり、誰が何を変更したかを確認したりできるという利点を示します(これは、すべてバイナリファイルの場合はより困難ですが、コンテンツが実際にコードである場合、確かに差分を有効にできる、ある種のG2からテキストへのコンバーター。)

  2. 継続的インテグレーションとテスト:エンドツーエンドテストの作成に関与するドメインエキスパートを取得します(どこかにすでに入力と期待される出力があるはずなので、より簡単です)と小さなユニットテスト(スパゲッティコードがおそらくより難しいため、より困難です)ほぼすべての機能と使用例をカバーする多数のグローバル変数が含まれます。

  3. 共通コードをリファクタリング再利用可能なルーチンとコンポーネントに。リビジョン管理のないソフトウェアを使用していない人は、ルーチンを作成するために一度に数百行をコピーアンドペーストするでしょう。それらを見つけてリファクタリングし、すべてのテストに合格し、コードが短くなったことを示します。これは、そのアーキテクチャを学ぶのにも役立ちます。難しいアーキテクチャの決定を始める必要があるときまでに運が良ければ、100KLOCまで下がることがあります。

政治的に、このプロセスで古いタイマーからの抵抗を見つけた場合は、コンサルタントを雇って、優れたソフトウェア方法論について話してください。ドメインの専門家が同意しなくても、意見に同意する良い意見を見つけて、経営陣にコンサルタントの必要性を売り出してもらいます。 (彼らは同意する必要があります-結局、彼らはあなたを雇ったので、明らかに彼らはソフトウェアエンジニアリングの専門知識が必要であることを理解しています。)これはもちろんお金を無駄にするトリックですが、その理由は、あなた-新しいホットショットヤングプログラマ-が彼らは何かをする必要がある彼らはそれを無視するかもしれません。しかし、経営陣がコンサルタントに5000ドルを支払い、必要なことを彼らに伝えれば、彼らはそれにもっと信頼を置くでしょう。 ボーナスポイント:コンサルタントに、実際に必要な変更の2倍の変更をアドバイスしてもらうと、「良い人」になり、ドメインの専門家と協力することができます、コンサルタントが提案した量の半分しか変更しないと妥協しています。

3
Conrad Poelman

最初に分析を行います。

何を教えるかを決める前に、少し分析をします。最大の問題点はどこにあるかを把握します。それらを使用して、どのプラクティスを優先するかを優先させます。

一度にいくつかの変更のみを導入します(同様の状況で、私は2週間ごとに2〜3回実践しました)

SDLCのプログラミングスタイルへの変更のレベルに応じて、プラクティスを3に制限します。彼らが慣れ始めるまで(新しいアプローチを学ぶという考え方に慣れてきたら、1〜2週間ごとに1つの新しい変更を導入するようにプッシュします)。また、成功の基準を特定することもお勧めします。練習で達成すべきこと(チームの士気のようなソフトな目標であっても)。そうすることで、効果があるかどうかを示すことができます。

  • 変更の数を制限する理由

これらの人々がより優れたプログラマーになりたいと思っていて、学習に進んでいると仮定しても、人々が新しい概念をどれだけ速く、どれだけ速く学習して適用できるかには限界があります。特に、CSの基盤がない場合、または以前にソフトウェア開発ライフサイクルに参加したことがある場合。

毎週のラップアップミーティングを追加して、プラクティスがどのように影響したかを話し合います。

会議は、何がうまくいったか、何が必要かを話し合うために使用されるべきです。彼らが発言権を持ち、共同作業できるようにします。話し合って、彼らが抱えている問題に対処し、次の変更をプレビューする計画を立てます。プラクティスとそのアプリケーションに焦点を当てたミーティングを維持します。彼らが実践を適用することから彼らが見始めるはずの利点について少し伝道してください。

特定のプラクティスが優先されます。

バージョン管理システム(IMO)の適切な使用は、他のすべてに勝ります。すぐ後ろには、モジュール化、結合/結合、機能/バグチケット追跡のレッスンがあります。

機能しないプラクティスを削除します。

うまくいかない習慣を取り除くことを恐れないでください。コストが高く、利益がほとんどないか、まったくない場合は、プラクティスを削除します。

改善はプロセスです。

持続的で一貫した改善がプロセスであることを伝えます。最大の問題点を特定し、解決策を適用し、待機/指導してから繰り返します。勢いを増すまで、最初は苦痛に感じるでしょう。今後の改善とすでに成功している改善に全員が集中するようにしてください。

2
dietbuddha

私は以下を捨てるでしょう:

  1. ここにはプログラマーが一人います。政治をねじ込みます。彼らは彼らの貿易を知っています。あなたはあなたのものを知っています。あなたがそれに腹を立てる必要がある場合でも、その領域をマークします。彼らは科学者です。彼らはそのようなことを尊重することができます。どんな手段でも、今すぐ境界をマークしてください。これを修正します。これは私には責任がありません。

  2. 科学者はアルゴリズムを作成/テストします。独自のアルゴリズムを1〜3言語で記述したい科学者は、コアコードに変換することについて誰もが同意することができます。それはそれらの上で彼らのものをテストすることになります。それを超えて、彼らはあなたが重要な科学的なものと、彼らが建築のために何をしたのかという神の知識を分離する手助けをしなければならないでしょう。コードベースはホースです。やらなければいけないことはたくさんあります。彼らにあなたが最もよく知っていることを採用しているものの作業バージョンを手渡すためのオプションを与えて、あなたがあなたが最も得意とすることをできるようにします。彼らが責任を負うが、あなたが協力できるボックスに彼らの知識を詰め込みなさい。理想的には、メガリファクタリングの会話がうまくいくとき、グローバル変数X19a91に腹を立てたときにdrBobsFuncStructObjThingMk2_0109の触手Z9が何をしたかよりも、インターフェイスでどのようなエキサイティングなことを実行できるかが重要になります。

  3. 可能であれば、ファーストクラスの機能を備えたイベント駆動型の言語を使用してください。他のすべてが失敗した場合、イベントをトリガーするか、または実際に意味のあるインターフェースと状態のメカニズムを使用して、オブジェクトへのコールバックを投げることは、流血の意味を持たず、おそらくまったく意味のないコードを深く理解している場合、時間を大幅に節約できます。意志。科学者たちはPythonが好きなようです。下位レベルの演算集中型のCのものを接着するのは難しくありません。言ってるだけ'

  4. この問題または同様の問題を解決した人を探してください。調査に真剣に時間をかけましょう。これらの人たちは誰かからG2について聞いた。

  5. デザインパターン。アダプター。 'emを使用します。このような状況では、たくさん使用してください。

  6. 科学でできることを学びましょう。あなたが知っているほど、コードの意図をよりよく判断できます。

2
Erik Reppen

何度も述べたように、ソースコード管理はステップ1です。あなたと一緒に働く人々はプロの開発者ではないかもしれません、そして彼らは多くのエンタープライズまたはアジャイルな巨大なジャンボに対応しません。それらも低レベルのコードモンキーではありません。「あなたのやり方」を実行するように強制することでそれらをそのように処理しようとすることは飛ばないでしょう。

あなたはそこに何を調査する必要があります。ソースコード管理を使用していない場合は、コードの適切なバージョン(可能な場合)を特定するだけで、考えられるすべての成果物を特定するには長い時間がかかります。次に、ソースコード管理の使用方法を同僚に教え、彼らに時間をかける価値があることを説得するというタスクを実行します。メリットから始めましょう!

あなたがそれをしている間に、他のぶら下がり果物を見つけて、それらの問題を修正してください。

何よりも、彼らが言わなければならないことに耳を傾け、彼らの状況の改善に取り組む。彼らが何をしているかにあなたの切手を貼ろうとすることについて心配しないでください。

幸運を!

0
Bill

あなたが持っている最初のステップのように聞こえるのは、新しいソフトウェアの方法論に投資する必要性をチームに売り込むことです。あなたの声明によると、チームにはコンセンサスがありません。コードの「アップグレード」をゆっくりと進めていくには、それが必要です。

私は(できれば)個人的に学んだ難しい教訓を取り入れて、ソフトウェア業界の問題の解決策としてしたい主要な概念をそれぞれ紹介します。

例えば。 2人の開発者が異なるコピーを持っていて、テストされていないハイブリッドリリースをデプロイすることになりました->バージョン管理、分岐、およびテストの導入。

誰かが理解できない数行のコードを削除して機能停止を引き起こした-> DDDを導入した。

ハードレッスンが十分に詳細に共有されていない場合は、この規律が守られなかったときに問題が発生した方法の例を示してください。

0
M Afifi