Factoryパターン
インスタンスの生成をFactoryクラスに集約することで、変更に強くなる。
生産拠点を一つの工場に集中するっちゅうことですね。
Factory methodパターンとはいちおう別物。
・複数クラスが直接クラスBのコンストラクタを呼ぶ場合
コンストラクタ呼び出し クラスA →→→→→→→→→→→→ クラスB クラスC →→→→→→→→→→→→ クラスB クラスD →→→→→→→→→→→→ クラスB // これだとクラスBのコンストラクタを変更するとACDも変更必要。
・ファクトリがコンストラクタを呼ぶ場合
createClassB() コンストラクタ呼び出し クラスA →→→→→→→→→→→→ ファクトリ →→→→→→→→→→→→ クラスB クラスC →→→→→→→→→→→→ ファクトリ →→→→→→→→→→→→ クラスB クラスD →→→→→→→→→→→→ ファクトリ →→→→→→→→→→→→ クラスB // ファクトリクラスのcreateClassB()メソッドだけ変更すればOK
↓こんな感じで直でCクラスのコンストラクタ呼び出すと、もしコンストラクタに変更あったときに、呼び出し側のA・Bも変更が必要になる。
public class A{ public static void main(String []args){ C c = newC("山田"); } } public class B{ public static void main(String []args){ C c = new C("山田"); } } public class C{ String name; public C(String s){ this.name = s; } }
↓Factoryクラスを仲介するパターン
public class A{ public static void main(String []args){ Factory f = new Factory; f.createClassB(); } } public class B{ public static void main(String []args){ Factory f = new Factory; f.createClassB(); } } public class Factory extends C { public void createClassC() { C c = new C("山田"); } } public class C{ String name; public C(String s){ this.name = s; } }
Adapterパターン
継承による方法と委譲による方法がある。今回は継承の方だけ。
Adapterはその名の通り、変換アダプターみたいなもの。
メリット
既存のクラスを変更せずに済むので、テストが楽になる。
例えばもしバグが発生した場合、既存のクラスが十分にテストされているなら、追加したAdapterとAdapteeのクラスだけをチェックすれば良い。
・DVI→HDMIに変換するコード例↓
既存クラス+Adaptee+Adapter+実行クラスの4つ。
package adapter; // 既存のクラス public class Hdmi { String maker; String originalType; Hdmi(String maker, String originalType) { this.maker = maker; this.originalType = originalType; } void printMaker() { System.out.println(maker); } void printOriginalType() { System.out.println(originalType + "からHDMIに変換"); } }
package adapter; // Adapteeクラス public interface Dvi { public void shovMaker(); public void showOriginalType(); }
package adapter; // Adapterクラス public class DviToHdmiAdapter extends Hdmi implements Dvi{ DviToHdmiAdapter(String maker, String originalType) { super(maker, originalType); } @Override public void shovMaker() { printMaker(); } @Override public void showOriginalType() { printOriginalType(); } }
package adapter; // 実行クラス public class Main { public static void main(String[] args) { Dvi dvi = new DviToHdmiAdapter("サンワ", "DVI"); dvi.shovMaker(); dvi.showOriginalType(); } }
運用方法
他にも変換したいケーブルがあれば、AdapterとAdapteeを追加していく。
・追加例
- USB→HDMI:Adapteeクラス「Usb」Adapterクラス「UsbToHdmiAdapter」
- VGA:Adapteeクラス「Vga」Adapterクラス「VgaToHdmiAdapter」