白話デザインモード_デコレーションモード


装飾者モード、名を見て意を知る.装飾装飾装飾とは、装飾とは何か、あるものの上に外にもう一つのものをつけることにほかならない.装飾者モードはたぶんそうだろう.
 
例えば、今クラスAがあります.新しい機能を追加したいのですが、元のコードを変更したくないので、どうすればいいですか.直接的な考え方は継承ですが、継承の柔軟性はよくありません.多くの組み合わせを使うことをお勧めします.継承を少なくします.
 
応用グループ:クラスB(装飾者)を新設し、A(被装飾者)をBに組み合わせることで、BにAの機能を行使させることができるが、2点に注意しなければならない.
一、AとBは同じスーパークラスやインタフェースを持つべきで、このようにしてやっと多態を利用してAを使う場所でBを使うことができて、私達は継承を採用して、BにAから継承させます.
二、BをAから継承させるのはAクラスを継承するための方法ではなく、共通のタイプを宣言するだけで、他人から見ればAとBは同じである.
 
前の例:
これは被装飾者です
public class Obj {
	public void doSth(){
		System.out.print("i do sth.");
	}
	public void doSthElse(){
		System.out.print("i do sth else.");
	}
}

次に、ObjインスタンスがdoSth()メソッドを実行するときに実行時間を追加し、doSthElse()を実行するときに実行場所を追加するように機能を拡張します.
これは装飾者です.
public class DecoraterObj extends Obj {
	private Obj obj;
	
	public DecoraterObj(Obj obj){
		this.obj = obj;
	}
	public void doSth() {
		obj.doSth();
		System.out.println(" at " + new Date());
	}
	public void doSthElse() {
		obj.doSthElse();
		System.out.println(" at somewhere.");
	}
}

装飾者DecoraterObjは被装飾者Objから受け継がれているので、両者は同じ対外的な「インターフェース」を持っています.私たちはもともとObjを使用する場所で、今では直接DecoraterObjを使用することができます.そして、Objを使用するように、DecoraterObjにObjリファレンスが結合されているため、元のObjの機能を提供しています.唯一の違いは、元のObjをDecoraterObjで拡張することができ,その前または後に機能を任意に追加することができる.
 
テスト:
public class Main {
	public static void main(String[] args) {
		Obj obj = new DecoraterObj(new Obj());
		
		obj.doSth();
		obj.doSthElse();
	}
}

このように、私たちはObjを使っているように見えますが、実は私たちはもうその外に包装しています.
 
これは見覚えがあるのではないでしょうか.デコレーションモードはjava I/Oで非常に多く使われているので、以下のコードがよく見られます.
new InputStreamReader(new ButteredInputStream(new InputStream()))

InputStreamクラスは最も簡単なバイナリ読み取りを提供し、外側にBufferedInputStreamを包装し、バッファ機能を提供し、外側にInputStremReaderを包装し、文字方式で読み取り機能を提供する.
 
まとめ:
装飾者モードの鍵は、対外的な「インタフェース」、マルチステート呼び出しを統一することです.