問題タブ [solid-principles]
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.
oop - 優れたリレーショナル データベース設計のように、優れたオブジェクト指向設計を形式化できますか?
データベースの世界では、正規化があります。設計から始めて、段階を踏んで、最終的には通常の形式のデータベースにたどり着くことができます。これは、データのセマンティクスに基づいて行われ、一連の設計リファクタリングと考えることができます。
オブジェクト指向設計では、SOLID 原則と、優れた設計に向けたさまざまなアドホック ガイドラインがあります。
一連のリファクタリング手順により、手続き型のコード (または不十分にファクタリングされた OO 設計) を正しい (明確に定義された意味で) 式に移行できるように、OO の正規形に相当するものを定義することは可能だと思いますか?同じ機能?
(注: このコミュニティ wiki を作成できて光栄です)
inheritance - インスタンスをスーパータイプとして宣言するのに、サブタイプとしてインスタンス化する理由と、リスコフの置換原則
私はここ数日、リスコフの置換原則を理解しようとしてきました。非常に典型的な長方形/正方形の例でいくつかのコードテストを行っているときに、以下のコードを作成し、それについて2つの質問を思いつきました。
質問1:スーパークラスとサブクラスの関係がある場合、インスタンスをスーパータイプとして宣言し、サブタイプとしてインスタンス化(新規作成)するのはなぜですか?
インターフェイスを介してポリモーフィズムを実行している場合、変数を次のように宣言してインスタンス化する理由を理解しています。
しかし、古いプログラミングクラスといくつかのブログの例でそれを思い出したので、継承を通じてポリモーフィズムを使用するとき、いくつかのコードがこのように変数を宣言するいくつかの例をまだ見ています
以下の私のコードでは、SquareはRectangleを継承しているため、次のように新しいSquareインスタンスを作成すると次のようになります。
それでも長方形として扱うことも、一般的な長方形のリストに追加することもできます。それでは、なぜ誰かがそれをRectangle = new Square()として宣言したいのでしょうか。私が見ていない利点、またはこれが必要となるシナリオはありますか?私が言ったように、以下の私のコードはうまく機能します。
}
これはリスコフの置換原則に違反しているはずですが、次の出力が得られます。
"幅:90、高さ:80
ConsoleApp.Program + Rectangle
幅:80、高さ:80
ConsoleApp.Program + Square
幅:80、高さ:80 ConsoleApp.Program + Square
質問2:では、なぜ、またはどのようにこのコードサンプルがLSPを破壊しているのでしょうか。すべての辺の正方形の不変量が等しいために、辺が独立して変更できるのは長方形の不変量を壊すだけですか?それが理由である場合、LSP違反は理論上のものにすぎませんか?または、コードで、このコードが原則を破っているのをどのように見ることができますか?
編集:私が読んでいたLSPブログ記事の1つで出てきた3番目の質問を思いついたが、答えがなかったのでこれだ
質問3:オープンクローズの原則は、新しいクラス(継承またはインターフェース)を通じて新しい動作/機能を導入する必要があると述べています。たとえば、基本クラスにWriteLogメソッドがあり、前提条件はありませんが、メソッドをオーバーライドする新しいサブクラスを導入しますが、イベントが非常に重要な場合にのみ実際にログに書き込みます。新しい意図された機能(サブタイプで強化されている前提条件)、それでもLSPを壊しているでしょうか?この場合、2つの原則は互いに矛盾しているように見えます。
前もって感謝します。
coding-style - 「ダイヤル可能な」電力原理(別名?)
デザイナーとして、私はパワーとシンプルさのバランスに対応するインターフェースを提供するのが好きです。たとえば、LINQの設計者は、ドット表記とクエリ表記の両方を提供しているため、この原則に従っていると思います。前者はより強力ですが、後者は読みやすく、理解しやすいです。LINQの私の評価に同意できない場合は、とにかく私のポイントを確認してみてください。LINQは単なる例であり、私の投稿はLINQに関するものではありません。
私はこの原理を「ダイヤル可能な力」と呼んでいます。しかし、私は他の人がそれを何と呼んでいるのか知りたいです。確かに「KISS」は一般的な用語だと言う人もいます。しかし、私はKISSをスーパーセット、つまり「消費主義」の実践と見なしています。再び私の例としてLINQを使用すると、私の見解では、ドット表記よりもクエリ表記を常に使用しようとするプログラマーのチームがKISSを実践しています。したがって、LINQの設計者は「ダイヤル可能な電力」を実践しましたが、LINQの消費者はKISSを実践しました。二人は一緒に美しい音楽を作ります。
編集別の例を挙げましょう。2つの使用を可能にする2つの署名を持つロギングツールを想像してみてください。
2つの署名の目的は、次のニーズを満たすことです。
消費者はシンプルなインターフェイスまたは強力なインターフェイスを選択できるため、これらの過負荷があることは「ダイヤル可能な電力」を表します。KISSを愛する消費者は、ほとんどの場合、より単純な署名を使用し、電力が必要なときに「忙しい」外観の署名を許可します。強力な署名を使用すると、コードのパフォーマンスが重要であることがリーダーに通知されるため、これは自己文書化にも役立ちます。ロガーに強力な署名しかない場合、「ダイヤル可能なパワー」はありません。
つまり、これは完全に一周します。自分の「ダイヤル可能なパワー」のコインがまだ存在しない場合は、それを維持できてうれしいですが、このプラクティスの明確な指定が欠けていると思わずにはいられません。
ps関連しているが、「ダイヤル可能な電力」と同じではない別の例は、Scott Meyerの原則であり、「インターフェイスを正しく使いやすく、誤って使いにくいようにする」というものです。
design-patterns - アダプターパターンとリスコフの置換
アダプタデザインパターンは、クラス(Target)のインターフェイスをクライアントが期待する別のインターフェイス(Adaptee)に変換するために使用されます。アダプタを使用すると、互換性のないクラスを連携させることができます。これは、互換性のないインターフェイスのために他の方法では機能しませんでした。
アダプタパターンは、継承(アダプタパターンのクラスバージョン)とコンポジション(アダプタパターンのオブジェクトバージョン)の2つの方法で実装できます。
私の質問は、継承を使用して実装されるアダプタパターンのクラスバージョンについてです。
図面エディタの例を次に示します。
TextViewクラスを再利用してTextShapeを実装したいのですが、インターフェイスが異なるため、TextViewオブジェクトとShapeオブジェクトを同じように使用することはできません。
シェイプインターフェイスに準拠するようにTextViewクラスを変更する必要がありますか?おそらくそうではありません。
TextShapeは、次の2つの方法のいずれかで、TextViewインターフェイスを図形のインターフェイスに適合させることができます。
- ShapeのインターフェースとTextViewの実装(Adapterパターンのクラスバージョン)を継承する
- TextShapeオブジェクト内にTextViewインスタンスを作成し、TextViewインスタンス(アダプタパターンのオブジェクトバージョン)を使用してTextShapeのインターフェイスを実装します。
クラスアダプタ
さて、質問です:-)。TextShapeはShape、特にTextViewから継承していますか?有効な「isa」関係ですか?そうでなければ、それはリスコフの置換原則に違反しませんか?
php - PHPの依存性逆転の原則
PHPは緩く型付けされた言語なので、DIPの原則をPHPにどのように適用できますか?
実用的な例をいただければ幸いです。
oop - 動的 GetHash 関数のクラス設計
複数の型のインスタンスの内部ハッシュコードを計算する必要があります (一部の型は互いに派生しています)。ここでは 2 つの側面が動的であり、独立して変化する可能性があります。ハッシュを要求するクライアントだけが、どのハッシュ アルゴリズムが使用され、どのプロパティが含まれるかを知っています。
- ハッシュ計算に使用される実際のアルゴリズムは変更される可能性があります。
- ハッシュ計算で考慮すべき各タイプのメンバーは変更される可能性があります。
これらの要件に合わせて型をどのように設計しますか?
solid-principles - 1つのことを実行し、それをうまく実行するプログラムを作成する
カプセル化、依存性注入、最小知識の原則、そしてあなたはそれを必要としないことによって、「1つのことをする」という部分を理解することができます。しかし、2番目の部分「うまくやる」をどのように理解できますか?
与えられた例は、同じYAGNIの記事で与えられた完全性の概念でした:
たとえば、アイテムの追加、アイテムの削除、またはアイテムの変更を可能にする機能の中で、完全性を使用して「アイテムの名前変更」を推奨することもできます。
しかし、私はそのような推論がフィーチャークリープに簡単に悪用され、「1つのことをする」部分に違反する可能性があることを発見しました。
したがって、機能を確認するためのリトマス試験とは、「うまくいく」カテゴリ(したがって、関数/クラス/プログラムに含める)または他の「1つのことを行う」カテゴリ(したがって、除外する)に属します。 ?
最初の部分である「1つのことを行う」は、UNIXのls
コマンドを介して、出力をフォーマットするための過剰な数のフラグが含まれていることの反例として最もよく理解されます。これは、別の外部プログラムに完全に委任されているはずです。しかし、2番目の部分が「うまくやる」のを見る良い例はありません。
それ以上の機能を削除すると「うまくいかない」という良い例は何ですか?
functional-programming - 関数型プログラミング用のSOLID
OOP言語から来て、私はオブジェクト指向設計のSOLID原則に精通しています。これらのいくつかは関数型プログラミングモデルに適合するように見えますが、他の部分は状態のない世界では意味がありません。関数型コードをリファクタリングするための同様の一連の原則はありますか?
asp.net-mvc-3 - SOLID アプリケーション アーキテクチャでの Ninject の使用
私は MVC3 から始めて、いくつかの柔軟なアーキテクチャを使用したいので、何十ものブログや本 (Pro ASP.NET MVC 3) を読み、SOLID の原則について読み、最終的に気に入ったアプリケーション構造にたどり着きました (または少なくとも私はまだ何も構築していないので、これまでのところそうだと思います):
この構造では:
- ドメインは POCO クラスを保持し、サービス インターフェイスを定義します
- サービスはサービス インターフェイスを実装し、リポジトリ インターフェイスを定義します
- データはリポジトリ インターフェイスを実装します
- WebUI とドメイン利用サービス
- サービスはリポジトリを使用します
- WebUI、サービス、およびデータは、POCO クラスのドメインに依存します
サービスを使用するドメインの主な理由は、POCO (IValidatable) クラスの Validate メソッドで一意のキーを検証することです。
この構造の参照アプリケーションを作成し始めていますが、これまでのところ 2 つの問題に直面しています。
リポジトリの単体テストを含む Data.Tests プロジェクトを使用していますが、サービスの実装を (コンストラクターまたはそれ以外で) モデルに (Ninject を使用して) 注入する方法が見つからないため、Validate メソッドでサービスで CheckUniqueKey を呼び出します。
Ninject を TEST プロジェクトに接続する方法についてのリファレンスは見つかりませんでした (WebUI プロジェクトの場合はたくさんあります)。
ここで達成しようとしているのは、DATA アセンブリを変更するだけで、EF から DAPPER のような別のものに切り替えることができるということです。
アップデート
現在 (2011 年 8 月 9 日現在) Ninject は動作していますが、何か足りないと思います。
2 つのコンストラクターを持つ CustomerRepository があります。
TestInitialize で:
顧客クラス:
このシナリオで Ninject を使用する最良の方法は何でしょうか?
どんな助けでも大歓迎です。
答え、一種
この質問は、これまでに回答したとおりに検討します。Ninject を機能させることはできましたが、SOLID の Dependency Inversion Principle (DIP) を達成するには、もう少し時間がかかりそうです。
その点で、ドメイン、サービス、データをひとまとめにする必要がありました。別の機会に別の質問を作成し、今のところ通常どおりプロジェクトを進めます。
みんなありがとう。
c# - おすすめのデザインパターン
私が取り組んでいるアプリケーションは、作業項目を処理します。ワークアイテムの状態に応じて、利用可能なアクションがいくつかあります。「完了」「キャンセル」「再割り当て」など…
アクションの機能を提供するために、私は現在、次のようなインターフェースを持っています...
次に、作業項目の他の詳細に基づいて、インターフェイスの具体的な実装を行います。たとえば...
と
問題は、新しいアクションを追加したい場合、たとえば...「デリゲート」ということです。もちろん、すべての実装に影響を与えるインターフェイスを更新する必要があります。
これはオープン/クローズの原則に違反していますか? ここで役立つと思われるデザインパターンまたはリファクタリングをお勧めできますか?