ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java Miniproject 중 Builder
    개발자 수업/Java 2021. 10. 27. 13:04
    package kr.co.ezenac.project;
    /*
     * Builder Pattern
     * 
     * 	1. 메서드의 조합으로 결과물을 생성
     * 		1) 생성에 대한 과정과 각 결과물을 표현하는 방법을 분리하여 동일한 생성 과정에 서로 다른 여러 결과물이 나올 수 있도록 함
     * 		2) 단계별 생성에 중점을 두는 패턴
     * 		3) 새로운 결과물이 필요한 경우에도 동일한 과정으로 생성할 수 있음
     * 		4) 생성 과정과 구현 방법을 분리하여 동일한 생성에서 여러 다른 표현이 나올 수 있음
     * 
     * 	2. 생성자를 대체하는 방법
     * 		1) 객체를 생성할 때 매개 변수가 여러 개인 경우 여러 개의 생성자를 사용하기보다는 인스턴스 생성을 위한 Builder를 제공함으로써
     * 		   이후 매개 변수가 늘어나더라도 유연하게 수정할 수 있는 구조를 제공함
     * 		2) 스프링 프레임워크에서 사용하고 있음
     * 
     * 	3. 객체 생성
     * 		1) 일반적으로 생성자를 제공
     * 		2) 때로는 변형이 필요
     * 			- 일반적인 생성자가 제공하는 것 이상이 필요한 경우가 있음
     * 			- 객체 생성을 클래스 로직 밖으로 옮길 필요
     * 			- 객체를 생성하기 전에 점진적으로 객체의 정보를 수집
     * 			- 모든 데이터가 한꺼번에 제공되지 못함
     * 		3) 결론
     * 			- 제품의 다양한 구현이 가능
     * 			- 제품의 생산 과정을 더 세분화 할 수 있음
     * 			- 클라이언트는 구체적인 사항을 알 필요가 없음
     */
    public class Builder {
    	
    	/*
    	 * 열거형 (Enum Type) : 상수의 집합을 만들거나 특정 객체의 상태를 모아놓음
    	 */
    	public enum Directions {
    		EAST,
    		WEST,
    		NORTH,
    		SOUTH
    	}
    	
    	public static void main(String[] args) {
    		Directions dir = Directions.NORTH;
    	}
    }

    import java.util.EnumSet;
    import java.util.Objects;
    import java.util.Set;
    
    // 여러 가지 피자를 만들기
    public abstract class Pizza {
    	public enum Topping {
    		HAM,
    		ONION,
    		PEPPER,
    		SAUSAGE,
    		MUSHROOM
    	};
    	
    	final Set<Topping> toppings;
    	
    	//Builder : Product의 각 요소들을 생성하는데 필요한 추상 메서드가 선언된 클래스나 인터페이스
    	abstract static class Builder {
    		EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);
    		
    		public Builder addTopping(Topping topping) {
    			toppings.add(Objects.requireNonNull(topping));
    			return self();
    		}
    		
    		public Builder sauceInside() {
    			return self();
    		}
    		
    		abstract Pizza build();
    		
    		protected abstract Builder self();
    	}
    
    	public String toString() {
    		return toppings.toString();
    	}
    	
    	public Pizza(Builder builder) {
    		toppings = builder.toppings.clone();
    	}
    }
    //뉴욕 피자
    //ConcreteBuilder : Builder에 선언된 메서드를 구현한 클래스
    //NYPizza는 size 값을 필수로 받아 생성
    
    import java.util.Objects;
    
    public class NYPizza extends Pizza {
    	
    	public enum Size {SMALL, MEDIUM, LARGE};
    	private final Size size;
    	
    	public static class Builder extends Pizza.Builder {
    
    		private final Size size;
    		
    		public Builder(Size size) {
    			//requireNonNull() : 인자 값이 null인지 체크하고 null이 아닐 때 그대로 반환
    			this.size = Objects.requireNonNull(size);
    		}
    		
    		@Override
    		public Pizza build() {
    			return new NYPizza(this);
    		}
    
    		@Override
    		protected Builder self() {
    			return this;
    		}
    		
    	}
    	
    	//생성자는 최대한 간단하게
    	public NYPizza(Builder builder) {
    		super(builder);
    		this.size = builder.size;
    	}
    
    }
    //칼조네 피자
    //ConcreteBuilder : Builder에 선언된 메서드를 구현한 클래스
    //Calzone는 sauseInside라는 부울 값을 통해 소스를 넣을지 말지 선택함
    public class Calzone extends Pizza {
    
    	private final boolean sauceInside;
    	
    	public static class Builder extends Pizza.Builder {
    		
    		private boolean sauceInside = false;
    		
    		public Builder sauceInside() {
    			sauceInside = true;
    			return this;
    		}
    		
    		@Override
    		public Calzone build() {
    			return new Calzone(this);
    		}
    
    		@Override
    		protected Builder self() {
    			return this;
    		}
    		
    	}
    	
    	public Calzone(Builder builder) {
    		super(builder);
    		this.sauceInside = builder.sauceInside;
    	}
    	
    	@Override
    	public String toString() {
    		return toppings.toString() + "sauceInside : " + sauceInside;
    	}
    }
    public class PizzaTest {
    	public static void main(String[] args) {
    		
    		Pizza nyPizza = new NYPizza.Builder(NYPizza.Size.MEDIUM)
    						.addTopping(Pizza.Topping.SAUSAGE).addTopping(Pizza.Topping.ONION).build();
    		Pizza calzone = new Calzone.Builder().addTopping(Pizza.Topping.HAM)
    						.addTopping(Pizza.Topping.PEPPER).sauceInside().build();
    		
    		System.out.println(nyPizza);
    		System.out.println(calzone);
    	}
    }

    '개발자 수업 > Java' 카테고리의 다른 글

    32. 연결리스트(Linked List) 구현  (0) 2021.11.02
    Java MiniProject  (0) 2021.10.26
    문제 2 - Chap09 / kr.co.ezenac.assignment  (0) 2021.10.26
    문제 1 - Chap13 / kr.co.ezenac.review02  (0) 2021.10.26
    31. 멀티스레드2  (0) 2021.10.25

    댓글