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

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

3
クラス内の属性を事前に初期化することをお勧めしますか、それとも途中で追加することですか?
これが絶対に二日酔いの質問である場合は申し訳ありませんが、ベストプラクティスがどこにあるのか興味があり、Googleで良い答えを見つけることができないようです。 Pythonでは、通常、空のクラスをスーパーキャッチオールデータ構造コンテナー(JSONファイルのようなもの)として使用し、途中で属性を追加します。 class DataObj: "Catch-all data object" def __init__(self): pass def processData(inputs): data = DataObj() data.a = 1 data.b = "sym" data.c = [2,5,2,1] これにより、コンテナオブジェクトは基本的に何でも保存できるため、非常に大きな柔軟性が得られます。したがって、新しい要件が生じた場合は、DataObjオブジェクトに別の属性として追加します(コードで渡します)。 しかし、最近、コードの読み取りが非常に難しくなるため、これはひどい慣行であると私(FPプログラマー)に感銘を受けました。すべてのコードを調べて、DataObjが実際に持っている属性を把握する必要があります。 質問:柔軟性を犠牲にすることなく保守性を高めるために、これをどのように書き直すことができますか? 関数型プログラミングから採用できるアイデアはありますか? 私はそこにベストプラクティスを探しています。 注:1つの考えは、遭遇することが予想されるすべての属性でクラスを事前初期化することです。例えば class DataObj: "Catch-all data object" def __init__(self): data.a = 0 data.b = "" data.c = [] def processData(inputs): data = …

2
DDDでは、ドメインサービスは基本的にはファサードパターンやメディエーターパターンだけですか?
ドメイン駆動設計では、ドメイン層にいくつかの(従来の)サービスを含めることができます。たとえば、ユーザードメインの場合、次のようになります。 さまざまな方法でUserオブジェクトを構築するUserFactory インフラストラクチャレイヤーの永続サービスとの対話を担当するUserRepository ドメインレイヤーのUserServiceは、これら2つのサービスとインフラストラクチャレイヤーのメディエーターやファサードにすぎませんか、それともそれ以上ですか?

2
インスタンスが1つだけのPythonクラス:(単一の)クラスインスタンスを作成するタイミングと、代わりにクラスを使用するタイミング
1回だけインスタンス化されるPythonクラスがある場合、つまり、クラスのオブジェクトは1つだけになります。クラスを直接操作するのではなく、単一のクラスインスタンスを作成する方が理にかなっているのではないかと思いました。 同様の質問がありますが、焦点は異なります。 グローバル変数と関数をクラスにグループ化することです Python固有ではありません。後者は、(Pythonで)クラスもオブジェクトであるという事実を考慮しないことを意味します。 更新: Pythonでは、クラスとオブジェクトの両方で次のことができます。 class A(object): pass A.some_state_var = True # Then later A.some_state_var = False my_a = A() my_a.some_state_var = True # Then later my_a.some_state_var = False そのため、クラスとそのクラスのインスタンスの間の選択が(Pythonで)状態に関するものであるかどうかはわかりません。どちらかで状態を維持できます。 さらに、クラス/クラスインスタンスを作成する動機は、シングルトン要件を強制することではありません。 また、新しいTypeを作成することはそれほど重要ではありません。 動機は、関連するコードとデータをグループ化し、それへのインターフェースを持つことです。これが、最初にクラス図のクラスとしてモデル化した理由です。実装に関してのみ、このクラスをインスタンス化するかどうか疑問に思い始めました。

5
このシナリオで構成または継承を優先すべきですか?
インターフェイスを考えてみましょう: interface IWaveGenerator { SoundWave GenerateWave(double frequency, double lengthInSeconds); } このインターフェイスは、さまざまな形状の波を生成するいくつかのクラス(SineWaveGeneratorおよびなどSquareWaveGenerator)によって実装されます。 SoundWave生のサウンドデータではなく、音楽データに基づいてを生成するクラスを実装したいと思います。それは音の名前と拍数(秒ではない)の長さを受け取り、内部的にIWaveGenerator機能を使用してSoundWaveそれを作成します。 質問は、「をNoteGenerator含むIWaveGeneratorべきIWaveGeneratorですか、それとも実装から継承すべきですか?」 次の2つの理由から、作曲に傾倒しています。 1- 動的に任意のIWaveGeneratorものを注入できNoteGeneratorます。またNoteGenerator、、などSineNoteGeneratorでSquareNoteGeneratorはなく、1つのクラスのみが必要です。 2-でNoteGenerator定義された下位レベルのインターフェースを公開する必要はありませんIWaveGenerator。 しかし、私はこれに関する他の意見を聞くためにこの質問を投稿しています。おそらく考えていない点です。 ところで:私はそれがsを生成するため、概念的に言うNoteGenerator と思います。IWaveGeneratorSoundWave

4
カプセル化の過剰使用に悩まされますか?
さまざまなプロジェクトのコードに、コードの臭いや悪いことのように見える何かに気づきましたが、対処できません。 「きれいなコード」を書き込もうとしている間、コードを読みやすくするためにプライベートメソッドを使いすぎる傾向があります。問題は、コードが確かにきれいであるが、テストするのが難しいことです(そう、私はプライベートメソッドをテストできることを知っています...)、一般的に私には悪い習慣のようです。 次に、.csvファイルからデータを読み取り、顧客のグループ(さまざまなフィールドと属性を持つ別のオブジェクト)を返すクラスの例を示します。 public class GroupOfCustomersImporter { //... Call fields .... public GroupOfCustomersImporter(String filePath) { this.filePath = filePath; customers = new HashSet<Customer>(); createCSVReader(); read(); constructTTRP_Instance(); } private void createCSVReader() { //.... } private void read() { //.... Reades the file and initializes the class attributes } private void readFirstLine(String[] inputLine) …

4
「混合」言語での設計:オブジェクト指向設計または関数型プログラミング?
過去数年間で、私が使用したい言語はますます「機能的」になりつつあります。現在、C#、F#、Scalaなどの「ハイブリッド」言語を使用しています。ドメインオブジェクトに対応するクラスを使用してアプリケーションを設計し、これによりコーディングがより簡単に、より正確に、より安全になる機能機能を使用します(特にコレクションの操作時または関数の受け渡し時)。 ただし、パターンを設計する場合、2つの世界は「衝突」します。私が最近直面した具体的な例は、Observerパターンです。アイテムが作成または変更されたときに、プロデューサーに他のコード(「消費者/オブザーバー」、たとえばDBストレージ、ロガーなど)に通知してほしい。 私は最初に次のように「機能的に」それをしました: producer.foo(item => { updateItemInDb(item); insertLog(item) }) // calls the function passed as argument as an item is processed しかし、私は今、もっと「OO」アプローチを使用すべきかどうか疑問に思っています。 interface IItemObserver { onNotify(Item) } class DBObserver : IItemObserver ... class LogObserver: IItemObserver ... producer.addObserver(new DBObserver) producer.addObserver(new LogObserver) producer.foo() //calls observer in a loop 2つのアプローチの長所と短所はどれですか?かつてFPの第一人者が、デザインパターンは言語の制限のためだけにあると言ったことを聞いたことがあり、それが関数型言語にはほとんどない理由です。たぶん、これはその例でしょうか? 編集:私の特定のシナリオでは、私はそれを必要としませんが、..機能的な方法で「観測者」の削除と追加をどのように実装しますか?(つまり、パターンのすべての機能をどのように実装しますか?)たとえば、新しい関数を渡すだけですか?

9
ソリッドメソッドと静的メソッド
私がよく遭遇する問題は次のとおりです。Productクラスを持つWebショッププロジェクトがあるとします。ユーザーが製品にレビューを投稿できる機能を追加したい。そのため、製品を参照するレビュークラスがあります。次に、製品に対するすべてのレビューをリストする方法が必要です。2つの可能性があります。 (A) public class Product { ... public Collection<Review> getReviews() {...} } (B) public class Review { ... static public Collection<Review> forProduct( Product product ) {...} } コードを見て、(A)を選択します:静的ではなく、パラメーターを必要としません。ただし、(A)は単一責任原則(SRP)およびオープンクローズド原則(OCP)に違反しているのに対し、(B)はそうではないと感じています。 (SRP)製品のレビューの収集方法を変更する場合、製品クラスを変更する必要があります。ただし、Productクラスを変更する理由は1つだけです。そして、それは確かにレビューではありません。Productの製品と関係のあるすべての機能をパックすると、すぐに散らかってしまいます。 (OCP)Productクラスを変更して、この機能で拡張する必要があります。これは原則の「変更のために閉鎖」部分に違反すると思います。レビューを実施するという顧客の要求を得る前に、私は製品が完成したと考え、それを「クローズ」しました。 より重要なことは、SOLID原則に従うか、よりシンプルなインターフェイスを使用するかです。 それとも私はここで何か間違ったことをしていますか? 結果 素晴らしい答えをありがとう 公式の回答として選ぶのは難しいです。 答えから主な議論を要約しましょう: pro(A):OCPは法律ではなく、コードの可読性も重要です。 pro(A):エンティティの関係はナビゲート可能でなければなりません。両方のクラスがこの関係について知っている場合があります。 pro(A)+(B):両方を行い、(A)から(B)に委任するため、製品が再び変更される可能性は低くなります。 pro(C):finderメソッドを静的でない第3クラス(サービス)に配置します。 コントラ(B):テストのモックを妨げます。 私の職場の大学が貢献したいくつかの追加事項: pro(B):ORMフレームワークは(B)のコードを自動的に生成できます。 pro(A):ORMフレームワークの技術的な理由により、ファインダーの行き先とは無関係に、「閉じた」エンティティを変更する必要がある場合があります。とにかく、私は常に固執することができるとは限りません。 コントラ(C):大騒ぎする;-) 結論 現在のプロジェクトでは、委任で(A)+(B)の両方を使用しています。ただし、サービス指向の環境では、(C)を使用します。

7
設計の観点から、ロギングのベストプラクティスは何ですか?[閉まっている]
閉じた。この質問はより集中する必要があります。現在、回答を受け付けていません。 この質問を改善したいですか?この投稿を編集するだけで1つの問題に焦点を当てるように質問を更新します。 6年前に閉鎖されました。 現在作業中のアプリケーションにロギングを追加したい。以前にロギングを追加しましたが、ここでは問題ではありません。 しかし、オブジェクト指向言語の設計の観点から、OOPとパターンに従うロギングのベストプラクティスは何ですか? 注:私は現在C#でこれを行っているので、C#の例は明らかに歓迎されています。また、JavaとRubyの例をご覧ください。 編集:私はlog4netを使用しています。プラグインするのに最適な方法がわからないだけです。

10
プロパティのポイントは何ですか?
プロパティと私の反論に対するいくつかの議論は次のとおりです。 getterおよびsetterメソッドを書くよりも使いやすい ゲッターメソッドとセッターメソッドのペアはコードのにおいです。これらの記述を簡単にすることは、Scantronフォームを使用してすべての「C」を入力することにより、数学テストに失敗しやすくするようなものです。永続化のために状態のみを含むオブジェクトは、getter / setterを使用してはならず、永続化時に不変オブジェクトを作成する必要があります。 オブジェクトのコンシューマーにとって重要なのは、オブジェクトが行う方法ではなく、オブジェクトが行うことです。その振る舞いはそれがすることです。その状態は、その方法です。オブジェクトの状態を気にかけている場合(永続性を除き、これもオブジェクト指向を破壊します)、OOPを実行せず、その利点を失います。 彼らは消費者にパフォーマンスの大まかな指標を与えます これは、特定のプロパティについて、将来変更される可能性があるものです。リリース1.0で、PropertyXにアクセスするとフィールドが返されるだけだとします。リリース1.5では、フィールドがnullの場合、PropertyXはNull Objectパターンを使用して新しいnullオブジェクトを作成します。リリース2.0では、PropertyXのgetterメソッドによってフィールドがさらに検証されています。 プロパティがますます複雑になるにつれて、プロパティを使用することによるパフォーマンスの指標はますます真実になりそうです。 パブリックフィールドよりも優れている これは本当です。しかし、メソッドもそうです。 これらはメソッドとは根本的に異なるオブジェクトの側面を表し、オブジェクトのすべてのコンシューマーはこれに注意する必要があります 上記のステートメントの両方が正しいと確信していますか? 入力しやすいです 確かに、タイピングmyObject.Lengthはタイピングよりも簡単ですがmyObject.Length()、それを少しの構文糖で修正することはできませんか? プロパティの代わりにメソッドを使用する理由 パフォーマンスの保証はありません。メソッドがより複雑になっても、APIは真実のままです。消費者は、パフォーマンスの問題に直面している場合、コードをプロファイルする必要があり、APIに依存しません。 消費者が考えることは少なくなります。このプロパティにはセッターがありますか?メソッドは確かにそうではありません。 消費者は適切なOOPの考え方から考えています。APIのコンシューマーとして、オブジェクトの動作と対話することに興味があります。APIでプロパティを見ると、状態によく似ています。実際、プロパティの実行が多すぎる場合は、プロパティであってはなりません。したがって、実際には、APIのプロパティはコンシューマに表示される状態です。 APIのプログラマは、戻り値を持つメソッドについてより深く考え、可能であれば、そのようなメソッドでオブジェクトの状態を変更することを避けます。可能な限り、コマンドをクエリから分離する必要があります。 それでは、なぜメソッドの代わりにプロパティを使用するのですか?MSDNのほとんどのポイントは、それ自体がコードの匂いであり、プロパティにもメソッドにも属していません。 (CQSについて考えた後、これらの考えが浮かびました。)

2
オブジェクト指向の遅延バインディング
ではオブジェクト指向のアラン・ケイズ定義が部分的に私は理解していないことを、この定義は次のとおりです。 私にとってOOPとは、メッセージング、ローカルでの保持と状態プロセスの保護と非表示、およびすべてのものの極端なLateBindingのみを意味します。 しかし、「LateBinding」とはどういう意味ですか?これをC#などの言語に適用するにはどうすればよいですか?そして、なぜこれがそれほど重要なのでしょうか?

5
Entity Frameworkによるドメイン駆動設計の落とし穴
私が研究したDDDに関するチュートリアルの多くは、主に理論をカバーしています。それらはすべて基本的なコード例(Pluralsightなど)を持っています。 Webでは、EFを使用したDDDをカバーするチュートリアルを作成しようとする試みも数人います。それらをほんの少しだけ調べ始めると、それらは互いに大きく異なることにすぐに気づきます。一部の人々は、アプリを最小限に保ち、追加のレイヤー(EFの上にリポジトリなど)を導入することを避けることを推奨します。他の人々は、追加のレイヤーを決定的に生成し、多くの場合、DbContext集約ルートに注入することによってSRPに違反します。 私が意見に基づく質問をしている場合、私はひどくお詫びしますが... 実践に関しては、Entity Frameworkは最も強力で広く使用されているORMの1つです。残念ながら、DDDに関する包括的なコースは見つかりません。 重要な側面: Entity Frameworkは、UoW&リポジトリ(DbSet)をすぐに使用できるようにします EFでは、モデルにナビゲーションプロパティがあります EFでは、すべてのモデルが常にオフで使用できますDbContext(それらはとして表されますDbSet) 落とし穴: あなたがすることはできません、あなたのモデルは、ナビゲーションプロパティを持っており、それが彼らとのコールを変更することができます-あなたの子供のモデルのみ集約ルートを経由して影響を受けている保証しますdbContext.SaveChanges() でDbContext、あなたはこのように、あなたのすべてのモデルにアクセスすることができます回避集約ルートを あなたは、経由ルートオブジェクトの子へのアクセスを制限することができますModelBuilderでのOnModelCreating法分野としてそれらをマークすることにより、(私はまだそれがDDDについて移動する正しい方法だとは思わないそれに加えて、これは将来的ににつながる可能性の冒険の種類何を評価するのは難しい- 非常に懐疑的) 矛盾: Aggregateを返すリポジトリの別のレイヤーを実装しないと、上記の落とし穴を部分的に解決することさえできません リポジトリーの追加レイヤーを実装することにより、EFの組み込み機能(すべてDbSetがすでにレポです)を無視し、アプリを複雑にします。 私の結論: 私の無知を許してください、しかし上記の情報に基づいてください-それはエンティティフレームワークがドメイン駆動設計に適切でないか、ドメイン駆動設計が不完全で時代遅れのアプローチであるかのいずれかです。 それぞれのアプローチにはメリットがあると思いますが、私は今完全に道に迷っており、EFとDDDをどのように調整するかについて少し考えていません。 私が間違っている場合-EFでDDDを実行する方法の簡単な一連の手順を詳細に説明できますか(または適切なコード例を提供できますか)。

4
クラス重複パターン?
私は現在、現在のプロジェクトでソロ開発者として働いています。私は別の開発者からプロジェクトを引き継ぎました。これは、C#のモデルビューコントローラースタイルのWebアプリケーションです。オブジェクトリレーショナルマッピングにEntity Frameworkを使用します。また、ドメインモデルの型には、2つの異なるクラスセットがあります。1つのセットはORMとの対話に使用され、もう1つのセットはMVCシステムのモデルとして使用されます。たとえば、次の2つのクラスがあるとします。 public class Order{ int ID{get;set;} String Customer{get;set;} DateTime DeliveryDate{get;set;} String Description{get;set;} } そして public class OrderModel{ String Customer{get;set;} DateTime DeliveryDate{get;set;} String Description{get;set;} public OrderModel( Order from){ this.Customer= from.Customer; // copy all the properties over individually } public Order ToOrder(){ Order result =new Order(); result.Customer = this.Customer; // copy …

5
一連の操作に最適なOOP設計パターン
私はアプリケーションに取り組んでおり、そのモジュールは次の財務操作を順番に実行します。 ユーザーが特定の金額を自分の銀行口座に送金するように要求した場合: トランザクションが発生するかどうかを確認しますか?(一定期間のみ取引可能) ユーザーが最小金額の引き出しを要求しているかどうかを確認します ユーザーがデフォルトのアカウントを持っているかどうかを確認します 上記のすべてのアクションの結果がログに記録されます。 上記の条件をすべて満たしている場合、トランザクションが実行されます。将来的には、いくつかのチェックが追加される可能性があります。 上記のケースに最適なオブジェクト指向のデザインパターンはどれですか。

4
「時期尚早の抽象化」とは何ですか?
私はフレーズが乱れているのを聞いたし、私には議論が完全に正気ではないように聞こえます(ここでわざわざ言っているとすみません、それは私の意図ではありません)。 一般的なケースがわかる前に抽象化を作成したくない場合は、(1)属していないものを抽象化に入れるか、(2)重要なものを省略します。 (1)私にはこれはプログラマーが十分に実用的ではないように聞こえます、彼らは最終的なプログラムには存在しないものがあると仮定しているので、抽象化のレベルが低い状態で作業していますが、問題はありません時期尚早な抽象化、それは時期尚早な結着です。 (2)重要なことの省略は1つです。後で重要になることが仕様から省略されている可能性があります。これに対する解決策は、独自の結論を導き出してリソースを無駄にすることではありません。間違っていると思います、それはクライアントからより多くの情報を取得することです。 これは、抽象化から具体化に至るまで常に作業する必要があります。これは、最も実用的な方法であり、その逆ではないためです。 そうしないと、クライアントを誤解し、変更が必要なものを作成するリスクがありますが、クライアントが独自の言語で定義した抽象化のみを構築する場合は、このリスクにぶつかることはありません(少なくとも、いくつかの具体的な暗闇の中でのショット)、はい、クライアントは詳細について考えを変える可能性がありますが、本来彼らが望むものを伝えるために使用していた抽象化は依然として有効である傾向があります。 以下に例を示します。クライアントがアイテムバギングロボットの作成を希望しているとします。 public abstract class BaggingRobot() { private Collection<Item> items; public abstract void bag(Item item); } 私たちは、クライアントが使用した抽象化から何かを構築していますが、わからないことについては詳しく説明していません。これは非常に柔軟性があり、「時期尚早な抽象化」と呼ばれるのを見てきましたが、実際にはバギングがどのように実装されたかを想定するのは時期尚早です。複数のアイテムを一度にバギングすることをクライアントと話し合った後、 。クラスを更新するために必要なのはシグネチャを変更することだけですが、ボトムアップを始めた人にとっては、大規模なシステムのオーバーホールが必要になる可能性があります。 時期尚早な抽象化などはなく、時期尚早な結集だけです。このステートメントの何が問題になっていますか?私の推論のどこに欠陥がありますか?ありがとう。

2
ビジネスロジックをサービスレイヤーに移動せずに、ドメインオブジェクト属性の一意の制約を確認するための洗練された方法はありますか?
私はドメイン駆動設計を約8年間適応してきましたが、これらすべての年が経過した後でも、まだ1つ問題があります。それは、ドメインオブジェクトに対してデータストレージ内の一意のレコードをチェックしています。 2013年9月、Martin Fowlerは、可能であればすべてのドメインオブジェクトに適用する必要があるTellDon'tAsk原則について言及し、操作がどのように行われたかをメッセージで返します(オブジェクト指向の設計では、これはほとんど例外によって行われます)。操作は失敗しました)。 私のプロジェクトは通常多くの部分に分かれており、そのうちの2つはドメイン(ビジネスルールのみを含み、ドメインは完全に永続性を無視する)とサービスです。データをCRUDするために使用されるリポジトリレイヤーを認識するサービス。 オブジェクトに属している属性の一意性はドメイン/ビジネスルールであるため、ドメインモジュールにとっては長くなければならないため、ルールは本来あるべき場所にあります。 レコードの一意性を確認できるようにするには、現在のデータセット(通常はデータベース)にクエリを実行して、別のレコードNameが存在するかどうかを確認する必要があります。 ドメインレイヤーは永続性を無視しており、データを取得する方法がわからないだけでなく、データを操作する方法しか考慮していないため、リポジトリ自体に直接触れることはできません。 私が適応させたデザインは次のようになります。 class ProductRepository { // throws Repository.RecordNotFoundException public Product GetBySKU(string sku); } class ProductCrudService { private ProductRepository pr; public ProductCrudService(ProductRepository repository) { pr = repository; } public void SaveProduct(Domain.Product product) { try { pr.GetBySKU(product.SKU); throw Service.ProductWithSKUAlreadyExistsException("msg"); } catch (Repository.RecordNotFoundException e) { // suppress/log …

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