1 개요
빌더 패턴(Builder Pattern)은 주로 "복잡한 개체를 단계별로 빌드하는" 데 사용되는데, 여기서 "단계별"은 안정적인 알고리즘인 동시에 복잡한 개체의 다양한 부분이 자주 변경됩니다. 따라서 빌더 패턴은 주로 "객체 부분"의 변화하는 요구 사항을 해결하는 데 사용됩니다. 이를 통해 객체 생성 프로세스를 보다 세밀하게 제어할 수 있습니다.
2 예시
휴대폰 생산을 예로 들어보겠습니다. 각 휴대폰은 화면, CPU, 배터리로 구분됩니다. 이제 생산되는 휴대폰에는 Apple과 Samsung 두 가지 유형이 있습니다.
사과:
아아아아삼성:
아아아아테스트 클라이언트:
package org.scott.builder.before.use; import java.util.ArrayList; import java.util.List; /** * @author Scott * @version 2013-11-20 * @description */ public class ApplePhone { List<String> parts = new ArrayList<String>(); public void createCPU() { parts.add("CUP: Qualcomm"); } public void createScreen() { parts.add("SCREEN: JDI"); } public void createBattery() { parts.add("BATTERY: DeSai"); } public void show(){ System.out.print("产品部件信息:"); for(String part : parts){ System.out.print(part + "\t"); } } }
문제를 발견하셨나요? 즉, 휴대폰을 생산하는 모든 공정은 동일하지만, 공정 명칭은 동일하지만, 구체적인 공정은 몇 가지만 다를 뿐입니다. 각 프로세스 변경 사항을 처리하고, 이 중에서 "모든 변경 사항에 대응하기 위해 변경되지 않은" 것을 추출하고 변경 사항을 특정 제품에 넘길 수 있습니다.
구체적으로 어떻게 하나요? 이번에는 빌더 모드가 유용합니다.
먼저 전화 인터페이스를 살펴보겠습니다.
package org.scott.builder.before.use; import java.util.ArrayList; import java.util.List; /** * @author Scott * @version 2013-11-20 * @description */ public class SamsungPhone { List<String> parts = new ArrayList<String>(); public void createCPU() { parts.add("CUP: MTK"); } public void createScreen() { parts.add("SCREEN: Samsung"); } public void createBattery() { parts.add("BATTERY: DeSai"); } public void show(){ System.out.print("产品部件信息:"); for(String part : parts){ System.out.print(part + "\t"); } } }
Apple 휴대폰 카테고리:
package org.scott.builder.before.use; /** * @author Scott * @version 2013-11-20 * @description */ public class BuilerTest { private static ApplePhone iphone = new ApplePhone(); private static 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(); } }
삼성 휴대폰 카테고리:
package org.scott.builder.after.use; import java.util.ArrayList; import java.util.List; /** * @author Scott * @version 2013-11-20 * @description */ public abstract class Phone { protected List<String> parts = new ArrayList<String>(); public void add(String part){ parts.add(part); } public void show(){ System.out.print("产品部件信息:"); for(String part : parts){ System.out.print(part + "\t"); } } }
그런 다음 생산 단계에 대한 인터페이스 빌더를 정의합니다:
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public class ApplePhone extends Phone{ }
iPhone용 빌더:
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public class SamsungPhone extends Phone{ }
삼성 휴대폰용 빌더:
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public interface Builder { public void buildCPU(); public void buildScreen(); public void buildBattery(); public Phone getPhone(); }
특정 휴대폰 생산을 지도하는 디렉터:
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public class ApplePhoneBuilder implements Builder{ private Phone phone = new ApplePhone(); @Override public void buildCPU() { phone.add("CUP: Qualcomm"); } @Override public void buildScreen() { phone.add("SCREEN: JDI"); } @Override public void buildBattery() { phone.add("BATTERY: DeSai"); } @Override public Phone getPhone() { return phone; } }
마지막으로 테스트 클래스 작성:
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public class SamsungPhoneBuilder implements Builder{ private Phone phone = new SamsungPhone(); @Override public void buildCPU() { phone.add("CUP: MTK"); } @Override public void buildScreen() { phone.add("SCREEN: Samsung"); } @Override public void buildBattery() { phone.add("BATTERY: DeSai"); } @Override public Phone getPhone() { return phone; } }
실행 결과:
package org.scott.builder.after.use; /** * @author Scott * @version 2013-11-20 * @description */ public class Director { private Builder builder; public Director(Builder builder){ this.builder = builder; } public void construct(){ builder.buildCPU(); builder.buildScreen(); builder.buildBattery(); } }
여기서 두 개의 Phone 엔터티 클래스는 비어 있습니다. 이 경우 생략할 수 있습니다. Phone 인터페이스도 생략할 수 있으면 결국 Director, Builder 및 특정 Bulider 구현 클래스만 남게 됩니다. 또한 ApplePhone 클래스와 SamsungPhone 클래스는 서로 다른 휴대폰 브랜드이므로 서로 관련이 없는 클래스가 두 개 이상 발생하는 경우에는 공용 인터페이스인 Phone이 존재할 필요가 없습니다. , 그렇다면 Builder 인터페이스에 지정된 getPhone() 메소드의 반환 값을 결정하는 방법은 무엇입니까?
반환 값 유형이 ApplePhone이든 SamsungPhone이든 상관없이 반환되는 결과의 유형이 일정하지 않기 때문에 문제가 발생합니다. 이때 Phone을 빈 인터페이스(어떤 메소드도 포함하지 않는 인터페이스)로 정의한 다음 서로 관계가 없는 특정 제품 클래스가 이 인터페이스를 구현하도록 하면 getPhone( ) Builder 인터페이스에 지정된 메소드가 여전히 Phone 유형인 경우 문제가 해결됩니다. 하지만 이 경우에는 빌더 모드를 사용할 필요가 없습니다.
자바 디자인 패턴의 빌더 패턴 학습과 관련된 더 많은 기사를 보려면 PHP 중국어 웹 사이트를 주목하세요!