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

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

5
変更された戦略設計パターン
私は最近、デザインパターンの調査を開始しましたが、コーディングしていることの1つは、小さな違いを除いて、戦略パターンに完全に適合します。 基本的に、私のアルゴリズムの一部(すべてではない)には、追加のパラメーターまたは2つを渡す必要があります。 だから私はどちらかをする必要があります 計算メソッドを呼び出すときに追加のパラメーターを渡します または それらをConcreteAlgorithmクラス内の変数として保存し、アルゴリズムを呼び出す前にそれらを更新できるようにします。 このニーズに合ったデザインパターンはありますか/戦略パターンにこだわってこれを実装するにはどうすればよいですか? クライアントオブジェクトをすべてのアルゴリズムに渡し、変数をそこに格納し、特定のアルゴリズムで必要な場合にのみ使用することを検討しました。しかし、これは扱いにくく、戦略パターンのポイントを打ち負かすと思います。 明確にするために、私はJavaで実装しているので、オプションのパラメーター(これをうまく解決できる)の贅沢はありません。

5
オープンクローズド原則の利点を活用していますか?
Open-Closed Principle(OCP)は、オブジェクトは拡張のために開かれ、修正のために閉じられるべきであると述べています。私はそれを理解し、SRPと組み合わせて使用​​して、たった1つのことを行うクラスを作成すると信じています。そして、すべての動作コントロールをサブクラスで拡張またはオーバーライドできるメソッドに抽出できるようにする多くの小さなメソッドを作成しようとしています。したがって、依存関係の注入と構成、イベント、委任など、多くの拡張ポイントを持つクラスになります。 次の単純で拡張可能なクラスを考えてください。 class PaycheckCalculator { // ... protected decimal GetOvertimeFactor() { return 2.0M; } } たとえば、OvertimeFactor1.5に変更するとします。上記のクラスは拡張するように設計されているため、簡単にサブクラス化して別のを返すことができますOvertimeFactor。 しかし ... ...クラスは拡張用に設計され、OCPに準拠していますが、問題のメソッドをサブクラス化およびオーバーライドしてからIoCコンテナー内のオブジェクトを再配線するのではなく、問題のメソッドを変更します。 その結果、OCPが達成しようとしていることの一部に違反しました。上記の方法は少し簡単なので、怠けているように感じます。OCPを誤解していますか?私は本当に何か違うことをするべきですか?OCPのメリットをさまざまに活用していますか? 更新:回答に基づいて、この人為的な例は、いくつかの異なる理由で貧弱な例のように見えます。この例の主な目的は、オーバーライドされると、内部コードまたはプライベートコードを変更せずにパブリックメソッドの動作を変更するメソッドを提供することにより、クラスが拡張されるように設計されたことを示すことでした。それでも、私は間違いなくOCPを誤解していました。

2
Static Createメソッド—コンストラクターと比較した賛否両論
コンストラクターに対して静的オブジェクト作成メソッドを使用することの長所と短所は何ですか? class Foo { private Foo(object arg) { } public static Foo Create(object arg) { if (!ValidateParam(arg)) { return null; } return new Foo(arg); } } 私が考えることができることはほとんどありません: 長所: 例外をスローする代わりにnullを返します(名前を付けますTryCreate)。これにより、クライアント側でコードがより簡潔でクリーンになります。クライアントがコンストラクターの失敗を期待することはほとんどありません。 明確なセマンティクスでさまざまな種類のオブジェクトを作成します。たとえばCreatFromName(String name)、CreateFromCsvLine(String csvLine) 必要に応じて、キャッシュされたオブジェクト、または派生した実装を返すことができます。 短所: 発見しにくく、コードのスキミングがより困難です。 シリアル化やリフレクションなどの一部のパターンはより困難です(例Activator<Foo>.CreateInstance())

4
サービスをラップして簡単にする方法
私たちは、3つのメソッドのように必要なだけの巨大なインターフェースを公開するサードパーティのサービスに依存しています。さらに、インターフェースは頻繁に変更されます... プロジェクトのクラスにインターフェイスをラップし、必要なメソッドのみを公開することにしました。 しかし、私は戻り値をどのように処理するべきかわかりません...インターフェイスは型のオブジェクトを返しますStorage。内部StorageModelには、の内部表現であるタイプがありますStorage。 マッパーで何を返しますか:StorageまたはStorageModel?StorageService挿入されたラッパーの依存関係を取得するDataServiceがあります。 現在、私は基本的に次のようにしています: public class StorageService { private readonly IExternalStorageWrapper externalStorageWrapper; public StorageService(IExternalStorageWrapper externalStorageWrapper) { this.externalStorageWrapper = externalStorageWrapper; } public StorageModel GetStorage(int storageId) { return this.externalStorageWrapper.GetStorage(storageId).ConvertToStorageModel(); } } public class ExternalStorageWrapper : IExternalStorageWrapper { public Storage GetStorage(int storageId) { using(var ext = new ExternalStorage()) { return ext.GetStorage(storageId); } …

2
データベースサービス関数を呼び出すアプリケーションサービス層。悪いアーキテクチャ?
シナリオ: スタック:Java、Spring、Hibernate。 モデル:クライアントサーバーアプリケーション。 パターン:Model-View-Controller(MVC)。 サービス層クラスには3つの動作があります。 一部のサービスには、メソッド内にビジネスルールがあり、永続性をアプリケーションに委任します。お気に入り: EntityManager.save(entity); 一部のサービスは、単純にデータベース関数(パラメーターを渡す)を呼び出します。 CallableStatement cls = con.prepareCall( "{call databaseFunction(args)}"); 一部のサービスには、両方の動作を持つメソッドがあります。 私の質問: アプリケーションサービスに直接データベース機能を呼び出しても問題はありませんか?これは悪い習慣ではありませんか?このようなプロジェクトに適用できるアーキテクチャモデルは何でしょうか? 同じサービスで動作が混在することに問題はありますか?トランザクションや一貫性など? メンテナンスの場合、このカプセル化により、開発者はデータベースの機能も変更する必要があることがわかりにくくなりますか?これを回避するには? このシナリオは世界中の他のアプリケーションで発生しますか、それとも単なるアーキテクチャ上のエラーですか?

1
制御の反転は依存関係の反転とどのように関連していますか
Web上の多くの記事では、制御の反転と依存関係の反転の原則という用語が混同され、同義語として使用されているように見えます(さらに混乱は、「DIコンテナー」と「IoCコンテナー」と呼ばれるツールによって強制されます)。ウィキペディアの記事は、IoCがDIと同じではないことを説明しようとする素晴らしい仕事をしています。 制御の反転(IoC)は、コンピュータープログラムのカスタム記述部分が汎用の再利用可能なライブラリから制御のフローを受け取る設計を表します したがって、DIPは、モジュールを具体的な実装ではなく抽象化に依存させることです。 IoCは、プログラムフローを別のモジュールに制御することを目的としています。このモジュールで実行できることの1つは、実行時に依存関係を解決することです。 この違いは公平に思えますが、依存関係の解決以外のIoC原則の他のアプリケーションについて誰も言及していません。ウィキペディアの定義は非常に広範であり、その構成といくつかの内部ロジックに基づいてカスタムコードを呼び出すことができるモジュールを使用すると、さらに多くのことができるようです。 それで、私がまだまだ理解できないいくつかの質問があります: IoCとDIPの実際の関係は何ですか?IoCは常にDIPを実装する手段として機能しますか? 依存関係を解決するためのツールがDIコンテナーとIoCコンテナーの両方と呼ばれるのはなぜですか?これは、DIとIoCが同じものであることを意味します。 注:この質問はDIとIoCの違いは何ですか。後者は依存関係のインバージョンではなく、依存関係の注入について質問するためです。

2
.NET MVCプロジェクトアーキテクチャ/レイヤー
中規模のMVC Webアプリケーションのアーキテクチャを計画するとき、レイヤーを可能な限り分離してテストしやすいように実装するにはどうすればよいですか?(基本的にベストプラクティスに従います)データアクセスとして最初にコードを使用しているとしましょう。 「ビジネスロジック」の定義、およびデータレイヤーとのやり取りをどのように定義するかについて、私は苦労しています。車両販売アプリケーションを例にとると、ビジネスロジックは、特定の車両の税帯の計算、ガロンあたりのマイル統計の比較などのタスクを実行するクラスでしょうか。ビジネスエンティティ(例:車、バン、オートバイ)については、これらをDataContextクラスと共にデータレイヤーに配置します。 また、ビジネスとは対照的に、アプリケーションロジックを構成するものは何ですか。セッション/ユーザー入力の検証などを推測していますか? したがって、たとえば、車のコントローラは、タイプと最良のmpgでフィルタされた上位10台の車をリストするアクション/ビューの結果を返す場合があります。たとえば、ICarRepository「リポジトリ」/ DIを使用して「carRepo」をコントローラに注入したとします。アクションメソッドのパラメータから車をフィルタリングします。var cars = carRepo.getCarsByType("hatchback"); したがって、リポジトリを使用してデータアクセスの知識をコントローラーから除外し、ドメインモデルを使用してビジネスロジックをコントローラーから除外しました-var result = new MpgCalculator(cars); -DBからエンティティをロード/フィルタリングするだけではなく、最高の燃料効率を計算するために追加のロジックを実行する必要があるため、電卓クラスが必要だとしましょう。これで、ビューをレンダリングするためのデータセットがあり、リポジトリを使用してデータアクセスレイヤーから取得し、ドメイン固有のオブジェクトを処理して、そのデータに対してビジネス関連のタスクを実行します。 ここで間違いをしていますか?それでもリポジトリパターンを使用する必要がありますか、それともORMを分離してテストするためにインターフェイスに対してコーディングするだけですか?このトピックでは、具体的なデータアクセスクラスdbcontextがデータレイヤーにあるので、インターフェイス定義をドメイン/ビジネスレイヤーに入れる必要があります。つまり、データアクセステクノロジーが変更されても、他のレイヤーは影響を受けません。 これまでに調べたことから、私の構造は次のようになります。 MVCインターネットアプリケーション ->標準インターネットプロジェクト-ここのモデルはViewModelsです ドメイン/ビジネスレイヤー ->コントローラーが関連するビューに渡す前にデータレイヤーからドメインエンティティを処理するために使用できるビジネス固有のクラス/モデル リポジトリの抽象化が必要ですか?->特にORMを使用する場合、これについて多くの議論が聞こえます データレイヤー ->エンティティクラス(Car、Van、Motorcycle)、DbContext-具象データアクセステクノロジーレイヤー

6
SRPを実装する実際的な方法は何ですか?
クラスが単一責任の原則に違反しているかどうかを確認するために人々が使用する実用的なテクニックは何ですか? クラスには変更する理由が1つだけあるべきだと知っていますが、その文は実際にそれを実装する実用的な方法に少し欠けています。 私が見つけた唯一の方法は、「それは…………それ自体……」という文を使うことです。ここで、最初のスペースはクラス名で、後はメソッド(責任)名です。 ただし、責任が本当にSRPに違反しているかどうかを判断するのが難しい場合があります。 SRPを確認する方法は他にありますか? 注意: 問題は、SRPの意味ではなく、SRPを確認して実装するための実際的な方法論または一連の手順です。 更新 SRPに明らかに違反するサンプルクラスを追加しました。単一の責任の原則にどのように取り組むかを説明するための例として、人々がそれを使用できれば素晴らしいと思います。 例はここからです。

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を実行する方法の簡単な一連の手順を詳細に説明できますか(または適切なコード例を提供できますか)。

1
OOP ECSとPure ECS
まず、この質問はゲーム開発のトピックに関連していることを認識していますが、実際にはより一般的なソフトウェア生成問題に帰着するので、ここで質問することにしました。 過去1か月間に、Entity-Component-Systemsについてたくさん読んだので、今はその概念にとても慣れています。ただし、明確な「定義」が欠落しているように見える側面が1つあり、記事によって根本的に異なる解決策が提案されています。 これは、ECSがカプセル化を解除する必要があるかどうかの問題です。つまり、そのOOPスタイルのECS(コンポーネントは、それらに固有のデータをカプセル化する状態と動作の両方を持つオブジェクト)と純粋なECS(コンポーネントは、パブリックデータのみを持ち、システムが機能を提供するcスタイルの構造体)です。 フレームワーク/ API /エンジンを開発していることに注意してください。したがって、目標は、それを使用している人なら誰でも簡単に拡張できることです。これには、新しいタイプのレンダリングまたは衝突コンポーネントの追加などが含まれます。 OOPアプローチの問題 コンポーネントは他のコンポーネントのデータにアクセスする必要があります。たとえば、renderコンポーネントのdrawメソッドは、transformコンポーネントの位置にアクセスする必要があります。これにより、コードに依存関係が作成されます。 コンポーネントはポリモーフィックになる可能性があり、さらに複雑さをもたらします。たとえば、レンダーコンポーネントの仮想描画メソッドをオーバーライドするスプライトレンダーコンポーネントがある場合があります。 純粋なアプローチの問題 ポリモーフィックな動作(レンダリングなど)はどこかに実装する必要があるため、システムに外部委託するだけです。(たとえば、スプライトレンダーシステムは、レンダーノードを継承するスプライトレンダーノードを作成し、それをレンダーエンジンに追加します) システム間の通信は避けるのが難しい場合があります。たとえば、衝突システムには、そこにある具体的なレンダリングコンポーネントから計算される境界ボックスが必要な場合があります。これは、データを介して通信させることで解決できます。ただし、レンダリングシステムがバウンディングボックスコンポーネントを更新し、衝突システムがそれを使用するため、これによりインスタント更新が削除されます。システムの更新関数を呼び出す順序が定義されていないと、問題が発生する可能性があります。他のシステムがハンドラーをサブスクライブできるイベントをシステムが発生できるようにするイベントシステムがあります。ただし、これはシステムに何をすべきか、つまりvoid関数を伝える場合にのみ機能します。 追加のフラグが必要です。たとえば、タイルマップコンポーネントを見てみましょう。サイズ、タイルサイズ、インデックスリストフィールドがあります。タイルマップシステムは、それぞれの頂点配列を処理し、コンポーネントのデータに基づいてテクスチャ座標を割り当てます。ただし、フレームごとにタイルマップ全体を再計算するにはコストがかかります。したがって、システムでそれらを更新するために行われたすべての変更を追跡するために、リストが必要になります。OOPの方法では、これはタイルマップコンポーネントによってカプセル化できます。たとえば、SetTile()メソッドは、呼び出されるたびに頂点配列を更新します。 純粋なアプローチの美しさはわかりますが、従来のOOPよりも具体的にどのようなメリットがあるのか​​はよくわかりません。コンポーネント間の依存関係は、システムに隠されていますが、依然として存在しています。また、同じ目標を達成するには、さらに多くのクラスが必要になります。これは私には、決して良いことではない、やややりすぎたソリューションのように思えます。 さらに、私はパフォーマンスにそれほど関心がないので、データ指向の設計とキャッシュミスのこの全体的な考えは、私にはそれほど重要ではありません。素敵な建築物が欲しいだけです^^ それでも、私が読んだ記事や議論のほとんどは、2番目のアプローチを提案しています。どうして? アニメーション 最後に、純粋なECSでアニメーションをどのように処理するかについて質問したいと思います。現在、私はアニメーションを、0と1の間の進行状況に基づいてエンティティを操作するファンクタとして定義しています。アニメーションコンポーネントには、アニメーションのリストを持つアニメーターのリストがあります。次に、更新機能で、現在アクティブなアニメーションをエンティティに適用します。 注意: 私はこの投稿を読んだばかりですが、エンティティコンポーネントシステムアーキテクチャオブジェクトは定義によって指向されていますか?これは私よりも少し問題を説明します。基本的に同じトピックを扱っていますが、純粋なデータアプローチの方が優れている理由についてはまだ答えがありません。

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
ロギングを実行にラップするための設計パターン
前書き 処理フレームワークの抽象Javaクラスを実装しています*。関数を実装することでexecute、ビジネスの論理機能を追加することができます。すべての実行関数のすべての実装の最初と最後にロギングを追加したいと思います。また、特定の処理が行われた場合、ロギングの合間にも実行されます。でもこれを一律に作りたい。私の考えは、ロギングを実装executeWithLoggingし、特定の部分にロギングをラップするいくつかの新しい機能を提供する独自の新しいクラスにフレームワーククラスを継承することでした。それが最高のアイデアかどうか、全体がエレガントになるようなデザインパターンを使用できるかどうかはわかりません。全体をどうやって進めますか? 課題(これらを考慮してください!) 私の場合の1つの課題は、元のクラスには1つのexecute関数しかないということですが、複数の部分をログに記録する必要があります。 2つ目は次のとおりです。Decoratorパターンを使用して、私も使用している場合ではなく、かなりの仕事ん(だけでなく、私の最初のアイデアだった)executeので、super.execute()-functionは私の新しいの最初の行で呼び出さなければならないexecute()、そうではありません? 関連する少なくとも4つのクラスがあり、次のようになります。BaseFunctionフレームワークからLoggingFunction extends BaseFunction私から、MyBusinessFunction extends LoggingFunction私から、MyBusinessClassinstanciates MyBusinessFunction。 の最初と最後だけでなくexecute、途中でもロギングが必要です。 「ロギング」は単純なJavaロギングではなく、実際にはデータベースへのロギングです。これは原則については何も変更しませんが、ロギングが単なる1行のコードではない場合があることを示しています。 たぶん、私がすべてを行う方法の例は、私を動かすのにいいでしょう。 | *ストームトライデント関数。ストームボルトに似ていますが、これは特に重要ではありません。

1
Brendan Eichが引用したPeter Norvigの論文
私はCoders at Workを読んでいますが、Brendan EichはNorvigがHarlequinにいたときの「デザインパターンが実際にプログラミング言語の単なる欠陥である方法について」という論文を引用しています。 誰でもこのペーパーへのリンクを提供できますか?

4
関数を呼び出すこの方法は悪い習慣ですか?
私は次のコードを持っています: public void moveCameraTo(Location location){ moveCameraTo(location.getLatitude(), location.getLongitude()); } public void moveCameraTo(double latitude, double longitude){ LatLng latLng = new LatLng(latitude, longitude); moveCameraTo(latLng); } public void moveCameraTo(LatLng latLng){ GoogleMap googleMap = getGoogleMap(); cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, INITIAL_MAP_ZOOM_LEVEL); googleMap.moveCamera(cameraUpdate); } このようにすると、LatLngたとえば、別のクラスの内容を知る責任がなくなると思います。 また、関数を呼び出す前にデータを準備する必要はありません。 どう思いますか? このアプローチには名前がありますか?それは本当に悪い習慣ですか?

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