問題タブ [god-object]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
debugging - 神物の扱い
私は中規模のチームで働いており、これらの非常に大きなクラス ファイルに定期的に遭遇します。私の最初の傾向はナイフで彼らに向かうことですが、それは通常、事態を悪化させ、私を悪い精神状態に陥らせます.
たとえば、作業する Windows サービスが与えられたとします。現在、このサービスにはバグがあり、それを修正する望みを持つ前に、サービスが何をするかを理解する必要があります. サービスを開くと、誰かがすべてに 1 つのファイルを使用することにしたことがわかります。そこには Start メソッド、Stop メソッド、タイマー、すべての処理と機能があります。私は何千行ものコードについて話しています。コードが 100 行未満のメソッドはまれです。
クラス全体を書き直すことができず、これらの神のクラスがポップアップし続けると仮定すると、それらに対処する最良の方法は何ですか? どこから始めますか?最初に何を達成しようとしますか?この種のことにどのように対処し、すべてをスタビーにしたいだけではありませんか。
気性を抑えるための戦略があれば、それも大歓迎です。
ここまでのヒント:
- テスト範囲を確立する
- コードの折りたたみ
- 既存手法の再編成
- 発見された動作を文書化する
- 漸進的な改善を目指す
編集:
Charles Conway は、非常に役立つことが判明したポッドキャストを推奨しています。リンク
Michael Feathers (ポッドキャストの男) は、単純にプロジェクトをソース管理から外して直接操作し、変更を破棄することはあまりにも恐れられているという前提から始めました。私はこれについて有罪であると言えます。
彼は本質的に、あなたがもっと知りたいと思うアイテムを手に取り、それをバラバラにし始めると言った. 依存関係を発見し、それらを壊します。どこまでもそれに従ってください。
大きなヒント 他の場所で使用されている大規模なクラスを使用して、空のインターフェイスを実装します。次に、クラスを使用してコードを取得し、代わりにインターフェイスをインスタンス化します。これにより、コード内のその大きなクラスへのすべての依存関係の完全なリストが得られます。
asp.net-mvc - 神のコントローラー-それらを防ぐ方法は?
私が取り組んできたいくつかのMVCプロジェクトでは、神のクラスに有機的に成長した問題のあるコントローラーがいくつかあることが明らかになりました。
この質問は「何がどこに行くのか」という問題かもしれませんが、SRP(単一責任原則)、DRY(Do n't Repeat Yourself)、および物事を簡潔に「アジャイル」に保つことに関して重要な質問だと思います。そして、私はこれについて精通するのに十分な経験がありません(このパターンと一般的な設計で)。
1つのプロジェクトには、NutritionControllerがあります。時間の経過とともに、これらのアクション(多くはそれぞれのGET、POST、およびDELETEメソッドを含む)を含むようになりました。
次に、ExerciseControllerがあります。これには、検索やお気に入りのアクションなど、多くの同様のアクションが含まれます。これらを独自のコントローラーにリファクタリングして、そのようなものにする必要がありますか?
それらを別々のコントローラーに分割すると、必要な情報を処理するために、あるレベルで信じられないほど大きな依存関係が大きくなるように思われます。または、(M、V、またはCレベルのいずれかで)目的の効果を得るには非常に多くのフープをジャンプする必要があるため、処理が非常に難しい完全に汎用的な処理アプリケーションを使用することになります。
私はこれを間違った方法で考えていますか?たとえば、一般的なお気に入りオブジェクトを作成してから、それをスローするビューをコントローラーに決定させる必要がありますか?
*頭字語を綴って申し訳ありません-他の誰かがこの質問に出くわし、それらが何であるかについて無知な場合に備えて、私はそうしています
編集: 私が実行するすべてのロジックは、ほとんどサービスレイヤーで処理されます。たとえば、コントローラーは「新しい」FoodItemをサービスに送信します。すでに存在する場合、またはエラーがある場合、サービスはそれをコントローラーにバブルバックします。
design-patterns - 不要なシングルトンと神のオブジェクトのどちらが悪いですか?
状況は次のとおりです。やりすぎているクラスがあります。主に構成情報にアクセスするためのものですが、データベース接続もあります。これはシングルトンとして実装されているため、ほとんどのコードが非常に緊密に結合されているため、単体テストも困難になります。これは、インポート時の依存関係を作成するため (Python でこれを行っています)、さらに問題が大きくなります。これは、特定のモジュールを特定の順序でインポートする必要があることを意味します。理想的には、これを 2 つのクラスに分割し、非シングルトンにしたいと考えています。
幸いなことに、私の雇用主は、この種のテストが優れているという事実を受け入れており、コードがよりテストしやすくなるのであれば、このような変更を喜んで許可してくれます。しかし、私がそれに多くの時間を費やすことを彼らが喜んで許してくれるかどうかは疑わしい. そして、過激になりすぎるのではなく、これを段階的に修正したいと思います。
したがって、ここには 3 つの選択肢があります。
- 構成オブジェクトを (シングルトン) 構成オブジェクトと (非シングルトン) データベース オブジェクトに分割します。これにより、少なくともインポート時の依存関係としてデータベースを削除できます。
- 構成オブジェクトを非シングルトンにして、それを必要とするオブジェクトに渡します。これは私たちの短期的なニーズによりよく対応していると思いますが、それにはかなり時間がかかると思います.
- あなたがあなたの答えで提案することを私が考えていなかった何かをしてください。:-)
それで、私は何をしますか?
.net - IObservable / IObserverを利用して、「神オブジェクト」を取り除くにはどうすればよいですか?
私が現在取り組んでいるシステムには、インターフェースと基本クラスとして定義されている多くのコンポーネントがあります。システムの各部分には、システムの他の部分と相互作用する特定のポイントがいくつかあります。
たとえば、データ準備コンポーネントは、最終的にデータ処理部分に移動する必要がある一部のデータを準備します。通信コンポーネントは、外部に中継するために、さまざまなコンポーネントのステータスを照会する必要があります。
現在、私は「神オブジェクト」、またはシステムのさまざまな部分についての深い知識を持つオブジェクトを使用して、システムのこれらの部分を接着します。ここでイベントに登録し、結果をあちらのメソッドにシャトルし、ここでコールバックメソッドを作成して、あちらでそのメソッドの結果を返します。特定のアクションがSTAスレッドなどで実行します。
便利ですが、この1つのタイプは、システム内の他のすべての人がどのように設計されているかについて多くのことを知っているのではないかと心配しています。イベント、メソッド、またはコールバックを公開できるインスタンス、またはこれらを消費できるインスタンスを指定できる、より汎用的なハブの方がはるかに望ましいです。
私はリアクティブフレームワークのIObservable/IObserver機能についてもっと見てきましたが、それは.NET 4.0に組み込まれています(私は信じています)。
このパターンを利用して、「神オブジェクト」を置き換えることはできますか?どうすればこれを行うことができますか?この特定の目的のためにこのパターンを使用するためのリソースはありますか?
c# - 「神オブジェクト」にならないようにクラスを設計する
グラフィックにいくつかの関数を描画できるアプリケーションを設計しています。各関数は、このグラフィッククラスに渡す一連のポイントから描画されます。
ポイントにはさまざまな種類があり、すべてMyPointクラスから継承されます。ある種のポイントについては、そのまま画面に印刷するだけで、他のポイントは無視でき、他のポイントは追加されるため、複雑になる可能性のあるロジックが関連付けられています。
ここでは、実際にグラフィックを描画する方法は主要な問題ではありません。気になるのは、このGraphicMakerクラスがいわゆる神オブジェクトにならないようにコードロジックを作成する方法です。
次のようなものを作成するのは簡単です。
このようなことをどのように行いますか?正しい方法は、各Pointオブジェクトに描画ロジックを配置することだと思います(したがって、Pointの各子クラスはそれ自体を描画する方法を知っています)が、2つの問題が発生します。
- 自分自身を描画する方法を知るために、GraphicObjectクラスに存在する他のすべてのポイントを知る必要がある種類のポイントがあります。
- グラフィッククラスから多くのメソッド/プロパティを公開できるので、すべてのポイントがグラフィッククラスへの参照を持ち、必要に応じてすべてのロジックを作成できますが、それほど大きな代償はありません。神のクラスを持ちたいですか?
c# - MVVM とモノリシックな神オブジェクトの回避
私は、画像取得、画像処理、データ ストレージ、工場 I/O (自動化プロジェクト) など、いくつかの大きなコンポーネントを含む大規模なプロジェクトの完了段階にあります。
これらの各コンポーネントは適度に独立していますが、プロジェクト全体を実行するには、各コンポーネントのインスタンスが少なくとも 1 つ必要です。各コンポーネントには、ステータスを監視して物事を変更するための ViewModel と View (WPF) もあります。
私の質問は、これらすべてのオブジェクトをインスタンス化し、あるクラスを別のクラスの Event にサブスクライブし、これらすべてに共通の ViewModel と View を持つ最も安全で、最も効率的で、最も保守しやすい方法です。
これらすべてのオブジェクトのプライベート インスタンスを持つ God という名前のクラスがあれば最適でしょうか? 過去にやって後悔したことがあります。
それとも、神がこれらのオブジェクトの Singleton インスタンスに依存してボールを転がすことができた方がよいでしょうか。
または、Program.cs (または Main(...) がある場所) でこれらすべてのコンポーネントをインスタンス化し、それらをパラメーターとして神に渡し、神 (笑) と神の ViewModel にこのプロジェクトの実行の詳細を処理させる必要があります。
私が聞きたい他の提案。
ありがとうございました!
java - 神オブジェクトにせずにコントローラーを作成するにはどうすればよいですか?
私のアプリにはController
、mainメソッドで開始されたものがあります。コントローラは、フック、データベース接続、UI、別の接続などを初期化します。プログラムの状態のほとんどを保持します(いいえ、シングルトンではありません)。別の例では、コマンドの解釈と送信を処理するボット用のコントローラーがあります。どちらもかなり大きなファイルです。
私は神のオブジェクトについて読みましたが、それを分割する方法を本当に知りません。ボットでインタープリターとディスパッチャーを分割すると、恐ろしいコールチェーンが作成されます(のようなものgetBot().getParser().getOutput().sendMessage(recipient, message)
)。同様に、最初のコントローラーでは、物事を分割すると、フィールドといくつかのエイリアスユーティリティメソッドを保持するDataオブジェクトが作成されます。それらを分割すると、事態はさらに悪化します。そして、あなたがその維持不可能であると考える前に、それは実際にはそうではありません。ボットコントローラーも作成していませんが、何が起こっているのかはわかっています。
ただし、問題は、Botクラスの長さが2000行(Javadocコメントを削除した場合はおそらく短い)であり、Botの長さが約1000行であるということです。たくさんの線=神オブジェクト。しかし、プロジェクトの1つまたは2つのコアクラスで問題ありませんか?
php - 14 個の静的メソッドと 4 個の静的プロパティを持つクラスがありますが、これは悪いことですか?
私はちょうど 450 行の長さの PHP クラスを作成しており、14 の静的メソッドと 4 つの静的プロパティ、および 6 つの定数 (およびプライベート__construct()
と__clone()
) が含まれています。
ここで私は何か間違ったことをしているのだろうか、私のクラスは悪なのでしょうか?
クラスを使用するときは、常に次のような単一のメソッドを呼び出します。
そして、それを完全に放っておくので、それを構築可能にするのはばかげていると感じますか?
直接呼び出すことができるいくつかのメソッドを含むツールに似ているため、そこからオブジェクトを構築することにはあまり意味がありません。
実際には、これらの 14 個のメソッドのうち、7 個はパブリックであり、残りはクラスが使用するためのプライベートです。
oop - 複数のクラスを管理するクラスは「神のオブジェクト」ですか?
God Objects に関するウィキペディアのエントリを読むと、クラスがあまりにも多くのことを知っているか、あまりにも多くのことを行うと、クラスは神のオブジェクトであると書かれています。
この背後にあるロジックはわかりますが、それが本当なら、どのようにしてすべての異なるクラスを結合しますか? ウィンドウ管理やDB接続などの接続にいつもマスタークラスを使っていませんか?