❤️01_Java/03_Library

#Lombok #Lombok사용법 #장점 #단점 #@NonNull #@ToString #@EqualsAndHashCode #@Data #@Builder

roomname-dev 2023. 11. 6.
728x90
반응형

 

📚Lombok이란 무엇일까?

Lombok이란 java라이브러리로 반복되는 메소드를 Annotaion을 통해 자동으로 작성해주는 라이브러리입니다.

보통 DTO나 Model, Entity의 경우 여러 속성이 존재하고 이들이 가지는 속성(Property)에 대한 Getter & Setter & 생성자등을 매번 작성해줘야할때  자동으로 만들어주는 라이브러리이다. 

 

Lombok을 이용하여 작성한 코드는 컴파일 과정세ㅓ Annotaion을 이용하여 코드를 생성하여 .class 파일에 자동 컴파일 된다. 

 

📚Lombok  장점 

- Annotaion 기반의 코드 자동생성을 통한 생산성 향상 
- 반복코드 제거를 통한 가독성 및 유지보수 향상
- Getter/Setter 외 빌더 패던, 로그생성등 다양한 방명사용가능

📚Lombok  단점

 

- 코드가 간소화 되어 직관성이 없다고도 함
- 롬복의 @Data 어노테이션이나 @toString 어노케이션으로 자동 생성되는 toString()메서드는 
  순환 참조 또는 무한재귀호출 문제로 인해 StackOverflowError가 발생할 수도 있음

 

⭐기존 setter, getter 메소드 형식

package com.example.lombok.dto;
 
public class UserDTO {
	
	private String userId; 
	private String userName;
 
 	/* userId [getter]메소드 */
	public String getUserId() {
		return userId;
	}
 
 	/* userId [setter]메소드 */
	public void setUserId(String userId) {
		this.userId = userId;
	}
 
 	/* userName [getter]메소드 */
	public String getUserName() {
		return userName;
	}
 
 	/* userName [setter]메소드 */
	public void setUserName(String userName) {
		this.userName = userName;
	}
    
}

 

⭐Annotation을 통한 구성

🧨@Getter & @Setter 어노테이션을 통하여 간략히 사용할수 있다.
package com.example.lombok.dto;

import lombok.Getter;
import lombok.Setter;
 
@Getter
@Setter
public class UserDTO {
	
	private String userId; 
	private String userName;
 
}

🧨이런형태로 전체 필드가 아닌 특정 필드에만 setter 메소드를 추가 할수 있다.
package com.example.lombok.dto;
 
import lombok.Getter;
import lombok.Setter;
 
@Getter
public class UserDTO {
	
	private String userId;
	
	@Setter
	private String userName;
}

 

@NonNull

- @NonNull을 통한 Null Check (메소드, 생성자, 매개변수)

 

@ToString

- ToString이 붙은 클래스는 toString() 메소드 생성
- 기본적으로 class명과 각 필드에 대한 값을 출력 
- @ToString.Exclude를 통한 출력 제한가능
- 부모클래스에 대한 toString적용이 필요시 부모 클래스에 @ToString(callSuper = true) 적용 필요

package com.example.lombok.dto;

import lombok.Getter;
import lombok.Setter;
 
@Getter
@Setter
@ToString(exclude = "userId")
public class UserDTO {
	
	private String userId; 
	private String userName;
 
}

이런식으로 선언시 Getter를 통해 호출하면 toString()이 적용되어 호출이 된다.
(exclude = "userId") 특정 값만 제외처리 가능

 

@EqualsAndHashCode

- 클래스에 대한 equals(Object other)과 hashCode()를 생성

 

@Data

- @ToString, @EqualsAndHashCode, @Getter, non-final필드에 대한 @Setter를 일괄 설정해주고 
  @RequiredArgsConstructor를 설정해줌

 

@RequiredArgsConstructor

- 초기화되지 않은 모든 final 필드, @NonNull 필드에 대한 생성자를 생성 및 의존성을 주입 가능
- @NonNull 필드의 경우 null check 구문 생성가능

package com.example.lombok.dto;
 
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
 
@Getter
@RequiredArgsConstructor
public class UserDTO {
 
	@NonNull
	private String userId; 
    
	private final String userName;
   
    // public UserDTO(String id, String name){ 
	//	this.id = id; this.name = name;
	// }
  
}

 

@NoArgsConstructor

- 매개변수가 없는 기본 생성자 생성
- 만약 불가능 하다면(final 필드 떄문에) 컴파일 에러가 발생
- 만약 @NoArgsConstructor(force = true)를 사용하면 컴파일 에러를 발생시키는 
대신 모든 final 필드는 기본값(0, false, null)로 초기화발생

package com.example.lombok.dto;
 
import lombok.NoArgsConstructor;
import lombok.ToString;
 
@Getter
@NoArgsConstructor
public class UserDTO {
 
	private String userId;
 
	private String userName;
	
	// public UserDto() {}
}

 

.@AllArgsConstructor

모든 필드에 대한 생성자를 생성 및 의존성을 주입받을 수 있으며,
@NonNull 필드에 대한 null check 구문을 생성할 수 있다.

package com.example.lombok.dto;
 
import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.ToString;
 
@Getter
@AllArgsConstructor
public class UserDTO {
 
	private String usrId;
 
	private String userName;
	
	// public UserDTO(String usrId, String userName) {
	//	this.usrId = usrId;
	//	this.userName = userName;
	//}
}

@Builder

- 빌더를 자동으로 작성
- 클래스에 작성하면 모든 필드에 대한 빌더생성 
- 원하는 필드에 대해서만 빌더를 작성하고 싶은 경우 생성자를 작성하고 
  그 위에 @Builder를 붙여주면 된다.
  
  package com.example.lombok.dto;
 
import lombok.Builder;
import lombok.Getter;
 
@Getter
public class UserDTO {
 
	private String id;
 
	private String name;
 
	@Builder
	public UserDTO(String id, String name) {
		this.id = id;
		this.name = name;
	}
}

 

package com.example.lombok.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
 
import com.example.lombok.dto.UserDTO;
 
@Controller
public class testController {
 
	@GetMapping("/")
	public String home(Model model) {
 
		UserDTO userDTO = UserDTO.builder().userId("userId").userName("userName").build();
		model.addAttribute("userDTO", userDTO);
 
		return "test";
	}
}

 

🌞Builder Pattern을 사용하는 이유는?

객체를 생성하는 방법에는 생성자 생성과 빌더를 통한 생성이 있다. 생성자를 통해서 객체를 생성을 하고 있는데 왜 빌더 패턴이 생겼는지 알아보자 

 

빌더 패턴(Builder Patten) 은 복잡한 객체의 생성과정과 표현방법을 분리하여 다양한 구성의 인스턴스를 생성하는 생성패턴이다. 

 

빌더 패턴(Builder Patten)을 알기 전에 기존 패턴에 대해서 알아보자.

 

🧨점층적 생성자 패턴

class Hamburger {
    // 필수 매개변수
    private int bun;
    private int patty;

    // 선택 매개변수
    private int cheese;
    private int lettuce;
    private int tomato;
    private int bacon;

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

    public Hamburger(int bun, int patty, int cheese, int lettuce, int tomato) {
        this.bun = bun;
        this.patty = patty;
        this.cheese = cheese;
        this.lettuce = lettuce;
        this.tomato = tomato;
    }
    

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

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

    ...
}
public static void main(String[] args) {
    // 모든 재료가 있는 햄버거
    Hamburger hamburger1 = new Hamburger(2, 1, 2, 4, 6, 8);

    // 빵과 패티 치즈만 있는 햄버거
    Hamburger hamburger2 = new Hamburger(2, 1, 1);

    // 빵과 패티 베이컨만 있는 햄버거
    Hamburger hamburger3 = new Hamburger(2, 0, 0, 0, 0, 6);
}

 

🧨자바 빈(Java Beans) 패턴

 

class Hamburger {
    // 필수 매개변수
    private int bun;
    private int patty;

    // 선택 매개변수
    private int cheese;
    private int lettuce;
    private int tomato;
    private int bacon;
    
    public Hamburger() {}

    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 setLettuce(int lettuce) {
        this.lettuce = lettuce;
    }

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

    public void setBacon(int bacon) {
        this.bacon = bacon;
    }
}
public static void main(String[] args) {
    // 모든 재료가 있는 햄버거
    Hamburger hamburger1 = new Hamburger();
    hamburger1.setBun(2);
    hamburger1.setPatty(1);
    hamburger1.setCheese(2);
    hamburger1.setLettuce(4);
    hamburger1.setTomato(6);
    hamburger1.setBacon(8);

    // 빵과 패티 치즈만 있는 햄버거
    Hamburger hamburger2 = new Hamburger();
    hamburger2.setBun(2);
    hamburger2.setPatty(1);
    hamburger2.setCheese(2);

    // 빵과 패티 베이컨만 있는 햄버거
    Hamburger hamburger3 = new Hamburger();
    hamburger3.setBun(2);
    hamburger2.setPatty(1);
    hamburger3.setBacon(8);
}

 

 

 

 

 

 

 

 

 

1. 생성자 파라미터가 많을 경우 가독성이 좋지 않다. 

🧨생성자 형태 
Bag bag = new Bag("name", 1000, "memo", "abc", "what", "is", "it", "?");

🧨Builder형태
Bag bag = Bag.builder() 
                .name("name") 
                .money(1000) 
                .memo("memo") 
                .letter("This is the letter") 
                .box("This is the box") 
                .build();

 

Ref. https://jiurinie.tistory.com/20

Ref. https://pig-programming.tistory.com/97

Ref. https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-%EB%B9%8C%EB%8D%94Builder-%ED%8C%A8%ED%84%B4-%EB%81%9D%ED%8C%90%EC%99%95-%EC%A0%95%EB%A6%AC

 

 

 

 

 

 

 

 

 

 

728x90
반응형

'❤️01_Java > 03_Library' 카테고리의 다른 글

#Tika 라이브러리  (0) 2023.03.14

댓글