目次
デコレータ パターンはどのような問題を解決しますか?
公式声明: デコレータ パターン (Decorator Pattern) を使用すると、構造を変更せずに既存のオブジェクトに新しい機能を追加できます。
個人的な理解: 元のインターフェイスでは機能が不十分で、新しいメソッドを追加する必要がありますが、元のインターフェイスは別の場所に実装されているため、元のインターフェイスに直接メソッドを追加することはできません。このとき、元のクラスオブジェクトを保持し、新しいメソッドを追加することで新しい機能を実装できます。そして、元のクラスを継承するか、元のインターフェイスを実装して、元のクラスを置き換える目的を達成します。
JDK のデコレータ パターンの実際の用途は何ですか?
FilterInputStream
InputStream は抽象クラスであり、ソース コードは次のとおりです。
public abstract class InputStream implements Closeable {
...
public abstract int read() throws IOException;
...
}
InputFilterStream ソース コード:
public
class FilterInputStream extends InputStream {
protected volatile InputStream in;
...
public int read() throws IOException {
return in.read();
}
...
}
BufferedInputStream ソース コード:
public
class BufferedInputStream extends FilterInputStream {
public BufferedInputStream(InputStream in) {
this(in, DEFAULT_BUFFER_SIZE);
}
public BufferedInputStream(InputStream in, int size) {
super(in); //注意这里调用了FilterInputStream的构造器
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
public synchronized int read() throws IOException {
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return getBufIfOpen()[pos++] & 0xff;
}
...
private InputStream getInIfOpen() throws IOException {
InputStream input = in;
if (input == null)
throw new IOException("Stream closed");
return input;
}
...
}
3 つのクラスの完全なメソッド:
InputStream は、抽象メソッドを 1 つだけ持つ抽象クラスです。
FilterInputStream はメソッドを追加せず、InputStream のインスタンスを保持するだけです。
BufferedInputStream には、次のようないくつかのメソッドが追加されますgetInIfOpen()
。
使用BufferedInputStream:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("/home/user/abc.txt")));
Android SDK のデコレーター パターンの実際の用途は何ですか?
- ContextWrapper とアプリケーション、アクティビティ。具体的な参照:デザイン パターン (11) コンテキスト内のデコレータ モード
インターネット上の一部のブログでは、デコレータ モードを使用して RecyclerView にヘッダーを追加する方法について説明しています。例: Decorator デザイン パターン - RecyclerView は head とbottom を追加します。慎重に分析したわけではないので、結論は出しません。
デコレータ パターンとアダプタ パターンの違いは何ですか?
簡単に言えば、デコレータ パターンは、元のクラスの機能が不十分であるという問題を解決します。元のクラスにはこの機能があるのに機能が一致しないという問題をアダプターパターンで解決します。
たとえば、元のクラスにはズボンはありますが、靴はありませんが、このときはデコレータ モードが使用されます。本来のクラスには靴がありますが、靴のサイズが大きすぎて入らないため、このときはアダプターモードを使用します。
デコレータパターン:
- デコレータ パターンの目的は、元のクラス オブジェクトに新しい機能を動的に追加することです。元のクラスの機能不足の問題を解決します。
- デコレータ クラスは機能拡張として機能します。
- 元のクラスを継承し、デコレータ クラスを作成し、元のクラス オブジェクトをデコレータでラップし、組み合わせて関数を追加します。
アダプターモード:
- アダプター パターン (Adapter Pattern) の目的は、目的のインターフェイスを実現し、元のクラスの関数が一致しない問題を解決することです。ターゲット インターフェイスが元のクラスと対話できるようにします。
- アダプター クラスはブリッジとして機能します。
- アダプター パターンは、元のクラスのメソッドと連携するアダプター クラスを作成することによって、ターゲット インターフェイスのメソッドを実装します。
デコレータ パターンとプロキシ パターンの違いは何ですか?
- 目的は異なります。デコレータ パターンは、元のオブジェクトの機能を拡張し、デコレータに新しいメソッドを追加することです。プロキシモードは、元のオブジェクトへのアクセスを制御するモードであり、元のオブジェクトのメソッドが変更されます。
- メソッドの数が異なります。デコレータ パターンでは、新しいメソッドを追加する必要があるため、デコレータのメソッドの数がデコレータのメソッドの数よりも多くなります。プロキシ モードには通常、親クラスと同じ数のメソッドがあります。
- 元のオブジェクトのアクセス修飾子が異なります。デコレーター モードでは、通常、元のオブジェクトのアクセス修飾子は次のようになります。
protected