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

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

3
循環依存関係を解決する方法は?
相互に循環依存する3つのクラスがあります。 TestExecuterはTestScenarioのリクエストを実行し、ReportGeneratorクラスを使用してレポートファイルを保存します。そう: TestExecuterはReportGeneratorに依存してレポートを生成します ReportGeneratorは、TestScenarioおよびTestExecuterから設定されたパラメーターに依存します。 TestScenarioはTestExecuterに依存しています。 それらの依存関係を削除する方法がわかりません。 public class TestExecuter { ReportGenerator reportGenerator; public void getReportGenerator() { reportGenerator = ReportGenerator.getInstance(); reportGenerator.setParams(this.params); /* this.params several parameters from TestExecuter class example this.owner */ } public void setTestScenario (TestScenario ts) { reportGenerator.setTestScenario(ts); } public void saveReport() { reportGenerator.saveReport(); } public void executeRequest() { /* …

2
スケーラブルな通知システムを設計する方法は?[閉まっている]
通知システムマネージャーを作成する必要があります。 私の要件は次のとおりです。 異なるプラットフォームで通知を送信できる必要がありますが、これは完全に異なる場合があります(たとえば、SMSまたはEメールのいずれかを送信できる必要があります)。 通知は、特定のプラットフォームのすべての受信者で同じ場合もありますが、プラットフォームごとの受信者(または複数)ごとの通知である場合もあります。 各通知にはプラットフォーム固有のペイロードを含めることができます(たとえば、MMSにはサウンドまたは画像を含めることができます)。 システムはスケーラブルである必要があり、アプリケーションまたはサーバーをクラッシュさせることなく、非常に大量の通知を送信できる必要があります。 これは2段階のプロセスです。最初に顧客がメッセージを入力し、送信先のプラットフォームを選択します。その後、リアルタイムで処理されるように通知を作成する必要があります。 次に、システムはプラットフォームプロバイダーに通知を送信する必要があります。 今のところ、私はいくつかの結果になりますが、どれだけスケーラブルであるか、またはそれが良いデザインであるかどうかはわかりません。 私は次のオブジェクトを(疑似言語で)しました: 汎用Notificationオブジェクト: class Notification { String $message; Payload $payload; Collection<Recipient> $recipients; } 次のオブジェクトの問題は、受信者が1.000.000だったらどうなりますか?Recipientオブジェクトが非常に小さい場合でも、メモリを大量に消費します。 受信者ごとに1つの通知を作成することもできますが、一部のプラットフォームプロバイダーはバッチで送信する必要があるため、複数の受信者で1つの通知を定義する必要があります。 作成された各通知は、DBやRedisなどの永続ストレージに保存できます。 これを後で集約してスケーラブルであることを確認するのは良いことでしょうか? 2番目のステップで、この通知を処理する必要があります。 しかし、適切なプラットフォームプロバイダーへの通知をどのように区別できますか? をMMSNotification拡張するようなオブジェクトを使用する必要がありabstract Notificationますか?または何かのようなNotification.setType('MMS')? 大量の通知を同時に処理できるようにするには、RabbitMQのようなメッセージングキューシステムが適切なツールであると考えています。それは...ですか? これにより、大量の通知をキューに入れ、複数のワーカーに通知をポップして処理させることができます。しかし、上記のように受信者をバッチ処理する必要がある場合はどうなりますか? 次に、プラットフォームプロバイダーを接続して通知を実行するために、それぞれNotificationProcessor追加できるオブジェクトを担当することを想像します。NotificationHandlerNotificationHandler を使用しEventManagerて、プラグイン可能な動作を許可することもできます。 フィードバックやアイデアはありますか? お時間をいただきありがとうございます。 注:私はPHPでの作業に慣れており、おそらく選択した言語です。 編集 (morphunrealの答えによる) 1秒間に送信するメッセージの数(現在/初期レベルを定義し、再設計する前にシステムが処理する必要がある最大レベルを定義します) システムのハードウェア制約(システムで使用可能なメモリ、CPUなど) ハードウェアはどのように拡張されますか(つまり、サーバーの追加、クラウドコンピューティングなど) どの言語/システムが通知を生成しますか? 通知はプログラムで作成しますが、UIから作成するのは私自身です。 ジェネレーターはメッセージの受信者を知っていますか(?)、または他の手段で提供されていますか(つまり、特定のアラートタイプのビジネスルールは特定の受信者に送信されます) 特定の受信者、受信者のグループ(たとえば、タグシステムを使用)、またはプラットフォーム全体に対して通知を作成できる必要があります。 CC / BCC /開封確認を追加するためのビジネスルールはありますか はい。これは実際にはプラットフォーム固有であり、readまたはccはすべてのプラットフォームで利用できるわけではないことに注意してください。 …

7
後で使用するためにループにフラグを設定するのはコードの匂いですか?
特定の条件が満たされるまでマップを反復処理し、後でその条件を使用してその他の処理を実行するコードがあります。 例: Map<BigInteger, List<String>> map = handler.getMap(); if(map != null && !map.isEmpty()) { for (Map.Entry<BigInteger, List<String>> entry : map.entrySet()) { fillUpList(); if(list.size() > limit) { limitFlag = true; break; } } } else { logger.info("\n>>>>> \n\t 6.1 NO entries to iterate over (for given FC and target) \n"); } if(!limitFlag) …

3
「開始」、「実行」、「実行」の方法は良い習慣ですか?
現在、Startメソッドを実装する多くのクラスを持つコードベースで作業しています。これは私にとって二段階の構成のように思えますが、私は常に悪い習慣だと考えていました。これとコンストラクターの違いはわかりません。 通常のオブジェクト構築の代わりに開始メソッドを使用するのが適切なのはいつですか? コンストラクターを使用するのはいつですか? 編集:私はそれが関連しているとは思わないが、プログラミング言語はC#であり、JavaまたはC ++に等しく適用できる

10
関数型プログラミングの支持者は、Code Completeでこのステートメントにどのように答えますか?
Steve McConnellは、第2版の839ページで、プログラマーが大きなプログラムで「複雑さを克服する」ためのすべての方法について議論しています。彼のヒントは次のステートメントで終わります。 「オブジェクト指向プログラミングは、アルゴリズムとデータに同時に適用される抽象化のレベルを提供します。これは、機能分解だけでは提供されない一種の抽象化です。」 「複雑さを軽減することは、間違いなく効果的なプログラマーになるための最も重要な鍵」(同じページ)という彼の結論と相まって、これは関数型プログラミングへのほとんどの挑戦のようです。 FPとOOの間の議論は、並行性または並列化の課題に特に由来する複雑性の問題に関するFPの支持者によってしばしばフレーム化されます。ただし、ソフトウェアプログラマが克服する必要があるのは、同時性だけではありません。おそらく、ある種の複雑さを減らすことに焦点を合わせると、他の次元では大幅に増加するため、多くの場合、ゲインはコストに見合うものではありません。 FPとOOの比較の条件を、並行性や再利用性などの特定の問題からグローバルな複雑さの管理にシフトした場合、その議論はどのように見えるでしょうか? 編集 私が強調したかったのは、オブジェクト指向はデータとアルゴリズムの両方の複雑さをカプセル化して抽象化しているように見えますが、関数型プログラミングはデータ構造の実装の詳細をプログラム全体に「公開」することを奨励しているようです。 たとえば、ここで「データ型の過剰な指定」は「慣用的なOOスタイルの否定的な結果」であり、AddressBookをより豊富なOOオブジェクトではなく単純なベクトルまたはマップとして概念化することを推奨するStuart Halloway(Clojure FP支持者)を参照してください追加の(非ベクター的かつ非マップ的)プロパティとメソッドがあります。(また、オブジェクト指向およびドメイン駆動設計の支持者は、AddressBookをベクトルまたはマップとして公開すると、カプセル化されたデータがドメインの観点からは無関係または危険なメソッドに過度に露出されると言うかもしれません)。

17
抽象化によって詳細を隠すことの価値は何ですか?透明性に価値はありませんか?
バックグラウンド 私は抽象化の大ファンではありません。インターフェースの適応性、移植性、再利用性などの恩恵を受けることができると認めます。そこには本当の利点がありますが、それを疑いたくないので無視しましょう。 抽象化のもう1つの主要な「利点」があります。これは、この抽象化のユーザーから実装ロジックと詳細を隠すことです。引数は、詳細を知る必要はなく、この時点で独自のロジックに集中する必要があるということです。理論的には理にかなっています。 ただし、大規模なエンタープライズアプリケーションを保守しているときはいつでも、常に詳細を知る必要があります。それは、何かが正確に何であるかを正確に見つけるために、毎回、抽象化を深く掘り下げる大きな手間となります。つまり、使用されているストアドプロシージャを見つける前に約12回「宣言を開く」必要があります。 この「詳細を隠す」という考え方は、邪魔をしているようです。私は常に、より透明なインターフェースとより少ない抽象化を望んでいます。私は高レベルのソースコードを読むことができ、それが何をするのかを知ることができますが、それがどのように行われるのか、それがどのように行われるのかを知る必要はありません。 何が起きてる?私がこれまでに取り組んできたすべてのシステムは、(少なくともこの観点から)ひどく設計されていますか? 私の哲学 ソフトウェアを開発するとき、私はArchLinuxの哲学と密接に関連していると思う哲学に従うように感じています: Arch Linuxは、GNU / Linuxシステムに固有の複雑さを保持しながら、それらを適切に組織化して透明性を保ちます。Arch Linuxの開発者とユーザーは、システムの複雑さを隠そうとすると、実際にはさらに複雑なシステムになるため、避けるべきだと考えています。 したがって、抽象レイヤーの背後にソフトウェアの複雑さを隠そうとはしません。私は抽象化を悪用しようとしますが、それの奴隷になることはしません。 心からの質問 詳細を隠すことには本当の価値がありますか? 透明性を犠牲にしませんか? この透明性は重要ではありませんか?

10
抽象クラスのインターフェース
同僚と私は、基本クラスとインターフェイスの関係について異なる意見を持っています。インターフェイスの実装が必要なときにそのクラスを使用できる場合を除き、クラスはインターフェイスを実装すべきではないと考えています。言い換えれば、私はこのようなコードを見たい: interface IFooWorker { void Work(); } abstract class BaseWorker { ... base class behaviors ... public abstract void Work() { } protected string CleanData(string data) { ... } } class DbWorker : BaseWorker, IFooWorker { public void Work() { Repository.AddCleanData(base.CleanData(UI.GetDirtyData())); } } DbWorkerは、インスタンス化可能なインターフェイスの実装であるため、IFooWorkerインターフェイスを取得するものです。契約を完全に満たします。私の同僚はほぼ同じものを好む: interface IFooWorker { void Work(); } …

3
メソッドがTDDで再設計されてプライベートになった場合、メソッドのテストはどうなりますか?
他のキャラクターやそのようなものを攻撃するキャラクターでロールゲームの開発を始めたとしましょう。 TDDを適用して、Character.receiveAttack(Int)メソッド内のロジックをテストするテストケースを作成します。このようなもの: @Test fun healthIsReducedWhenCharacterIsAttacked() { val c = Character(100) //arg is the health c.receiveAttack(50) //arg is the suffered attack damage assertThat(c.health, is(50)); } メソッドをテストreceiveAttackする10のメソッドがあるとします。次に、メソッドCharacter.attack(Character)(メソッドを呼び出すreceiveAttack)を追加し、TDDサイクルでテストした後、決定するCharacter.receiveAttack(Int)必要がありますprivate。 以前の10個のテストケースはどうなりますか?それらを削除する必要がありますか?メソッドを保持する必要publicがあります(そうは思わない)。 この質問は、プライベートメソッドをテストする方法ではなく、TDDを適用する際の再設計後にそれらを処理する方法に関するものです。

4
C#6.0の新しいnull条件演算子は、Demeterの法則に反しますか?
デメテルの法則は次のように述べています: 各ユニットは、他のユニットに関する限られた知識のみを持つ必要があります。現在のユニットに「密接に」関連するユニットのみです。 各ユニットは、その友人とのみ会話する必要があります。見知らぬ人と話をしないでください。 身近な友達とだけ話してください。 C#6.0では、null-conditional operatorと呼ばれる新しい演算子が導入されました。私見、それはコーディングを容易にし、読みやすさを向上させます。ただし、クラスフィールドをナビゲートするのが簡単で、すでにヌル(のようなものvar x = A?.B?.C?.D?.E?.F?)をチェックしているため、より結合されたコードを簡単に記述できます。 この新しいオペレーターがデメテルの法則に反すると述べるのは正しいですか?

6
classキーワードなしで「オブジェクト指向」プログラミングを実装できますか?
銀行の「口座」の抽象化を提供したいとします。functionPythonでオブジェクトを使用する1つのアプローチを次に示します。 def account(): """Return a dispatch dictionary representing a bank account. >>> a = account() >>> a['deposit'](100) 100 >>> a['withdraw'](90) 10 >>> a['withdraw'](90) 'Insufficient funds' >>> a['balance'] 10 """ def withdraw(amount): if amount > dispatch['balance']: return 'Insufficient funds' dispatch['balance'] -= amount return dispatch['balance'] def deposit(amount): dispatch['balance'] += amount return dispatch['balance'] …

6
フラグをチェックする必要をなくすためのデザインパターンはありますか?
データベースに文字列ペイロードを保存します。2つのグローバル構成があります。 暗号化 圧縮 これらは、構成を使用して有効または無効にすることができます。その場合、どちらか一方のみを有効にするか、両方を有効にするか、両方を無効にします。 私の現在の実装はこれです: if (encryptionEnable && !compressEnable) { encrypt(data); } else if (!encryptionEnable && compressEnable) { compress(data); } else if (encryptionEnable && compressEnable) { encrypt(compress(data)); } else { data; } デコレータパターンについて考えています。それは正しい選択ですか、それとももっと良い選択肢がありますか?

7
関数型プログラミングは、「システムをモジュールに分解する際に使用される基準について」(データの隠蔽)から得られる利点を無視しますか?
「システムをモジュールに分解する際に使用する基準について」という古典的な記事がありますが、これは初めて読んだばかりです。それは私にとって完全に理にかなっており、おそらくOOPのベースとなった記事の1つです。その結論: これらの例により、フローチャートに基づいてシステムのモジュールへの分解を開始することはほとんど常に間違っていることを実証しようとしました。...各モジュールは、そのような決定を他のモジュールから隠すように設計されています 私の無学で経験の浅い意見では、関数型プログラミングはこの記事の正反対のアドバイスを取ります。私の理解では、関数型プログラミングはデータフローを慣用的にします。データは関数から関数に渡され、各関数はデータを密接に認識し、途中で「変更」します。そして、データの隠蔽が過大評価されているか、不必要であるか、または何かについて話しているリッチヒッキーのトークを見たことがあると思いますが、確かに思い出せません。 まず、私の評価が正しいかどうか知りたいです。FPパラダイムとこの記事は哲学的に同意しませんか? 彼らが同意しないと仮定すると、FPはデータ隠蔽の欠如をどのように「補償」しますか?おそらく、データ隠蔽を犠牲にしてX、Y、およびZを獲得する可能性があります。X、Y、およびZがデータ隠蔽よりも有益である理由を知りたいのです。 または、両者が同意しないと仮定すると、FPはデータの非表示が悪いと感じるかもしれません。もしそうなら、なぜデータ隠蔽が悪いと思うのですか? 彼らが同意すると仮定して、FPがデータ隠蔽の実装とは何かを知りたいです。OOPでこれを見るのは明らかです。privateクラス外の誰もアクセスできないフィールドを持つことができます。FPの場合、これについての明らかな類推はありません。 質問すべき他の質問もあると思いますが、質問すべきかはわかりません。それらにも自由に答えてください。 更新 このNeal Fordの講演には、非常に関連性の高いスライドが含まれています。ここにスクリーンショットを埋め込みます。

9
リスコフの代替原則に違反した場合、何が問題になる可能性がありますか?
私は、リスコフ代替原理の違反の可能性について、この非常に投票された質問に従っていました。Liskov Substitutionの原則が何であるかは知っていますが、開発者としてオブジェクト指向コードを書いている間にこの原則を考えないと、何が間違っているのかが私の心ではまだはっきりしていません。

4
プロトタイプ継承は、従来の継承と実際にどのように異なりますか?
継承、ポリモーフィズム、およびカプセル化は、OOPの3つの最も明確で重要な機能であり、それらから、最近では継承に高い使用統計があります。私はJavaScriptを学んでいますが、ここでは彼らはすべてプロトタイプ継承を持っていると言い、どこでも人々はそれが古典的な継承とはまったく異なるものだと言います。 しかし、実際の使用の点との違いは理解できませんか?つまり、基本クラス(プロトタイプ)を定義し、そこからいくつかのサブクラスを派生させると、どちらも基本クラスの機能にアクセスでき、派生クラスの機能を拡張できます。私が言ったことを継承の意図した結果であると考える場合、プロトタイプバージョンとクラシックバージョンのどちらを使用しているのかを気にする必要があるのはなぜですか? さらに明確にするために、プロトタイプ継承と従来の継承の有用性と使用パターンに違いは見られません。その結果、両者が同じものであるOOADをもたらすため、それらが異なる理由を学ぶことに興味がありません。プロトタイプの継承は、実際には(理論的にではなく)古典的な継承とどの程度異なりますか?

3
オブジェクト指向の分析と設計(OOAD)を上手にするには?
優れたアナライザーおよびデザイナーになることは、開発者に大きな利益をもたらします。しかし、これには間違いなく障害があります。誰もがOOADに興味があるわけではなく、興味のあるすべての人が経路を知っているわけでもありません。優れたOOADは複数のOO言語を知っているべきですか?または彼/彼女はプロジェクトに失敗したはずですか?どうすればよいOOADになれますか?

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