タグ付けされた質問 「object-oriented-design」

オブジェクト指向設計とは、ソフトウェアの問題を解決するために、相互作用するオブジェクトのシステムを計画するプロセスです。

1
継承と合成ではなく、いつ特性を使用するのですか?
OOPに関して再利用性を実装するには、AFAIKの3つの一般的な方法があります。 継承:通常はis-a関係(アヒルis-a鳥)を表す 構成:通常、関係があることを表す(車はエンジンがある) 特性(例:PHPの特性キーワード):...これについて本当にわからない トレイトはhas-aとis-aの両方の関係を実装できるように思えますが、どのようなモデリングが意図されていたのかはよくわかりません。どのような状況のために特性が設計されましたか?

4
ビジネスオブジェクトクラス設計のこの「完全にパブリック」な考え方に反対する方法
私たちは多くのユニットテストとビジネスオブジェクトのリファクタリングを行っており、クラスの設計について他のピアとは非常に異なる意見を持っているようです。 私がファンではないクラスの例: public class Foo { private string field1; private string field2; private string field3; private string field4; private string field5; public Foo() { } public Foo(string in1, string in2) { field1 = in1; field2 = in2; } public Foo(string in1, string in2, string in3, string in4) { field1 = …

2
データ指向インターフェースへのプログラミング
次のスタイルで記述されたコードベースの一部があります。 // IScheduledTask.cs public interface IScheduledTask { string TaskName { get; set; } int TaskPriority { get; set; } List<IScheduledTask> Subtasks { get; set; } // ... several more properties in this vein } // ScheduledTaskImpl.cs public class ScheduledTaskImpl : IScheduledTask { public string TaskName { get; set; } public …

8
データベースからの誤ったnullエントリを防ぐための設計と実践
私のプログラムの一部は、データベース内の多くのテーブルと列からデータをフェッチして処理します。一部の列はである可能性がありますがnull、現在の処理コンテキストではエラーです。 これは「理論的には」発生しないはずなので、発生する場合は、不良データまたはコード内のバグを示しています。エラーの重大度は、フィールドによって異なりnullます。つまり、一部のフィールドでは処理を停止して誰かに通知する必要があり、他のフィールドでは処理を続行して誰かに通知するだけにする必要があります。 まれですが可能なnullエントリを処理するための優れたアーキテクチャまたは設計原則はありますか? ソリューションはJavaで実装できるはずですが、問題は言語にとらわれないため、タグを使用しませんでした。 私自身が持っていたいくつかの考え: NOT NULLの使用 最も簡単なのは、データベースでNOT NULL制約を使用することです。 しかし、データの元の挿入がこの後の処理ステップよりも重要である場合はどうなりますか?そのため、挿入がnull(バグまたは何らかの正当な理由のために)テーブルに挿入される場合、挿入が失敗しないようにします。プログラムのさらに多くの部分が挿入されたデータに依存しているが、この特定の列には依存していないとしましょう。そのため、挿入ステップではなく、現在の処理ステップでエラーが発生する危険を冒したいのです。それが、NOT NULL制約を使用したくない理由です。 単純にNullPointerExceptionに依存 常にそこにあると期待しているかのようにデータを使用し(実際にそうであるはずです)、結果のNPEを適切なレベルでキャッチします(たとえば、現在のエントリの処理は停止しますが、処理全体は進行しません) )。これは「フェイルファースト」の原則であり、私はしばしばそれを好みます。少なくともバグの場合、ログに記録されたNPEを取得します。 しかしその後、さまざまな種類の欠落データを区別する能力が失われます。たとえば、一部の欠落しているデータについては除外することができますが、他の場合は処理を停止して管理者に通知する必要があります。 null各アクセスの前に確認し、カスタム例外をスローする カスタム例外を使用すると、例外に基づいて正しいアクションを決定できるため、これは進むべき道のようです。 しかし、どこかで確認するのを忘れた場合はどうなりますか?また、私はコードを、まったくまたはほとんど期待されない(そしてビジネスロジックフローの一部ではない)nullチェックで混乱させます。 この方法を選択した場合、どのパターンがアプローチに最適ですか? 私のアプローチについての考えやコメントは大歓迎です。また、あらゆる種類の優れたソリューション(パターン、原則、私のコードまたはモデルの優れたアーキテクチャなど)。 編集: 別の制約があります。ORMを使用してDBから永続オブジェクトへのマッピングを行うため、そのレベルでnullチェックを実行しても機能しません(nullが害を及ぼさない部分で同じオブジェクトが使用されるため)。 。これまでに提供された回答の両方がこのオプションについて言及したため、これを追加しました。

5
抽象化に依存することに重大な欠点はありますか?
私はこのウィキを安定した抽象化の原則(SAP)で読んでいました。 SAPは、パッケージの安定性が高いほど、抽象的である必要があると述べています。これは、パッケージの安定性が低い(変更される可能性が高い)場合、より具体的であることを意味します。私が本当に理解していないのは、これが事実であるべき理由です。確かにすべての場合において、安定性に関係なく、抽象化に依存し、具体的な実装を隠す必要がありますか?

2
Scalaでの自己型と特性継承の違いは何ですか?
グーグルドすると、このトピックに対する多くの回答が出てきます。しかし、これらの2つの機能の違いをうまく説明しているようには思えません。もう一度試してみたいのですが、具体的には... 継承ではなく自己型でできること、およびその逆は何ですか? 私には、2つの間に定量化可能な物理的な違いがあるはずです。そうでなければ、それらは名目上異なるだけです。 特性AがBまたは自己型Bを拡張する場合、どちらもBであることは要件であることを示していませんか?違いはどこですか?

4
Listインターフェースは漏れやすい抽象化ですか?
を含む変数がある場合、その変数には、またはなどList、さまざまなタイプのオブジェクトが含まれる可能性があります。a とan の違いはかなり大きいです。メソッドのビッグO動作は大きく異なります。たとえば、をソートしてからバイナリ検索を実行することは完全に問題ありませんが、では意味がありません。ArrayListLinkedListLinkedListArrayListListArrayListLinkedList

7
オブジェクト指向に必要な機能は何ですか?
言語またはライブラリが「オブジェクト指向」として定義されるために、言語またはライブラリが提供しなければならない機能とは正確には何なのかと思います。オブジェクト指向は、缶は、多かれ少なかれ、中に達成されることを何かである任意のまともな機能を備えた汎用プログラミング言語?それとも、オブジェクト指向プログラミングをサポートしていることを具体的に宣伝している言語でのみ達成できるものですか? たとえば、次のCコードを見てください。 SDL_Surface* screen = SDL_SetVideoMode( 640, 480, 16, SDL_HWSURFACE); SDL_FreeSurface( screen ); またはここで説明したコード。 さて、上記のコードは継承、ランタイムポリモーフィズム(?)、仮想関数などを使用していません。しかし、私にはほとんどOOPのようです。 オブジェクト指向は、オブジェクト、クラス、構造体など、プログラミング言語またはライブラリによって提供される特別なパターンや機能を必要としない、作成および破壊可能なデータ構造に基づくコードを単に記述しているのですか?

2
…Helperまたは…Managerクラスを回避する方法
プロジェクトにはかなりの数のヘルパークラスがあります。これは悪いことだと読んだことがありますが、「ヘルパー」がサフィックスとして間違っていると思います。例を挙げましょう。 まず、Userクラスがあります。GetSuggestedFriends()ユーザーのための方法が必要です。提案された友達のリストをUserクラスから除外するためのロジックを保持したいので、肥大化しません。現在、コンストラクターでFriendshipHelperを受け取るがありUserます。友達候補を取得するためのロジックが含まれているので、を呼び出すことができますmyUser.FriendshipHelper.GetSuggestedFriends()。 元々FriendshipHelperは静的メソッドのみがあり、Userオブジェクトはそれぞれに渡されていました。今、クラスを最初から作成している場合は、それを呼び出すかもしれませんFriendshipManager-友達の追加や削除なども行います。 ...Managerただし、クラスが悪いことも読みました。私はこのクラスを何と呼ぶべきですか?または、これは「不良コード」ですか?友達候補、現在の友達、友達の追加と削除のロジックはどこにあるべきですか?きっとすべてが巨大なUserクラスにいるわけではありませんか?

8
現在のスレッドがメインスレッドであることを表明する単体テスト
問題は、現在のスレッドがメインスレッドであることを表明する単体テストを記述することには意味があるのでしょうか。長所短所? 最近、サービスのコールバックのために現在のスレッドをアサートする単体テストを見ました。いいアイデアだとは思いませんが、もっと統合テストだと思います。私の意見では、単体テストはメソッドを個別にアサートする必要があり、サービスの利用者の性質については知らないはずです。 たとえば、iOSでは、このサービスのコンシューマーは、デフォルトでメインスレッドでコードを実行するための制約を持つUIであることが意図されています。

4
イベントを使用した分離コンポーネント間の通信
相互に作用する小さな(> 50)小さなWebComponentsがたくさんあるWebアプリがあります。 すべてを切り離しておくために、原則として、どのコンポーネントも別のコンポーネントを直接参照できないようにしています。代わりに、コンポーネントはイベントを発生させ、(「メイン」アプリ内で)配線されて、別のコンポーネントのメソッドを呼び出します。 時間が経つにつれ、追加されるコンポーネントが増え、「メイン」のアプリファイルには次のようなコードチャンクが散らばっています。 buttonsToolbar.addEventListener('request-toggle-contact-form-modal', () => { contactForm.toggle() }) buttonsToolbar.addEventListener('request-toggle-bug-reporter-modal', () => { bugReporter.toggle() }) // ... etc これを改善するために、同様の機能をグループ化し、にClass関連性のある名前を付け、インスタンス化するときに参加要素を渡し、内の「配線」を次のClassように処理します。 class Contact { constructor(contactForm, bugReporter, buttonsToolbar) { this.contactForm = contactForm this.bugReporterForm = bugReporterForm this.buttonsToolbar = buttonsToolbar this.buttonsToolbar .addEventListener('request-toggle-contact-form-modal', () => { this.toggleContactForm() }) this.buttonsToolbar .addEventListener('request-toggle-bug-reporter-modal', () => { this.toggleBugReporterForm() }) …

8
単一の責任の原則違反ですか?
私は最近、以下のクラスに関して別の開発者との議論に入りました: public class GroupBillingPayment { public void Save(IGroupBillingPayment model) { if (model == null || UserInfo.UserID == 0) { throw new Exception("GroupBillingPayment object or Current User Id is NULL , Please Contact Administrator."); } Data.GroupBillingPayment groupBillingPayment = RepositoryManager.GroupBillingPaymentRepository.GetById(model.GroupBillingPaymentID); Mapper.Map(model, groupBillingPayment); ServiceManager.GroupBilling.IsBillAlreadyCancelled(groupBillingPayment.GroupBillingID, THROW_ERROR); groupBillingPayment.UpdatedBy = UserInfo.UserID; groupBillingPayment.UpdatedOn = DateTime.Now; RepositoryManager.GroupBillingPaymentRepository.Update(groupBillingPayment, false); …

4
非常に複雑なソフトウェアのコードベースを管理するにはどうすればよいですか?
私は、さまざまなオブジェクト指向プログラミング言語を使用して、自分自身と他の人のためのプログラムを作成することがよくあります。その場合、通常は比較的小さくなります(最大で数千行)。しかし最近、私は完全なゲームエンジンなど、より大きなプロジェクトを作成しようとしています。そうするとき、私はしばしば複雑さという障害にぶつかるように見えます。 私の小さなプロジェクトでは、プログラムのすべての部分がどのように機能するかについてのメンタルマップを覚えることは簡単です。これにより、変更がプログラムの残りの部分にどのように影響するかを十分に認識し、バグを非常に効果的に回避できるだけでなく、新機能がコードベースにどのように適合するかを正確に確認できます。しかし、より大きなプロジェクトを作成しようとすると、非常に面倒なコードと多数の意図しないバグにつながる、優れたメンタルマップを維持することが不可能であることがわかりました。 この「メンタルマップ」の問題に加えて、自分のコードを他の部分から切り離しておくことは難しいと思います。たとえば、マルチプレーヤーゲームにプレーヤーの動きの物理を処理するクラスとネットワークを処理するクラスがある場合、これらのクラスの1つが他のクラスに依存してプレーヤーの動きのデータをネットワークシステムに取得する方法はありませんネットワーク経由で送信します。このカップリングは、優れたメンタルマップを妨げる複雑さの重要な原因です。 最後に、他のクラスを調整する1つ以上の「マネージャー」クラスを考え出すことがよくあります。たとえば、ゲームでは、クラスがメインのティックループを処理し、ネットワーククラスとプレーヤークラスの更新メソッドを呼び出します。これは、各クラスは他とは独立して単体テスト可能で使用可能でなければならないという私の研究での発見の哲学に反しています。そのようなマネージャークラスは、その目的によってプロジェクトの他のほとんどのクラスに依存しているためです。さらに、プログラムの残りのマネージャークラスオーケストレーションは、メンタルマッピング不可能な複雑さの重要な原因です。 まとめると、これにより、かなりのサイズの高品質のバグのないソフトウェアを作成できなくなります。この問題を効果的に処理するために、プロの開発者は何をしますか?私は特にJavaとC ++のOOP回答ターゲットに興味がありますが、この種のアドバイスはおそらく非常に一般的です。 ノート: 私はUMLダイアグラムを使用してみましたが、それは最初の問題に役立つようであり、それでも(たとえば)最初に初期化されるものに関するメソッド呼び出しの順序付けではなく、クラス構造に関する場合に限られます。

3
OOで場所、学術用語、さまざまなコホートをモデル化する方法
私は大学向けのアプリに取り組んでいます。ケースはこれです: 各大学にはいくつかの学術プログラムがあります。各プログラムには多くの主題(モジュール)があります。各科目は異なる場所で提供できます。学年は学期に分かれており、各学期は数週間続きます。すべてのモジュールが同じ場所で各学期に提供されるわけではなく、プログラムは同じ学年度内の異なる開始日を持つ異なる学生グループに提供できます。 たとえば、A大学はニューヨークとロンドンでMBAプログラムを提供しています。MBAには、1学期(10週間)ごとに2つのモジュールがあります(MBA-NYとMBA-Lなど)。需要に応じて、通常の摂取量よりも1週間遅れて開始するプログラム(したがって、この用語ではモジュール)の3回目の実行を行うことができます。したがって、別のMBA-NYグループがありますが、タイムラインが異なります。ただし、このグループは、MBAカリキュラムの同じ用語の一部でもあります(つまり、2つのグループはMBAの用語2を実行しています)。 私の質問は、場所、学術用語、OOデザインでの実行をモデル化する方法です。場所、学術用語(およびおそらく「実行」)は、大学オブジェクトまたはプログラムオブジェクトのプロパティですか?またはモジュールオブジェクトの? 更新:あなたの回答に基づいて、私の困難は学問の用語、コホート、および異なるタイムラインをモデル化することです。それは私にはまっすぐに見えるので、実際には場所ではありません。説明にそれを含めて、接続を示します。

4
メンバー関数がクラスプロパティ/メンバー変数を使用しない場合、OOP原則に違反しますか?
私は、ファイルを開いたり、読んだり、書き込んだりできる相互作用する既存のクラスを持っています。そのためにファイルの変更を取得する必要があります新しいメソッドを追加する必要があります これが私のクラス定義で、新しいメソッドを追加したいとします。 class IO_file { std::string m_file_name; public: IO(); IO(std::string file_name); + time_t get_mtime(file_name); + OR + time_t get_mtime(); }; 2つのオプションがあります- 空のオブジェクトを作成してから、ファイルの変更時刻を取得するメソッドの引数にfile_nameを渡します。 オブジェクト構築時にファイル名を渡し、単純にメンバー変数を操作するメンバー関数を呼び出します。 どちらのオプションも目的を果たします。また、2番目のアプローチは最初のアプローチよりも優れていると思います。しかし、私が理解していないのはどのようにですか?メンバー変数を利用しないので、最初のアプローチは悪いデザインですか?オブジェクト指向設計のどの原則に違反しますか?メンバー関数がメンバー変数を使用しない場合、そのメンバー関数は常に静的にする必要がありますか?

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