본문 바로가기

신세계 국비과정/신세게 - Java 공부

2주차 배운점 느낀점 - 빌더패턴, 자바빈패턴, 점층적 생성자 패턴

728x90
반응형
 

클래스와 관계

 

객체를 생성할때 점층적 생성자 패턴, 자바 빈 패턴, 빌더 패턴을 배웠다. getter setter 메소드를 알고있었지만 정확하게 왜 사용하는지 몰랐지만 쉽게 멤버변수에 접근하지 못하도록 할 수 있음을 알게되었다. 새롭게 배운 빌더패턴을 현업에서 주로 쓴다고 하시는데 구조는 복잡해보이지만 익숙해지면 참 편할 것 같다.

 

배운점

 

빌더 패턴


빌더 패턴은 간단한 객체를 사용하고 단계별 접근 방식을 사용하여 복잡한 객체를 생성한다고 하여 생성패턴에 속한다.
Builder 클래스는 단계별로 최종 객체를 구축하여, 빌더는 다른 개체와 독립적이다.
복잡한 객체의 생성과정과 표현방법을 분리해서 다양한 인스턴스를 만드는 생성 패턴이다.
생성자에 들어갈 매개변수를 메소드로 하나한 받아들이고 마지막에 통합빌드하여 객체를 생성하는 방법

 

메인문:

public class NutritionFactsMain {
    public static void main(String[] args) {
        NutritionFacts cocaCola = new NutritionFacts.Builder(240,8).calories(100).sodium(35).build();
    }
}

 

객체를 생성할때 Builder안에 필수로 넣어줘야하는 필드변수값 넣어주고 그 뒤에 선택적인 calories, sodium에 값을 넣어준다.

 

생성:
클래스명 변수 = new 클래스.Builder(@@@).멤버(@@@).멤버(@@@).build();

 

NutritionFacts 클래스:

 

public class NutritionFacts {
    private final int servingSize;   //(m1, 1회 제공량) 필수
    private final int servings;      //(m1, n회 제공량) 필수
    private final int calories;      //(1회 제공량당) 선택
    private final int fat;           //(g, 1회 제공량) 선택
    private final int sodium;        //선택
    private final int carbohydrate;  //선택

    public static class Builder {        // 빌더클래스 
        //필수 매개변수
        private final int servingSize;   //(Lm1, 1회 제공량) 필수
        private final int servings;      //(m1, n회 제공량) 필수

        //선택 매개변수
        private int calories = 0;       //(1회 제공량당) 선택
        private int fat = 0;            //(g, 1회 제공량) 선택
        private int sodium = 0;         //선택
        private int carbohydrate = 0;   //선택

        public Builder(int servingSize, int servings) { // 필수
            this.servingSize = servingSize;
            this.servings = servings;
        }

        public Builder calories(int val) {       //선택
            calories = val;
            return this;
        }

        public Builder fat(int val) {            //선택
            fat = val;
            return this;
        }

        public Builder sodium(int val) {         //선택
            sodium = val; 
            return this;
        }

        public Builder carbohydrate(int val) {   //선택
            carbohydrate = val;
            return this;
        }

        public NutritionFacts build() {          //선택

            return new NutritionFacts(this);
        }
    }
    private NutritionFacts(Builder builder){     //필수
        servingSize = builder.servingSize;       //선택 매개변수들
        servings = builder.servings;
        calories = builder.calories;
        fat = builder.fat;
        sodium = builder.sodium;
        carbohydrate = builder.carbohydrate;
    }

}

 

빌더 클래스 만들기


1. private final 타입 변수명 선언을한다.
2. public static class Builder 클래스를 만든다.
3. 필수 매개변수는 private final 타입+변수명 (그대로) 또 써줌
4. 선택 매개변수는 private 타입+변수명 final 떼고 써줌
5.

public Builder(타입 변수, 타입 변수){  //Builder 메소드
  this.변수 = 변수;  //필수는 this.로 받음
  this.변수 = 변수;
}

 

6.

public Builder(타입 val){
  변수 = val
  return this
}

 

7.(빌더클래스 바깥에서)

private 클래스(Builder builder){
  변수=builder.변수;
  변수=builder.변수;
  변수=builder.변수;
  변수=builder.변수;
}

 

JavaBean 패턴
Setter 메소드를 사용한 패턴
객체 생성 일관성, 불변성 문제 생길 수 있다.
필수매개변수 없이 다 선택적이게 됐다.
객체 생성 일관성(객체 생성 부분과 값을 설정되는 부분이 물리적으로 분리되었기 때문에), 불변성 문제 생길 수 있다. , 필수매개변수 없이 다 선택적이게 됐다. setter 웬만하면 쓰지마라, 실수로 초기값 세팅안될수도있고

 

메인문

 

HambergerBean hambergerBean1 = new HambergerBean();
hambergerBean1.setBun(1);
hambergerBean1.setPatty(1);
hambergerBean1.setPatty(2);
hambergerBean1.setBun(1);
hambergerBean1.setPatty(2);
hambergerBean1.setTomato(2);

 

hambergerBean1 객체 생성한다. 각각 멤버변수에 대해 set 메소드를 이용하여 값을 초기화 해준다.

 

HambergerBean 클래스
모든 필드는 private 변경한다. -> HambergerBean의 모든 멤버들을 캡슐화하겠다. 캡슐화(다른 클래스가 함부로 직접 접근 금지)

 

public class HambergerBean {
    //필수
    private int bun;      //private
    private int patty;    //private
    //선택
    private int cheese;   //private
    private int tomato;
    private int bacon;

    public void setBun(int bun) {  // 번 변수 초기화
        this.bun = bun;
    }

    public void setPatty(int patty) {  // 패티 변수 초기화
        this.patty = patty;
    }

    public void setCheese(int cheese) {
        this.cheese = cheese;
    }

    public void setTomato(int tomato) {
        this.tomato = tomato;
    }

    public void setBacon(int bacon) {
        this.bacon = bacon;
    }

    public HambergerBean(){

    }
}

 

클래스에서 alt + insert 를 누르면 getter 와 setter 메소드를 자동으로 만들어준다. 필수적인변수, 선택적인 변수 구분이 없다.

pulblic void set변수 (타입 변수){
  this.변수 = 변수;
}

 

점층적 생성자 패턴


Hamberger 클래스 생성자를 오버로딩하여 매개변수의 종류나 갯수에 따라 각각 만들어 주어야한다. 이렇게되면 비효율 적이다.

 

Hamberger 클래스

 

public class Hamberger {
    //필수
    private int bun;
    private int patty;
    //선택
    private int cheese;
    private int tomato;
    private int bacon;

    public Hamberger(){}

    public Hamberger(int bun,int patty,int cheese,int tomato, int bacon){
        this.bun = bun;
        this.patty = patty;
        this.cheese = cheese;
        this.tomato = tomato;
        this.bacon = bacon;
    }
    public Hamberger(int bun,int patty,int cheese,int tomato){
        this.bun = bun;
        this.patty = patty;
        this.cheese = cheese;
        this.tomato = tomato;

    }
    public Hamberger(int bun,int patty,int cheese){
        this.bun = bun;
        this.patty = patty;
        this.cheese = cheese;

    }
}

 

모든 클래스의 생성자는 해당 클래스의 접근제한자를 따른다.
리턴 타입이없다, 클래스이름과 같다 : 생성자
생성자의 매개변수는 new 연산자로 생성자를 호출할때, 매개값을 생성자 블록 내부로 전달하는 역할을 한다.

 

메인문

//모든 재료가 있는 햄버거
Hamberger hamberger1 = new Hamberger(2, 2, 2, 2);
//빵, 패티, 치즈 ,토마토
Hamberger hamberger2 = new Hamberger(1, 1, 1, 1);
//빵과 패티와 치즈 햄버거
Hamberger hamberger3 = new Hamberger(1, 1, 1, 1);

 

멤버변수 자동초기화

 

Car myCar = new Car();    //Car 객체의 필드값 읽기
System.*out*.println(myCar.model); -> null
System.*out*.println(myCar.speed); -> 0
System.*out*.println(myCar.start); -> false

 

힙에서 객체영역은 인스턴스화 하면서 자동 초기화

 

iter

 

for (Car car : myCarArray) {    
}

 

this()메소드를 사용하여 초기화 작업 성능 향상시키기
생성자 안에 또 생성자를 호출해서 생성

 

 

가변길이 매개변수


메소드를 호출할 때, 매개변수의 개수에 맞게 제공해야 한다.
만약, 메소드가 가변길이 매개변수를 가지고 있다면 ,매개변수의 개수와 상관없이 매개값을 제공해야 한다.
int sum(int ... values) // '...' 사용

 

int sum(int ... values){    
int sum = 0;    
for(int i = 0 ; i<values.length;i++){
        sum+=values[i];    
}   
return sum;}

 

다음과 같이 사용할 수 있다.

 

int result1 = computer.sum(1,2,3);      //세개
int result2 = computer.sum(1,2,3,4,5);  //5개
int[] values = {1,2,3,4,5,6,7,8,9,10};  
int result3 = computer.sum(values);     //10개짜리 배열

 

return 문


메소드의 실행을 강제 종료, 호출한 곳으로 제어가 이동한다.
메소드의 실행을 강제 종료하고 호출한 곳으로 돌아간다는 의미
메소드 선언에 리턴 타입이 있을 경우에는 return 문 뒤에 리턴값을 추가로 지정해야 함
return문 이후에 실행문을 작성하면 'Unreachable code' 컴파일 에러발생

 

메소드 오버로딩


메소드 이름은 같되 매개변수의 타입 , 개수 , 순서가 다른 메소드를 여러 개 선언하는 것

 

 

싱글톤 패턴


생성자를 private 접근 제한해서 외부에서 new 연산자로 생성자를 호출할 수 없도록 막아서 외부에서 마음대로 객체를 생성하지 못하게 함
대신 싱글톤 패턴이 제공하는 정적 메소드를 통해 간접적으로 객체를 얻을 수 있음

 

 

 

회고

 

점점 내가 알던 지식이 바닥나고 있다. 디자인패턴은 현업에서 중요하다. 새롭게 알아가는것이 생소하고 두렵기는 하지만 내 실력이 향상되는 것 같아 기분이 좋다. 재밌다. 다음주 더 많은 내용을 진도나간다고 하는데 즐기자.
오늘 금요일 한 주 마지막이다. 끝나고 조원 스터디로 하기로했다. 조금만 더 무리하고 내일은 주말이니깐 늦잠좀 자야겠다.

반응형