Heestory

[코드 개선]파라미터가 많을 때 본문

개발(0)/Java

[코드 개선]파라미터가 많을 때

까만밀가루 2023. 8. 17. 13:37

코드 작성 중에 넘기는 파라미터 개수가 3개에서 점점 많아지더니 결국 7개 되었고 이를 가독성, 유지보수, 솔루션 개발 중이기 때문에 확장성을 위해 코드를 개선하기로 하였다.

//무수히 많은 파라미터..
DmSendCallable sendRunnable = new DmSendCallable(sqlSessionFactory, dm_input_no, dm_link_key, filePath, atch_filePath, sender);

 

파라미터 많을 경우

글 검색 시 '파라미터 많을 때' 검색해보니 빌더 패턴이 나왔고

GPT는 파라미터 객체, 빌더 패턴을

회사 자체 내부 소스에선 map을 이용하여 전달 중이었다.

그외 지인 회사에선 enum객체를 쓰고 있었는데

나는 빌더패턴, 파라미터 객체, map 이용에 대해 좀 더 자세히 알아보기로 한다.

 


파라미터 객체 생성

: 관련된 파라미터를 하나의 객체로 묶어서 전달하는 방법

이의 경우 파라미터를 객체로 묶기 위한 클래스를 별도로 생성해야 한다.

  • 장점
    - 관련된 파라미터의 그룹화
    - 높은 타입 안정성
    - 불필요한 파라미터들을 전달하지 않게 제어
  • 단점
    - 파라미터 객체를 정의하고 생성해야하기 때문에 조금 더 코드 작성
    - 파라미터가 여전히 많은 경우, 객체의 생성이 복잡

<예제>

//별도의 파라미터 담는 클래스(VO)
public class DmSendParams {
    private SqlSessionFactory sqlSessionFactory;
    private int dmInputNo;
    private String dmLinkKey;
    private String filePath;
    private String atchFilePath;
    private PostSender sender;

    public DmSendParams(SqlSessionFactory sqlSessionFactory, int dmInputNo, String dmLinkKey,
                        String filePath, String atchFilePath, PostSender sender) {
        this.sqlSessionFactory = sqlSessionFactory;
        this.dmInputNo = dmInputNo;
        this.dmLinkKey = dmLinkKey;
        this.filePath = filePath;
        this.atchFilePath = atchFilePath;
        this.sender = sender;
    }
}

 

DmSendParams params = new DmSendParams(sqlSessionFactory, dm_input_no, dm_link_key, filePath, atch_filePath, sender);
DmSendCallable sendRunnable = new DmSendCallable(params);

 

 

 

Map 사용

: 여러 파라미터들을 하나의 맵으로 묶어서 전달하는 방법

  • 장점
    - 유연성 있으며 언제든지 파라미터 추가 및 제거 가능
    - 동적으로 파라미터 변경 가능
  • 단점
    - 낮은 타입 안정성, 올바른 키와 타입을 매칭시키는 책임이 개발자에게 있음(내가 초반 많이 겪음..)
    - 가독성이 떨어질 수 있음

<예제>

Map<String, Object> params = new HashMap<>();
params.put("sqlSessionFactory", sqlSessionFactory);
params.put("dm_input_no", dm_input_no);
params.put("dm_link_key", dm_link_key);
params.put("filePath", filePath);
params.put("atch_filePath", atch_filePath);
params.put("sender", sender);

DmSendCallable sendRunnable = new DmSendCallable(params);

 

 

빌더 패턴(내가 이번에 적용한 코드)

:복잡한 파라미터를 가진 객체를 생성할 때 유용한 패턴. 

  • 장점
    - 복잡한 객체 생성을 가독성 있게함
    - 필요한 파라미터만 설정할 수 있어, 불필요한 파라미터 전달하지 않게 제어 가능
    - 높은 타입 안정성
  • 단점
    - 파라미터 설정하는 과정이 추가
    - 빌더 패턴에 대한 코드가 다소 길어질 수 있음

<실제 수정 코드>

DmSendCallable sendRunnable = new DmSendCallable.Builder()
							.sqlSessionFactory(sqlSessionFactory)
							.dmInputNo(dm_input_no)
							.dmLinkKey(dm_link_key)
							.sendTypeCd(sendTypeCd)
							.filePath(filePath)
							.atchFilePath(atch_filePath)
							.sender(sender)
							.build();
	private DmSendCallable(Builder builder) {
		this.sqlSessionFactory = builder.sqlSessionFactory;
		this.dm_input_no = builder.dmInputNo;
		this.dm_link_key = builder.dmLinkKey;
		this.sendTypeCd = builder.sendTypeCd;
		this.filePath = builder.filePath;
		this.atch_filePath = builder.atchFilePath;
		this.sender = builder.sender;
	}

	public static class Builder {
		private SqlSessionFactory sqlSessionFactory;
		private int dmInputNo;
		private String dmLinkKey;
		private String sendTypeCd;
		private String filePath;
		private String atchFilePath;
		private PostSender sender;

		public Builder sqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
			this.sqlSessionFactory = sqlSessionFactory;
			return this;
		}

		public Builder dmInputNo(int dmInputNo) {
			this.dmInputNo = dmInputNo;
			return this;
		}

		public Builder dmLinkKey(String dmLinkKey) {
			this.dmLinkKey = dmLinkKey;
			return this;
		}

		public Builder sendTypeCd(String sendTypeCd) {
			this.sendTypeCd = sendTypeCd;
			return this;
		}

		public Builder filePath(String filePath) {
			this.filePath = filePath;
			return this;
		}

		public Builder atchFilePath(String atchFilePath) {
			this.atchFilePath = atchFilePath;
			return this;
		}

		public Builder sender(PostSender sender) {
			this.sender = sender;
			return this;
		}

		public DmSendCallable build() {
			return new DmSendCallable(this);
		}

 

1.왜 빌더 패턴 선택하였는지?

: 위에 말했듯 개발 중인 솔루션이기 때문에 훗날 코드에 대한 확장성이 제일 유연하다고 판단.

 

2.내부 클래스로 생성 한 이유?

: 하나의 클래스에서만 사용할 것이기 때문에 내부 클래스로 작성

  • 외부 클래스
    - 두 클래스의 크기가 상대적으로 큰 경우 두 클래스를 논리적으로 분리하여 코드를 보다 구조화
    - 두 클래스 간 의존성이 낮아지고 독립성을 유지
    - Builder 클래스를 재사용하거나 확장하기 쉬워짐
  • 내부 클래스
    - Builder 클래스를 외부에서 숨기고, 더 좁은 범위에서만 사용하고자 할 때 이용
    - Builder 클래스와 주 클래스 간의 밀접한 관련성이 있을 떄 내부 클래스로 함께 두면 응접성을 높임
    - 주 클래스가 Builder 클래스르 사용하는 것을 제한하거자 할 떄 사용

 

 

공부하는 과정에 점층적 생성자 패턴, 자바빈 패턴도 함께 알게 되었다.

테스트까지 완료하였고 디자인 패턴에 대해 아직 공부할 단계(?)가 아니라고 판단했는데, 알면 유용할 거 같아 디자인 패턴에 관한 도서를 하나 구매예정!

(사실 검색할 떄 빌더패턴만 나와서 공부하기 싫은데 너무 막막했는데 아래 참고 블로그가 설명을 잘해놨음!!)


https://dev-youngjun.tistory.com/197

 

빌더 패턴(Builder Pattern)

1. 빌더 패턴이란? 생성과 관련된 디자인 패턴으로, 동일한 프로세스를 거쳐 다양한 구성의 인스턴스를 만드는 방법 1-1. 정의(Definition) GoF 디자인 패턴 중 생성 패턴에 해당한다. 빌더 패턴은 복

dev-youngjun.tistory.com

 

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#%EB%B9%8C%EB%8D%94builder_%ED%8C%A8%ED%84%B4

 

💠 빌더(Builder) 패턴 - 완벽 마스터하기

Builder Pattern 빌더 패턴(Builder Pattern)은 복잡한 객체의 생성 과정과 표현 방법을 분리하여 다양한 구성의 인스턴스를 만드는 생성 패턴이다. 생성자에 들어갈 매개 변수를 메서드로 하나하나 받아

inpa.tistory.com