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

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

3
実際に開閉原理を遵守する方法
私は、オープンクローズド原則の意図を理解しています。変更せずに拡張しようとするように指示することで、変更中に既に機能しているものを壊すリスクを減らすことを目的としています。 しかし、この原則が実際にどのように適用されるかを理解するのに苦労しました。私の理解では、それを適用するには2つの方法があります。変更前と変更後: 前:できるだけ抽象化して「未来を予測する」プログラムを作成します。たとえば、将来システムにsが追加されたdrive(Car car)場合、メソッドは変更する必要 Motorcycleがあるため、おそらくOCPに違反します。ただし、この方法drive(MotorVehicle vehicle)は将来変更する必要性が低いため、OCPに準拠しています。 ただし、将来を予測し、システムにどのような変更が加えられるかを事前に知ることは非常に困難です。 変更後:変更が必要な場合、現在のコードを変更する代わりにクラスを拡張します。 練習#1を理解するのは難しくありません。しかし、適用方法を理解するのに苦労しているのは実践#2です。 例(YouTubeのビデオから取得しました):CreditCardオブジェクトを受け入れるクラスにメソッドがあるとします:makePayment(CraditCard card)。1日Voucherがシステムに追加されます。このメソッドはそれらをサポートしていないため、変更する必要があります。 そもそもメソッドを実装するとき、未来とプログラムをより抽象的な用語で予測することに失敗しました(たとえばmakePayment(Payment pay)、今、既存のコードを変更する必要があります)。 練習#2では、変更するのではなく拡張することで機能を追加する必要があります。どういう意味ですか?既存のコードを単に変更するのではなく、既存のクラスをサブクラス化する必要がありますか?コードの書き換えを避けるために、何らかのラッパーを作成する必要がありますか? または、原則は「機能を正しく変更/追加する方法」に言及するのではなく、「最初に変更を加える必要がないようにする方法」(つまり、プログラムを抽象化する方法)に言及していますか?

8
技術面接でのOOデザイン関連の質問[終了]
閉じた。この質問は意見に基づいています。現在、回答を受け付けていません。 この質問を改善したいですか?この投稿を編集して事実と引用で答えられるように質問を更新してください。 4年前に閉鎖されました。 私は最近、かなりの数のインタビューに参加しており、企業から「[モデルを挿入]を設計する」という質問に数回以上回答するように依頼されています。 これは最近の業界では普通ですか?私は20年以上ソフトウェアの世界にいて、インタビューに参加していますが、インタビューでこのパターンが現れるのはごく最近です。 質問は非常に開かれていると感じています。たとえば、「駐車場を設計する」ためにクラス図を描くように頼まれました。インタビュアーがどのレベルの詳細を期待しているのかわかりません。これは、Visioダイアグラムを添付することが期待されていたオンラインテストであったため、彼らの期待を尋ねることはできませんでした。 この種の質問を面接プロセスで使用していますか?それらはクラス図のみに関連していますか、またはシーケンス、フローチャート、ERD(もちろん職種の性質に基づいて)を求めていますか? *ケビンの応答用に編集* 例:完全な質問は、「空きスロットを見つけるために使用できる駐車場管理システムを設計する」です。 I 2クラスで行うことができ、ParkingLotかつSlot追加したり、私が上で行くことができるIVehicleとVehicleしてCarおよびMotorcycleクラス。どこで線を引きますか? public class ParkingLot { IVehicle Vehicle {set; get;} List<Slot> GetEmptySlots() { }; } public class Vehicle : IVehicle { Slot SlotNum {set; get;} } public class Slot { int Row {set; get;} int Column {set; get; } }

2
デザイン:オブジェクトメソッドと、オブジェクトをパラメーターとして取る別のクラスのメソッド
たとえば、行う方が良いですか: Pdf pdf = new Pdf(); pdf.Print(); または: Pdf pdf = new Pdf(); PdfPrinter printer = new PdfPrinter(); printer.Print(pdf); もう一つの例: Country m = new Country("Mexico"); double ratio = m.GetDebtToGDPRatio(); または: Country m = new Country("Mexico"); Country us = new Country("US"); DebtStatistics ds = new DebtStatistics(); double usRatio = ds.GetDebtToGDPRatio(us); double …

2
LinkedListを拡張するスタック。Liskov Substitution Principleの違反?
クラスLinkedListは、add_first()、add_last()、add_after()、remove_first()、remove_last()、remove()などの関数とともに存在します 現在、push()、pop()、peek()、またはtop()などの機能を提供するクラスStackがあり、これらのメソッドを実装するためにLinkedListクラスメソッドを拡張しています。これは、リスコフ代替原理の違反ですか? たとえば、リンクリストのn番目の位置にノードを追加する場合のadd_after()の場合を考えます。これは基本クラスで実行できますが、Stackクラスでは実行できません。ここで事後条件が弱くなっていますか、それともadd_after()メソッドを変更してスタックの一番上に追加しますか? また、違反ではない場合、これは悪い設計ですか?そして、LinkedListクラスを使用してStack機能をどのように実装しますか?

4
SOLIDをフォローする場合、ファイルの読み取りと書き込みには2つの異なる責任がありますか?
SOLIDの調査を始めたばかりで、ファイルの読み取りとファイルへの書き込みが同じ責任であるかどうかはわかりません。 ターゲットは同じファイルタイプです。アプリケーションで.pdfを読み書きしたい。 それが違いを生む場合、アプリケーションはPythonです。

5
静的メソッドをオーバーライドできないのはなぜですか?
この質問への回答で、一般的なコンセンサスは、静的メソッドはオーバーライドされることを意図していないということでした(したがって、C#の静的関数は仮想または抽象にできません)。ただし、これはC#の場合だけではありません。Javaもこれを禁止しており、C ++もそれを好まないようです。ただし、子クラスでオーバーライドしたい静的関数(ファクトリーメソッドなど)の多くの例を考えることができます。理論的には、それらを回避する方法がありますが、それらはどれもきれいでも単純でもありません。 静的関数をオーバーライドできないのはなぜですか?

1
オブジェクトライフタイム不変式と移動セマンティクス
ずっと前にC ++を学んだとき、C ++のポイントの一部は、ループに「ループ不変式」があるように、クラスにもオブジェクトの存続期間に関連する不変式があることを強く強調しました。オブジェクトが生きている限り。コンストラクターによって確立され、メソッドによって保持されるべきもの。カプセル化/アクセス制御は、不変条件を強制するのに役立ちます。RAIIは、このアイデアでできることの1つです。 C ++ 11以降、ムーブセマンティクスがあります。移動をサポートするクラスの場合、オブジェクトからの移動はその寿命を正式に終了することはありません-移動は「有効な」状態のままにすることになっています。 クラスの設計において、クラスの不変式が移動元までしか保持されないように設計するのは悪い習慣ですか?または、高速化できるようになれば大丈夫です。 具体的にするために、コピー不可だが移動可能なリソースタイプがあるとします。 class opaque { opaque(const opaque &) = delete; public: opaque(opaque &&); ... void mysterious(); void mysterious(int); void mysterious(std::vector<std::string>); }; そして、何らかの理由で、おそらく既存のディスパッチシステムで使用できるように、このオブジェクトのコピー可能なラッパーを作成する必要があります。 class copyable_opaque { std::shared_ptr<opaque> o_; copyable_opaque() = delete; public: explicit copyable_opaque(opaque _o) : o_(std::make_shared<opaque>(std::move(_o))) {} void operator()() { o_->mysterious(); } void operator()(int …

4
ソフトウェアパイプラインで共有データをカプセル化するための優れた実装戦略
既存のWebサービスの特定の側面のリファクタリングに取り組んでいます。サービスAPIの実装方法は、一連のタスクが順番に実行される「処理パイプライン」のようなものを持つことです。当然のことながら、後のタスクは前のタスクによって計算された情報を必要とする場合があり、現在これを行う方法は「パイプライン状態」クラスにフィールドを追加することです。 私は、無数のフィールドを持つデータオブジェクトを持つよりもパイプラインステップ間で情報を共有するより良い方法があると考えています(そして望んでいますか?)このクラスをスレッドセーフにするのは大きな苦痛になります(可能かどうかはわかりません)、その不変式について推論する方法はありません(そしておそらくないかもしれません)。 私はインスピレーションを見つけるためにGang of Fourのデザインパターンブックをページングしていましたが、そこに解決策があるとは感じませんでした(Mementoはやや同じ精神ですが、まったく同じではありませんでした)。私もオンラインで調べましたが、「パイプライン」または「ワークフロー」を検索する2番目のケースでは、Unixパイプ情報、または独自のワークフローエンジンとフレームワークのいずれかであふれています。 私の質問は、ソフトウェア処理パイプラインの実行状態を記録する問題にどのようにアプローチし、後のタスクが以前のタスクによって計算された情報を使用できるようにするかです。Unixパイプとの主な違いは、直前のタスクの出力だけを気にしないことです。 要求されたとおり、私のユースケースを説明するためのいくつかの擬似コード: 「パイプラインコンテキスト」オブジェクトには、さまざまなパイプラインステップで入力/読み取りできるフィールドがあります。 public class PipelineCtx { ... // fields public Foo getFoo() { return this.foo; } public void setFoo(Foo aFoo) { this.foo = aFoo; } public Bar getBar() { return this.bar; } public void setBar(Bar aBar) { this.bar = aBar; } ... // more …

7
設計:親クラスへのコールバック
子を持つオブジェクトをモデリングするとき、親クラスのメンバーとして、構成を介して子を含めるのが一般的です。ただし、子が親に何かを伝える必要がある場合もありますが、親の関数を呼び出す必要があります。C ++を使用してこれをどのように達成できますか?いくつかのオプションは次のとおりです。 親クラスをグローバルにします。したがって、子オブジェクトは親オブジェクトのメンバー関数を呼び出すことができます。 すべての子オブジェクトに、親オブジェクトをポインターまたは参照として注入します。子が親オブジェクトに何かを伝える必要がある場合、使用できるメンバー変数があるため、子は常にそうすることができます。 これを行う他の方法は何ですか?この種の一般的なデザインパターンや名前はありますか? 他のオブジェクト指向言語では詳細が異なるため、C ++のアイデアとソリューションに興味があることに注意してください。たとえば、上記のポイント2では「ポインターまたは参照」に言及しており、両方ともC ++でのみ可能です。C ++には他の言語にはない言語機能があるため、問題の解決策を実装すると、これらの言語機能が組み込まれる可能性があり、他の言語で考えられるソリューションとは異なるソリューションになります。

2
アプリの一部が異なる言語で記述されている場合、データ構造の重複を回避するにはどうすればよいですか?
例として、Javaでアプリを書いているとしましょう。 アプリは、Pythonで記述されたAPIサーバーと通信します。 PythonサーバーはSQLデータベースと通信します。 JavaScriptで記述されたアプリのWebサイトもあります。 4つの異なる言語を使用すると、本質的に同じデータ構造を4回異なるものにするのは簡単です。 たとえば、User型は次のようになります(擬似コード): type User { integer id; string name; timestamp birthday; } プロジェクトのすべての部分には何らかの表現が必要でしょうUser。JavaパーツとPythonパーツには、2つの異なるclass宣言が必要です。データベースにはUserテーブル宣言が必要です。そして、フロントエンドサイトUserも代表する必要があります。 このタイプを4回繰り返すことは、「繰り返しはしない」という原則に反します。また、Userタイプが変更された場合、プロジェクトのさまざまな部分でこれらの変更を繰り返す必要があるという問題があります。 Googleのprotobufライブラリは、特殊な構文を使用してデータ構造を記述し、ライブラリが複数の異なるプログラミング言語で構造宣言を生成するというこの問題に対する一種のソリューションを提供することを知っています。しかし、これでも型の検証ロジックを繰り返さなければならないという問題には対応していません。 これに関する本やブログの投稿への提案やリンクはありますか?

2
オブジェクト指向設計で何をする必要があるかを実際に調べる方法は?
最初の免責事項:この質問がこのウェブサイトに適合するかどうかはわかりませんが、私だけでなく、初心者である他の人にとっても関連する質問であることに変わりはありません。ここに収まるように質問を改善できる場合は、intコメントを指摘してください。それが合わない場合は、私にも知らせてください。可能であれば、これに関する良いフォーラムが見つからなかったので、これについて議論できる場所を教えてください。 私はPHPを勉強した2009年にプログラミングを学びました。2012年の後半に、C#と.NETに移行しました。とにかく、コーディングは問題ではなく、アルゴリズムを書き留めることは私の問題ではありません。私の実際の問題は、要件を達成するために何をコーディングする必要があるか、どこでコーディングする必要があるかを知ることです。 Web上で利用できるそこにほとんどのコースは対処方法ここでは私のポイントではないなど、いくつかのAPIセットを使用する方法、特定の言語でコードを書く方法を- 。 ここ数年、オブジェクト指向の分析と設計、設計パターン、ドメイン駆動設計など、たくさんのことを読みました。たとえば、SOLIDの原則、ドメインエキスパートの関与の必要性、ユビキタス言語の開発など、DDDの主要なアイデアのいくつかを理解しています。少なくとも理にかなった理論的背景があると思います。 しかし、それが練習になると、私は災害だと感じます。しばらく前に、私はすでに他の誰かによって開発されていた金融システムの開発を続ける必要がありました。それは、C#とWinFormsで開発されたそのような「古いシステム」です。実際のドメインの複雑さ、多くのビジネスルールなどを含むプロジェクトを選んだのは初めてでした。 ほとんどの場合、要件を受け取ったとき、「一体どうやってこれを行うことができるのか」と思います。-どうすればよいのかを理解するために、要件の作業を開始する方法すらわからない。私が信じている主な混乱は、私がコーディングしなければならないもの、クラス、インターフェース、そして各ロジックがどこに行くのか、各クラスがどのクラスにあるべきなのかです。問題は、どこから始めればいいかわからないことです。 ほとんどの場合、非常に多くの考えでいくつかのアイデアになりますが、私のアイデアが正しいかどうかを判断する方法がわかりません。 推奨されたソフトウェアアーキテクチャとオブジェクト指向に関する多くのことを読んだと言ったので、これは理論の欠如ではないと思いますが、実際には何をしなければならないかを特定するのにはあまり役立ちませんでした。 それでは、どうすればオブジェクト指向設計を実際に 行うことができますか?私が学びたいのは、与えられた要件は、何をすべきか、各コードがどこに属しているかを見つけるプロセスでそれらに取り組む方法を知っていることです。自分の考えが正しいかどうかを判断する方法を学ぶにはどうすればよいですか? ここで答えとしてこれを完全に説明することは不可能だと思います。しかし、私が探しているのは、サイトのスタイルに応じて、単に概要を示し、アイデアを拡大し、これらのことを実際に学習するために使用できる参照(書籍、オンラインコースなど)を示す回答です。

5
キャッシングを管理するためにクラス内のSRPに違反しないようにする方法は?
注:コードサンプルはc#で記述されていますが、それは問題ではありません。適切なものを見つけることができないため、c#をタグとして配置しました。これはコード構造についてです。 Clean Codeを読んで、より良いプログラマーになろうとしています。 私はしばしば、単一の責任原則(クラスと関数は1つのことだけを行うべきです)、特に関数に従うことに苦労しています。たぶん私の問題は、「一つのこと」が明確に定義されていないことですが、それでも... 例:データベースにFluffiesのリストがあります。Fluffyが何であるかは気にしません。クラスに綿毛を回復させたい。ただし、綿毛はいくつかのロジックに従って変化する可能性があります。いくつかのロジックに応じて、このクラスはキャッシュからデータを返すか、データベースから最新のデータを取得します。毛羽立ちを管理していると言えますが、それは一つのことです。簡単にするために、ロードされたデータが1時間有効であり、それを再ロードする必要があるとしましょう。 class FluffiesManager { private Fluffies m_Cache; private DateTime m_NextReload = DateTime.MinValue; // ... public Fluffies GetFluffies() { if (NeedsReload()) LoadFluffies(); return m_Cache; } private NeedsReload() { return (m_NextReload < DateTime.Now); } private void LoadFluffies() { GetFluffiesFromDb(); UpdateNextLoad(); } private void UpdateNextLoad() { m_NextReload = DatTime.Now …

1
Open Close Principle(OCP)vs依存関係反転原理(DIP)
Open Closed Principle(OCP)とDependency Inversion Princible(DIP)の違いを理解しようとしていました。 これまでにインターネットで行った調査に基づいて、「DIPはOCPを達成するための1つのオプション」という結論に達しました。 これでいいの? DIPではなくOCPに従っている例を教えてください。

4
モデルとビューを扱うときの切り替えとポリモーフィズム
私の問題に対するより良い解決策を見つけることができません。要素のリストを表示するView Controllerがあります。これらの要素は、B、C、Dなどのインスタンスになり、Aから継承できるモデルです。したがって、そのView Controllerでは、各項目はアプリケーションの異なる画面に移動し、ユーザーがそれらのいずれかを選択するとデータを渡す必要があります。私の頭に浮かぶ2つの選択肢は次のとおりです(構文を無視してください、それは特定の言語ではありません) 1)スイッチ(私はそれが悪いことを知っています) //inside the view controller void onClickItem(int index) { A a = items.get(index); switch(a.type) { case b: B b = (B)a; go to screen X; x.v1 = b.v1; // fill X with b data x.v2 = b.v2; case c: go to screen Y; etc... } } 2)多型 …

4
C#のハッシュテーブルと辞書の実用的なサイズ制限
C#4ディクショナリまたはHashtableに含めることができるアイテムの数と、これらの構造に合理的に含めることができる合計バイト数の実際的な制限は何ですか。多数のオブジェクトを使用して、これらの構造がいつ問題を起こし始めるかを知りたいと思います。 コンテキストでは、大量のメモリを備えた64ビットシステムを使用します。また、何らかのフォームまたは「キー」を使用してオブジェクトを見つける必要があります。パフォーマンスの要求を考えると、これらのオブジェクトはメモリに常駐する必要があり、多くは存続します。 サードパーティまたはオープンソースのライブラリを使用しないようにする必要がありますが、他のアプローチ/パターンを自由に提案してください。仕様上の理由から、ネイティブC#(またはC ++ \ CLI)を使用してこれをビルドできる必要があります。

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