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

設計パターンは、ソフトウェア設計で一般的に発生する問題に対する一般的な再利用可能なソリューションです。

5
ベストプラクティス-関数呼び出しの周りをラップするvs関数内でガードする場合は早期終了を追加する
これは非常にユースケース固有のものになる可能性があることは知っていますが、私はあまりにも頻繁にこれに疑問を感じています。一般的に推奨される構文はありますか? 私は関数の中で最善の方法を尋ねているのではなく、早く終了するか、関数を呼び出さないかを尋ねています。 関数呼び出しの周りをラップする if (shouldThisRun) { runFunction(); } 持っている場合(ガード)機能で runFunction() { if (!shouldThisRun) return; } 後者のオプションは、この関数が複数回呼び出された場合にコードの重複を減らす可能性があることは明らかですが、関数の単一の責任性を失う可能性があるため、ここに追加すると間違っていると感じる場合があります。 例はこちら 何かのステータスを更新するupdateStatus()関数がある場合。ステータスが変更された場合にのみステータスを更新します。ステータスが変更される可能性があるコード内の場所を知っています。 私だけかどうかはわかりませんが、この関数をできるだけ純粋にしたいので、この内部関数をチェックするのは少し汚れています。これを呼び出すと、ステータスが更新されることが期待されます。しかし、変更を加えていない可能性があることがわかっているいくつかの場所で、呼び出しをチェックでラップする方がよいかどうかはわかりません。

2
リポジトリパターンとDALオブジェクトの作成
私が学んだ限り、にはIRepositoryが含まれている必要がありますCRUD。その後、我々はこれを継承するIRepositoryような当社の他のインターフェイスにIProductして実装するIProduct具象クラスをProductRepository、などの方法でGetAllProducts()、Top5Products()。 n層アーキテクチャでも同じことができます。作成、のようにDAL Class Library、そこにクラスを定義するProductような方法でGetAllProducts()、Top5Products()。 両方において、DAL.ProductそしてRepo.ProductRepository、我々は初期化したクラスDB ContextでEntity Framework、当社の関連データを照会します。 呼び出しは両方Repo.ProductRepositoryまたはDAL.Productメソッドから似ていますBLL これらの類似点を考慮して、私の質問はレポの利点は何ですか?私はn層アーキテクチャを使用して非常に簡単に同じことを行うことができます(Controller、BLL Class Library、DAL Class Library)。

3
値で渡されるパラメーターの値を変更しない理由はありますか?
関数の本体にある値渡しパラメーターの値を変更することに対する、またはそれに対する反対の客観的でサポート可能なソフトウェアエンジニアリングの引数はありますか? 私のチームで繰り返されるスパッツ(大部分はおもしろい)は、値によって渡されるパラメーターを変更する必要があるかどうかです。チームのいくつかのメンバーは、パラメーターを決して割り当ててはならないことに固執しているため、最初に関数に渡された値を常に問い合わせることができます。パラメータは、メソッドを呼び出す構文によって初期化されたローカル変数に過ぎないと私は同意しません。値渡しパラメーターの元の値が重要な場合は、ローカル変数を宣言してこの値を明示的に格納できます。私たちのどちらかが私たちの立場を非常によくサポートしているとは確信していません。 これは解決できない宗教的紛争ですか、それともどちらの方向にも客観的なソフトウェアエンジニアリング上の理由がありますか? 注:原則の問題は、特定の言語の実装の詳細に関係なく残っています。たとえば、JavaScriptの場合、引数リストは常に動的であり、パラメーターはargumentsオブジェクトからのローカル変数初期化の構文糖と見なすことができます。それでも、呼び出し元から呼び出し先への情報の受け渡しをキャプチャするため、パラメータ宣言された識別子を「特別」として扱うことができます。

1
パターンはビルディングブロックではないので、MVC / MVPパターンでアプリを構築すべきではありませんか?
私が読んだ本のデザインパターンについてのページを、そしてあなたのコードを書くときに、どのようにそれらを扱う必要があります。私の理解から、リンクのタイトルは次のように述べています: パターンはビルディングブロックではありません。 私が正しく理解していれば、これは意味があるまでデザインパターンを使用しないことを意味しますよね?戦略パターンを使用するつもりだと言って始めないでください。コードを書くまで待ってください。戦略パターンを使用することが設計に意味がある場合は、それを使用してください。 GUIアプリケーションを作成するとき、MCV / MVPパターンを同じように扱いますか?それぞれのリンクから、それは建築パターンであると述べています。 GUIアプリケーションを作成し、MCV / MVPパターンを使用していなくても、コードがクリーンで、読みやすく、保守可能である場合、MCV / MVPパターンを使用しなかったのは、コードのにおい/悪い設計であると想定します。 ?

7
ウィザードとウォリアーのルールを回避する
でブログ記事のこのシリーズ、エリックリッペルトは、ウィザードとの例として、戦士を使用して、オブジェクト指向設計における問題点を説明します。 abstract class Weapon { } sealed class Staff : Weapon { } sealed class Sword : Weapon { } abstract class Player { public Weapon Weapon { get; set; } } sealed class Wizard : Player { } sealed class Warrior : Player { } 次に、いくつかのルールを追加します。 戦士は剣しか使用できません。 ウィザードはスタッフのみを使用できます。 次に、C#型システムを使用してこれらのルールを適用しようとすると発生する問題(たとえばWizard、ウィザードがスタッフのみを使用できることをクラスに責任を持たせるなど)を示します。Liskov置換原則に違反したり、ランタイム例外のリスクを冒したり、拡張が困難なコードを作成したりする。 …

3
ヘルパースタイルの「ユーティリティバッグ」静的クラスを回避し、「フリー関数」をクリーンに処理するC#パターン
最近、私が使用するいくつかの大きなC#コードベースの周りに浮かぶいくつかのヘルパースタイルの「ユーティリティバッグ」静的クラスを確認していました。 // Helpers.cs public static class Helpers { public static void DoSomething() {} public static void DoSomethingElse() {} } 私がレビューした特定の方法は 主に互いに無関係です 呼び出し間で持続する明示的な状態なしで、 小さい、そして それぞれが、関連のないさまざまなタイプによって消費されます。 編集:上記は申し立てられた問題のリストを意図したものではありません。これは、私が検討している特定のメソッドの一般的な特性のリストです。回答がより関連性の高いソリューションを提供するのに役立つコンテキストです。 この質問のためだけに、この種のメソッドをGLUM(一般的な軽量ユーティリティメソッド)と呼びます。「glum」の否定的な意味合いは部分的に意図されています。これが馬鹿げた言い回しとして出くわしたらすみません。 GLUMについての私自身のデフォルトの懐疑論はさておき、私はこれについて以下のことを好きではありません。 静的クラスは名前空間としてのみ使用されています。 静的クラス識別子は基本的に無意味です。 新しいGLUMが追加されると、(a)この「バッグ」クラスは理由もなく触れられるか、または(b)新しい「バッグ」クラスが作成されます(通常、それ自体は問題ではありません。悪いのは、新しい静的クラスは多くの場合、無関係な問題を繰り返すだけですが、メソッド数は少なくなります)。 メタ命名は、それはだかどうか、必然的に、ひどい非標準、通常は内部的に矛盾しているHelpers、Utilitiesまたは何でも。 これをリファクタリングするための合理的に良い&単純なパターンは何ですか? 私はおそらく強調する必要があります:私が扱っているすべての方法は、互いにペアで関係がありません。それらをよりきめ細かく、それでもマルチメンバーの静的クラスのメソッドバッグに分解するための合理的な方法はないようです。

3
ファイルの最初に、最後だけ知っているものを書き込む
背景: EBMLファイルを書き込むマイクロコントローラーCコードを書いています。EBMLは要素がネストされたバイナリXMLに似ていますが、開始タグと終了タグの代わりに、開始ID、長さ、そしてデータがあります。低電力アプリケーションの外部フラッシュにこれを書き込んでいるので、フラッシュアクセスを最小限に抑えたいと思います。決して簡単なことはないので、メモリも制限されます。 EBML要素全体をメモリに保持できる場合、その長さがわかったら、各要素の長さに戻って入力できるため、生成は簡単です。問題は、要素全体をメモリに保持できない場合の対処方法です。私が見るオプションは: 私が知っていることを書いてから、戻って長さを追加します(最も簡単ですが、必要以上にフラッシュアクセスを追加します) 書き始める前に各要素の長さを計算します(比較的簡単ですが、プロセッサ時間は長くなります) メモリがいっぱいになったらモードを切り替えて、データを調べ続けますが、すでにメモリに予約されている要素の長さを計算するだけです。次に、メモリにあるものを書き込み、戻って、中断したところからデータの処理を続けます。(これまでのところ私のお気に入りのオプション) 要素を書き込む必要があり、最終的な長さがまだわからない場合は、要素に最大または最悪の場合の長さを指定します。(上記より簡単ですが、裏目に出てスペースを無駄にする可能性があります) 質問:これは、人々が考えていた比較的一般的な問題であるように思われます。一部のデータパケットを形成するときにも発生する可能性があることを知っています。私がここで見逃している/より一般的/より受け入れられたより良いテクニックはありますか?または、私が検索できる問題のいくつかの用語?

4
複雑なドメイン中心のアプリケーションでの基本的なCRUD操作へのDDDアプローチ
私の会社はWebアプリケーションをゼロから書き直しています。これは、金融業界で複雑なドメインを持つ大規模なエンタープライズレベルのアプリケーションです。 永続化のためにORM(エンティティフレームワーク)を使用しています。 本質的に、アプリケーションの半分はユーザーから生データを収集して保存することに集中しており、実際のドメインロジックのほとんどを含むアプリケーションの残りの半分はその生データを使用して、元のデータとは大きく異なるドメイン画像を作成します生の入力、およびそれを計算エンジンに渡し、計算を実行し、結果を吐き出し、ユーザーに表示します。 レイヤーを使用したDDDアプローチでは、CRUD操作がドメインレイヤーを通過するように見えます。しかし、少なくとも私たちの場合、これは意味をなさないようです。 たとえば、ユーザーが編集画面に移動して投資口座を変更した場合、画面のフィールドはデータベースに保存されているフィールドそのものであり、後で計算に使用されるドメイン表現ではありません。では、編集画面でデータベース表現(生の入力)が必要なときに、なぜ投資口座のドメイン表現を読み込むのでしょうか。 ユーザーが投資口座画面で[完了]をクリックし、コントローラーに対してPOSTが実行されると、コントローラーには、保存する必要のある投資口座のほぼ正確なデータベース表現が表示されます。しかし、何らかの理由で、コントローラーのモデルをデータベースモデル(エンティティフレームワークモデル)に直接マッピングするのではなく、ドメイン表現をロードして変更を加えることになっていますか? つまり、本質的には、データモデルをドメインモデルにマッピングします。これにより、永続化するためにデータモデルにマッピングし直すことができます。それはどういう意味ですか?

1
ビジネスロジックとサービスレイヤー
私はこの答えを読みます:https : //softwareengineering.stackexchange.com/a/234254/173318私の理解を訂正してください。 ビジネスルールとは、現実の世界でのビジネスのステップのリストを指します(コードなし)。 ビジネスロジックは、ビジネスルールをコードに変換するプロセスと、「ビジネスロジック」と呼ばれるこれらのコードの束/種類を指します。 また、サービス層は何に使用されますか?私がこの答えを読んだ場合、それはビジネスロジックと同じように聞こえますhttps://stackoverflow.com/a/4817935/4190539 サービスレイヤーは、ビジネスロジックとリポジトリが出会う場所ですか?

2
イテレーターをデザインパターンにする理由
他の同様の構成と比較してIteratorが特別になるのは何だろうと思っていました。そのため、Gang of Fourがデザインパターンとしてリストされています。 イテレーターは、ポリモーフィズム(共通のインターフェースを持つコレクションの階層)と懸念の分離(コレクションの反復は、データの構造化方法から独立している必要があります)に基づいています。 しかし、コレクションの階層を、たとえば数学オブジェクト(整数、浮動小数点数、複素数、行列など)の階層と反復子を、これらのオブジェクトの関連するいくつかの操作を表すクラス(例えば、指数関数)で置き換えるとどうなるでしょうか。クラス図も同じです。 同じように機能する、Writer、Painter、Encoderなどのより多くの類似の例、おそらくより優れた例を見つけることができます。しかし、これらがデザインパターンと呼ばれるのを聞いたことがありません。 では、イテレータが特別な理由は何ですか? コレクション内の現在の位置を格納するために変更可能な状態を必要とするため、より複雑になるのは事実ですか?しかし、その場合、変更可能な状態は通常望ましいとは見なされません。 私のポイントを明確にするために、より詳細な例を挙げましょう。 ここに私たちの設計問題があります: クラスの階層と、これらのクラスのオブジェクトに対して定義された操作があるとします。この操作のインターフェースは各クラスで同じですが、実装は完全に異なる場合があります。同じオブジェクトに複数の操作を適用すること、たとえば異なるパラメーターを使用することが理にかなっていることも想定されています。 これが私たちの設計問題(実際には反復子パターンの一般化)の賢明な解決策です: 懸念を分離するために、操作の実装を関数として元のクラス階層(オペランドオブジェクト)に追加しないでください。同じオペランドに操作を複数回適用する必要があるため、関数だけでなく、オペランドへの参照を保持するオブジェクトで表す必要があります。したがって、オペランドオブジェクトは、演算を表すオブジェクトを返す関数を提供する必要があります。このオブジェクトは、実際の操作を実行する関数を提供します。 例: MathObject派生クラスMyIntegerとを備えた基本クラスまたはインターフェイス(愚かな名前です。たぶん誰かがより良いアイデアを持っています。)がありMyMatrixます。それぞれについて、正方形、立方体などの計算を可能にMathObjectする操作Powerを定義する必要があります。だから私たちは(Javaで)書くことができました: MathObject i = new MyInteger(5); Power powerOfFive = i.getPower(); MyInteger square = powerOfFive.calculate(2); // should return 25 MyInteger cube = powerOfFive.calculate(3); // should return 125

4
境界付きコンテキストの境界を明確に定義する方法
1か月ほどDDDを読んで調査した後、私は自分のプロジェクトを開始することを決め、これらの制限されたコンテキストでDDDを作成しました> クライアント 製品 注文 課金 各境界付きコンテキストには、プレゼンテーション層、ドメイン層、永続層としてREST APIがあります。 これまでのところ、コードはスムーズに実行されていますが、モノリシックな世界から来ているので、私はまだ次のことを理解しようとしています: 新しいクライアントを作成したい場合、新しい請求書を発行したい場合、たとえば、国のアクセスリストなど、新しい注文を作成したい場合。私は: a)各BCの国のリストを作成する b)国BC-> APIを作成し、それを使用して利用可能な国のリストを取得する c)サードパーティのAPIを使用し、各BCの腐敗防止層を介してデータをプルする 破損防止レイヤーまたはアダプターレイヤーを使用してサードパーティAPIと統合する場合、ドメインモデルにどのデータを含める必要がありますか?たとえば、zendesk APIをクライアントBCと統合したい場合。ドメインにticketIDのみが必要ですか、それともクライアントBCでアクセスして使用するすべてのデータをZendeskから抽出する必要がありますか? MVCアプリが実際にAPI(境界コンテキストのプレゼンテーションレイヤー)からデータを取得している場合、各BCの境界を明確に定義することは非常に困難です。それは、適切に設計されたBCが、追加のAPIを消費する必要なしに単一のMVCコントローラーを提供することを意味しますか?

2
オブザーバーパターンは、オブザーバーが互いに独立していない場合に適していますか?
私class Carは2つのプロパティを持つを持っています:int priceとboolean inStock。またList、abstract class State(空のクラス)も保持します。車に適用できる2つの状態があり、それぞれが独自のクラスで表されます:class Upgrade extends Stateおよびclass Shipping extends State。 A Carは、2つの状態をそれぞれいくつでも保持できます。州には次の規則があります。 Upgrade:1自動車自体に適用される各状態の価格に追加されます。 Shipping:Shippingリストに少なくとも1つの状態がある場合、inStockに設定されfalseます。 たとえば、始まるprice = 1とinStock = true: add Shipping s1 --> price: 1, inStock: false add Upgrade g1 --> price: 1, inStock: false add Shipping s2 --> price: 2, inStock: false add Shipping s3 --> price: …

1
コマンドオブジェクトを適切なレシーバーに関連付けるにはどうすればよいですか?
プロジェクトに元に戻すとやり直しを実装するためにコマンドパターンを使用しようとしました public abstract class Command { protected Form Receiver { set; get; } protected HtmlElement Element { set; get; } abstract public void ReDo(); abstract public void UnDo(); public Command(Form receiver) { this.Receiver = receiver; } } class AddElementCmd : Command { public AddElementCmd(HtmlElement elem, Form receiver) : base(receiver) { …

1
イベントソーシングは、書き込みがまれな場合のみですか?
私はイベントソーシングについて読んでいて、書き込みが非常にまれであるか、軍事レベルの監査が必要なエキゾチックな状況でのみ意味があるかどうかを自問するのをやめられません。 重要な使用法がある例外的ではないシステムでは、1日あたり数百から数千の書き込みが発生する可能性があり、たとえば、1年間の操作で100万回または2回の書き込み(つまりイベント)に変換されます。現在の状態を取得するためだけに数百万のオブジェクト(イベント)をマージすることは、従来のストレージからのまっすぐな読み取りと比較すると、ばかげた命題のように聞こえます。それでも、イベントソーシングは、最もパフォーマンスの高いシステムの背後にあります(LMAXなど)。 それで、私は何が欠けていますか?イベントストリームからの状態の復元は一般的に行われていますか?または、これを行う必要がほとんどなく、代わりに通常の操作(つまり、CQRSからのクエリストレージを使用)に別のストレージを使用し、例外的な場合(レプリケーション、監査など)にのみイベントから復元するという考えですか?

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

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