現在の回答はどちらも部分的にしか成功していないようで、中心的なアイデアを曇らせる例に焦点を当てています。これは(単独で)OOPの原則ではなく、一般的なソフトウェア設計の原則でもあります。
このフレーズで「変化する」のはコードです。クリストフは、それが何か普通であると言っに点にあることがありますが、多くの場合で異なり、予想されるこれは。目標は、コードの将来の変更から身を守ることです。これは、インターフェイスに対するプログラミングに密接に関連しています。ただし、クリストフはこれを「実装の詳細」に限定するのは正しくありません。実際、このアドバイスの価値はしばしば要件の変更によるものです。
これは、状態のカプセル化に間接的に関連しているだけです。これは、David Arnoが考えていることです。このアドバイスは、常に状態をカプセル化することを示唆しているわけではありませんが(多くの場合そうです)、このアドバイスは不変オブジェクトにも当てはまります。実際、単に定数に名前を付けることは、さまざまなものをカプセル化する(非常に基本的な)形式です。
CandiedOrangeは、「変化するもの」を「詳細」で明示的に圧縮します。これは部分的に正しいだけです。変化するコードは何らかの意味で「詳細」ですが、「詳細」を定義してトートロジーを作成しない限り、「詳細」は変化しないことに同意します。変化しない詳細をカプセル化する理由があるかもしれませんが、このthisは1つではありません。大まかに言って、「犬」、「猫」、「アヒル」だけが対処する必要があると確信している場合、このディクタムはCandiedOrangeが実行するリファクタリングを示唆していません。
CandiedOrangeの例を別のコンテキストでキャストする場合、Cのような手続き型言語があると仮定します。以下を含むコードがある場合:
if (pet.type() == dog) {
pet.bark();
} else if (pet.type() == cat) {
pet.meow();
} else if (pet.type() == duck) {
pet.quack()
}
このコードは将来変更されると合理的に予想できます。新しい手順を定義するだけで、それを「カプセル化」できます。
void speak(pet) {
if (pet.type() == dog) {
pet.bark();
} else if (pet.type() == cat) {
pet.meow();
} else if (pet.type() == duck) {
pet.quack()
}
}
コードブロックの代わりにこの新しいプロシージャを使用します(つまり、「抽出メソッド」リファクタリング)。この時点で、「牛」タイプまたはspeak
プロシージャの更新のみが必要なものを追加します。もちろん、OO言語では、代わりにCandiedOrangeの答えが示すように動的ディスパッチを活用できます。これはpet
、インターフェイスを介してアクセスする場合に自然に発生します。動的ディスパッチを介して条件付きロジックを排除することは、この手続き型の表現を作成した理由の一部であった直交的な懸念です。また、これにはOOPに固有の機能は必要ないことを強調したいと思います。オブジェクト指向言語であっても、変化するものをカプセル化しても、必ずしも新しいクラスまたはインターフェースを作成する必要があるわけではありません。
より典型的な例(より近いが完全にはオブジェクト指向ではない)として、リストから重複を削除したいとします。リストを繰り返し処理して、今までに別のリストで見た項目を追跡し、見た項目をすべて削除するとしましょう。少なくともパフォーマンス上の理由から、見たアイテムを追跡する方法を変更したいと思うかもしれません。さまざまなものをカプセル化するという考え方は、見たアイテムのセットを表す抽象データ型を構築する必要があることを示唆しています。アルゴリズムはこの抽象Setデータ型に対して定義されており、バイナリ検索ツリーに切り替えることにした場合、アルゴリズムを変更したり気にしたりする必要はありません。OO言語では、クラスまたはインターフェイスを使用してこの抽象データ型をキャプチャできます。SML / O 'のような言語で
要件駆動型の例では、いくつかのビジネスロジックに関していくつかのフィールドを検証する必要があるとします。現在、特定の要件があるかもしれませんが、それらが進化することを強く疑います。現在のロジックを独自のプロシージャ/関数/ルール/クラスにカプセル化できます。
これは「変化するものをカプセル化する」の一部ではない直交問題ですが、多くの場合、カプセル化されたロジックによって抽象化、つまりパラメーター化されます。通常、これによりコードがより柔軟になり、カプセル化されたロジックを変更するのではなく、代替実装に置き換えることでロジックを変更できます。