問題タブ [open-closed-principle]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
2 に答える
2208 参照

java - DAO パターンと Open-Closed 原則

私は、通常は CRUD メソッドで始まる、JDBC ベースの古い DAO コードを数多く見てきました。私の質問は、特に検索方法、または「ファインダー」に関連しています。通常、DAO は次の 2 つの方法で開始されます。

  • すべてを見つけて返す
  • 一意の識別子に基づいて特定のインスタンスを取得する

多くの場合、これら 2 つのファインダーでは不十分です。私は通常、次のようなファインダ メソッドを追加するために DAO クラスが繰り返し変更されているのを目にすることになります。

  • ALL where {condition} を検索して返す

新しい {condition} をサポートする必要がある場合、または既存のメソッドを変更して新しいパラメータをフラグとして追加し、メソッド内の SQL クエリを変更して追加の条件をサポートする場合に、さらにメソッドが追加されます。

これは醜いアプローチであり、Open-Closed Principle に違反しています。新しい検索条件をサポートする必要があるたびに、DAO クラスが継続的に変更されるのを目にするのは、私にとって常に気になることでした。この質問に関する調査は、多くの場合、Repository パターンと、検索の条件を仕様またはクエリ オブジェクトとしてカプセル化し、それらをファインダー メソッドに渡すことを示しています。ただし、これは、データセット全体のメモリ内コレクションがある場合、または何らかの ORM を使用している場合にのみ実行可能と思われます (私は古い JDBC コードを使用しています)。

私は、DAO がメモリ内のコレクションとして管理するデータ セット全体を遅延ロードし、仕様パターンを検索用のクエリとして使用するソリューションを検討しました。次に、creates、updates、または deletes メソッドが呼び出されたときにデータベースを更新する、ある種のオブザーバーをコレクションに実装します。しかし、明らかにパフォーマンスとスケーラビリティが大幅に低下します。

これについて何か考えはありますか?


これまでの回答に感謝します。コマンド/ポリシー パターンを使用してデータ アクセス リクエストをカプセル化することについて、どう思いますか? 個々の具象コマンドは、特定の種類のアクセスを表すことができ、Invoker に渡すことができます。最終的に多数の具象コマンド クラスが作成されることになりますが、各クラスは 1 種類のアクセスのみに焦点を当てており、非常にテスト可能で分離されている必要があります。

0 投票する
1 に答える
4830 参照

c# - オープンクローズの原則を理解する

次のコードに出くわしたとき 、単純なスクリプト ファイル パーサーの古いコードをリファクタリングしていました。

この単純なスクリプト プロセッサは、「オープン クローズドの原則」を適用してリファクタリングするのに適しているように思えます。a で始まる行は、$おそらく別の方法で処理されることはありません。しかし、a で始まる新しいディレクティブ!を追加する必要がある場合はどうでしょうか? または、新しい処理識別子 (新しいスイッチケースなど) が必要ですか?

問題は、OCP を壊さずにディレクティブとプロセッサを簡単かつ正確に追加する方法を理解できなかったことです。!-case を使用してscope and/or を使用すると、 -caselineと同様に少しトリッキーになりdefaultます。

助言がありますか?

0 投票する
2 に答える
379 参照

objective-c - ObjectiveCカテゴリとオープン/クローズド原則

オープン/クローズド原則による

。。。ソフトウェアエンティティ(クラス、モジュール、関数など)は、拡張のために開いている必要がありますが、変更のために閉じている必要があります

では、このカテゴリーはこの原則に対する強い違反であると言えますか?

0 投票する
3 に答える
186 参照

design-patterns - 柔軟なソフトウェアのために開く/閉じる

タイトルはあまり説明的ではないかもしれませんが、私はより良いものを考えることができませんでした。ごめんなさい。

ですから、私がここで抱えている問題は、私が今何度か遭遇した問題です。それは本当にデザインパターンと原則に関するものであり、あなたの言語にOO機能がある限り、言語に依存しません。実際の例なしでは問題が何であるかを説明するのは難しいので、私が抱えている現在の問題について説明します。

したがって、ここではいくつかのクラスを使用してロジックステートメントを記述しています。次のようなことを考えてください。

さて、これはすべてダンディですべてですが、このクラスシステムを使用したいときに問題が発生します。現在、条件をSQLWHERE句に変換する必要があるシステムを作成しています。

私はこれをいくつかの方法で行うことができましたが、オープン/クローズの原則に準拠しているものはないようです。たとえば、Databaseクラスに条件を解析させてSQLにすることができます。Condition問題は、このように、変更せずに拡張できないためDatabase、Open/Closedをフォローしていないことです。

別の方法(ここでは論理的に見えるでしょう)はtoSQL()、私のに関数を追加することConditionです。ただし、その場合、データベースを(名前を付けるためだけに)XMLを使用し、SQL形式の条件を必要としないデータベースと交換することはできません。

私が過去にこの問題を回避した1つの方法は、工場を使用することでした。この場合のファクトリメソッドは次のようになります。

これはそれほど良いことではありませんが、Open/Closedの違反を減らすことができます。

これで、データベースを適切にサブクラス化できます。ファクトリもサブクラス化する必要があり、同様にCondition固有のクラスの新しい束を作成する必要がありますDatabase。また、Conditionクラスで魔法をかけることもできます。新しいを作成することはできConditionますが、それぞれのコンパニオンクラスも作成する必要がありますDatabase。最後に、工場を変更する必要があります。

これはこれまでに見た中で最小の違反ですが、まだOpen/Closedに違反しています。しかし、実際のところ、私はそれをまったく侵害したくありません。ずっと開いた/閉じたままでこれを行う方法はありますか?

0 投票する
2 に答える
264 参照

design-patterns - これはオープン/クローズの原則ですか?そうでない場合

次のコードを考慮する

これはオープン/クローズの原則ですか?つまり、ほとんどの責任を基本クラスに委譲し、特定の機能的責任を継承クラスに許可します。

って感じではないので、開閉主義じゃないとしたらどういうデザインパターンなんですか?

乾杯

0 投票する
3 に答える
497 参照

php - オブジェクトを作成するときに開閉原理を適用する方法

私は xml ドキュメント (google docs api) を解析し、個々のドキュメントをオブジェクトに入れるのに忙しいです。

ドキュメントにはさまざまな種類があります (ドキュメント、スプレッドシート、プレゼンテーション)。これらのドキュメントに関するほとんどの情報は同じですが、一部が異なります。

アイデアは、特定のドキュメント タイプごとにサブクラスを使用しながら、すべての共有情報を保持するベース ドキュメント クラスを作成することでした。

問題は、さまざまなタイプに適切なクラスを作成することです。ドキュメントのタイプを区別するには、2 つの方法があります。各エントリには、タイプを見つけることができるカテゴリ要素があります。使用される別の方法は、resourceId によるもので、形式はtype:id.

最も単純なオプションは、エントリのタイプをチェックする if ステートメント (または switch ステートメント) を作成し、それに対応するオブジェクトを作成することです。ただし、新しいタイプが追加される場合は、コードを編集する必要があります。

これを解決する別の方法があるかどうかはよくわからないので、ここで質問しています。適切なタイプのオブジェクトの作成をファクトリ メソッドにカプセル化できるので、必要な変更量は最小限ですみます。

今、私はこのようなものを持っています:

私の質問は、この状況を処理するために私が見ていない別の方法はありますか?

編集: サンプルコードを追加

0 投票する
4 に答える
4309 参照

c# - オープン/クローズの原則 - このスイッチにどう対処するか?

私はオープンクローズドの原則を調べていて、それは良さそうだったので、その教えを実践したかったのです。新たに発見した知識を既存のプロジェクトに適用することを検討しましたが、すぐに行き詰まりました。

新しい UserType が登場した場合 (その可能性は非常に高い)、これを変更する必要がありますが、まだ変更を受け付けていません。どうすればこれを回避できますか?

私が読んだことから、OCP を適用する代わりに、ここにファクトリを実装する必要があるように思えますか?

開閉原則を破る工場

ありがとう、コハン

0 投票する
3 に答える
1362 参照

oop - オープンソース ライブラリにおける OCP の良い例

stackoverflow の「Open Closed Principle」については、多くの議論がなされてきました。ただし、一般的には、原則のよりリラックスした解釈が一般的であるように思われるため、たとえば Eclipse はプラグインを使用して変更できるようになっています。

厳密な OCP に従って、新しい動作を追加するためではなく、バグを修正するためだけに元のコードを変更する必要があります。

OCP を介して機能の進化を観察できる、パブリックまたは OS ライブラリで OCP の厳密な解釈の良い例はありますか?元のコードが変更されていない元のクラスが拡張された、ライブラリの次のバージョン。

編集: Robert C. Martin によると、「リンク可能なライブラリ、DLL、または Java .jar が変更されていないかどうかにかかわらず、モジュールのバイナリ実行可能バージョン」*。ライブラリが閉じられたままになっているのを見たことがありません。実際には、新しい動作がライブラリに追加され、新しいバージョンが公開されています。OCP によると、新しい動作は新しいバイナリ モジュールに属します。

*Robert C. Martin によるアジャイル ソフトウェア開発、原則、パターン、および実践

0 投票する
2 に答える
1582 参照

liskov-substitution-principle - Liskov と OCP の関係を理解する

Liskov Substitutional Principal と Open Close Principal の関係についての理解を深めています。誰かが私の推論を確認し、以下の私の質問に答えてくれれば、それは素晴らしいことです.

私は次のクラスを持っています。ご覧のとおり、Bから派生し、動作を変更するために関数をAオーバーライドしています。DisplayMessage

今、私のブートストラップ プログラムではShowClassTypeis、Type のオブジェクトを期待しています。これは、TypeAがどのクラスであるかを書き出すのに役立ちます。ただしB、LSP に違反しているため、そのDisplayMessage関数が呼び出されると、完全に予期しないメッセージが出力され、本質的に の意図された目的が妨げられShowClassTypeます。

だから私の質問は、ShowClassTypeタイプ B が入ってきてそのメソッドの期待される機能を変更できるようになったので、それはもはや変更のために閉じられていないため、Open Close Principal に違反していると結論付けるのは正しいですか?元の A オブジェクトのみを操作していることを最初に確認するように変更する必要があると予想される動作)?

ShowClassTypeまたは、逆に、これは変更に対して閉じられていること、および派生型を渡すことによって (LSP に違反しているものの) 意図されていることを拡張したことを示す単なる良い例ですか?

最後に、基本クラスが抽象クラスでない場合、基本クラスに仮想関数を作成するのは悪い習慣ですか? そうすることで、派生クラスをリスコフ置換の原則に違反するように誘っているだけではありませんか?

乾杯