1 概要
ビルダー パターン (ビルダー パターン) は主に「複雑なオブジェクトを段階的に構築する」ために使用されます。「段階的に」は安定したアルゴリズムですが、複雑なオブジェクトのさまざまな部分は頻繁に変更されます。したがって、ビルダーパターンは主に「オブジェクト部分」の変化する要件を解決するために使用されます。 これにより、オブジェクト構築プロセスをよりきめ細かく制御できるようになります。
2 例
携帯電話の製造を例にとると、各携帯電話は画面、CPU、バッテリーに分かれています。現在、Apple と Samsung の 2 種類の携帯電話が生産されています。
りんご:
次のようにコードをコピーします。
パッケージ org.scott.builder.before.use;
java.util.ArrayListをインポートします。
java.util.Listをインポートします。
/**
* @著者スコット
* @バージョン 2013-11-20
* @説明
*/
パブリック クラス ApplePhone {
List<String> パーツ = new ArrayList<String>();
public void createCPU() {
Parts.add("CUP: クアルコム");
}
public void createScreen() {
Parts.add("画面: JDI");
}
public void createBattery() {
Parts.add("バッテリー:デサイ");
}
public void show(){
System.out.print("製品コンポーネント情報:");
for(文字列部分:部分){
System.out.print(part + "/t");
}
}
}
サムスン:
次のようにコードをコピーします。
パッケージ org.scott.builder.before.use;
java.util.ArrayListをインポートします。
java.util.Listをインポートします。
/**
* @著者スコット
* @バージョン 2013-11-20
* @説明
*/
パブリック クラス SamsungPhone {
List<String> パーツ = new ArrayList<String>();
public void createCPU() {
Parts.add("カップ:MTK");
}
public void createScreen() {
Parts.add("スクリーン: サムスン");
}
public void createBattery() {
Parts.add("バッテリー:デサイ");
}
public void show(){
System.out.print("製品コンポーネント情報:");
for(文字列部分:部分){
System.out.print(part + "/t");
}
}
}
テストクライアント:
次のようにコードをコピーします。
パッケージ org.scott.builder.before.use;
/**
* @著者スコット
* @バージョン 2013-11-20
* @説明
*/
パブリック クラス BuilderTest {
プライベート静的 ApplePhone iphone = new ApplePhone();
プライベート静的 SamsungPhone samPhone = new SamsungPhone();
public static void main(String args[]){
iphone.createCPU();
iphone.createScreen();
iphone.createBattery();
iphone.show();
samPhone.createCPU();
samPhone.createScreen();
samPhone.createBattery();
samPhone.show();
}
}
問題は見つかりましたか?つまり、携帯電話を製造するすべてのプロセスは同じです。プロセスの名前は同じですが、各プロセスの具体的なプロセスは変わりません。各工程の処理が変化する中から、「あらゆる変化に対応できる変わらないもの」を抽出し、変化するものを特定の製品に引き継ぐことができます。
具体的にはどうすればいいのでしょうか?今回はビルダーモードが便利です。
まず、電話インターフェイスを見てみましょう。
次のようにコードをコピーします。
パッケージ org.scott.builder.after.use;
java.util.ArrayListをインポートします。
java.util.Listをインポートします。
/**
* @著者スコット
* @バージョン 2013-11-20
* @説明
*/
パブリック抽象クラス 電話 {
protected List<String> パーツ = new ArrayList<String>();
public void add(文字列部分){
Parts.add(パーツ);
}
public void show(){
System.out.print("製品コンポーネント情報:");
for(文字列部分:部分){
System.out.print(part + "/t");
}
}
}
Appleの携帯電話カテゴリ:
次のようにコードをコピーします。
パッケージ org.scott.builder.after.use;
/**
* @著者スコット
* @バージョン 2013-11-20
* @説明
*/
パブリック クラス ApplePhone は Phone{
}
サムスン携帯電話カテゴリ:
次のようにコードをコピーします。
パッケージ org.scott.builder.after.use;
/**
* @著者スコット
* @バージョン 2013-11-20
* @説明
*/
パブリック クラス SamsungPhone は Phone{
}
次に、実動ステップ用のインターフェース Builder を定義します。
次のようにコードをコピーします。
パッケージ org.scott.builder.after.use;
/**
* @著者スコット
* @バージョン 2013-11-20
* @説明
*/
パブリック インターフェイス ビルダー {
public void buildCPU();
public void buildScreen();
public void buildBattery();
公衆電話 getPhone();
}
iPhone 用ビルダー:
次のようにコードをコピーします。
パッケージ org.scott.builder.after.use;
/**
* @著者スコット
* @バージョン 2013-11-20
* @説明
*/
パブリック クラス ApplePhoneBuilder は Builder{ を実装します
プライベート電話 Phone = new ApplePhone();
@オーバーライド
public void buildCPU() {
Phone.add("CUP: クアルコム");
}
@オーバーライド
public void buildScreen() {
Phone.add("画面: JDI");
}
@オーバーライド
public void buildBattery() {
Phone.add("バッテリー:デサイ");
}
@オーバーライド
公衆電話 getPhone() {
電話を返す。
}
}
Samsung 携帯電話用ビルダー:
次のようにコードをコピーします。
パッケージ org.scott.builder.after.use;
/**
* @著者スコット
* @バージョン 2013-11-20
* @説明
*/
パブリック クラス SamsungPhoneBuilder は Builder{ を実装します
プライベート電話phone = new SamsungPhone();
@オーバーライド
public void buildCPU() {
Phone.add("カップ:MTK");
}
@オーバーライド
public void buildScreen() {
Phone.add("画面: サムスン");
}
@オーバーライド
public void buildBattery() {
Phone.add("バッテリー:デサイ");
}
@オーバーライド
公衆電話 getPhone() {
電話を返す。
}
}
携帯電話の具体的な生産を指導するディレクター:
次のようにコードをコピーします。
パッケージ org.scott.builder.after.use;
/**
* @著者スコット
* @バージョン 2013-11-20
* @説明
*/
パブリック クラス ディレクター {
プライベートビルダービルダー。
public Director(ビルダー ビルダー){
this.builder = ビルダー;
}
パブリック void コンストラクト(){
builder.buildCPU();
builder.buildScreen();
builder.buildBattery();
}
}
最後にテストクラスを書きます。
次のようにコードをコピーします。
パッケージ org.scott.builder.after.use;
/**
* @著者スコット
* @バージョン 2013-11-20
* @説明
*/
パブリック クラス BuilderTest {
プライベート静的ビルダー iPhoneBuilder = new ApplePhoneBuilder();
プライベート静的ビルダー samPhoneBuilder = new SamsungPhoneBuilder();
public static void main(String[] args) {
ディレクター ディレクター = 新しいディレクター(iPhoneBuilder);
Director.construct();
電話機 = iPhoneBuilder.getPhone();
System.out.println("iphone");
電話.show();
ディレクター = 新しいディレクター(samPhoneBuilder);
Director.construct();
電話 = samPhoneBuilder.getPhone();
System.out.println("/nsamSung");
電話.show();
}
}
実行結果:
次のようにコードをコピーします。
iphone
製品パーツ情報: CUP: Qualcomm SCREEN: JDI BATTERY: DeSai
サムソン
製品パーツ情報: カップ: MTK スクリーン: Samsung バッテリー: DeSai
この場合、Phone インターフェイスも省略できる場合は、Director、Builder、および特定の Builder 実装クラスのみが残ります。さらに、ApplePhone クラスと SamsungPhone クラスは、異なる携帯電話ブランドであるため、あまり関連性のないクラスが 2 つ以上ある場合は、現時点ではパブリック インターフェイス Phone が存在する必要はありません。 , では、Builder インターフェイスで指定された getPhone() メソッドの戻り値を確認するにはどうすればよいでしょうか。
戻り値の型が ApplePhone か SamsungPhone かに関係なく、返される結果の型が統一されていないため、問題が発生します。このとき、Phone を空のインターフェイス (メソッドを含まないインターフェイス) として定義し、相互に関係のないこれらの特定の製品クラスにこのインターフェイスを実装させ、 getPhone(. ) Builder インターフェイスで指定されたメソッド これはまだ Phone タイプであるため、問題は解決されます。ただし、この場合、ビルダー モードを使用する必要はありません。