[디자인 패턴] 전략 패턴 Strategy Pattern in Spring(Java)

sua_ahn·2024년 4월 3일
0

디자인 패턴

목록 보기
1/2
post-thumbnail

프로그래밍을 축구로 비유하면, 알고리즘은 축구 기술, 디자인 패턴은 축구 전술과 유사하다. 경기를 승리로 이끌기 위해 전술을 배워보자!

전략 패턴

: 객체의 행위를 동적으로 바꾸고 싶은 경우, 직접 행위를 수정하지 않고 전략을 바꿔 주기만 함으로써 행위를 유연하게 확장하는 방법

  • 디자인 패턴의 목적에 따라 3가지로 분류 가능
    → 행동 패턴에 속함

    행동 패턴
    : 클래스와 객체들이 상호작용하고 역할을 분담하는 방법

  • 참고사이트의 예시로, 내비게이션 기능을 설명하였다.

    • 차, 도보, 자전거 등 이동수단에 따라 경로탐색 알고리즘이 달라지고, 알고리즘의 수정이 빈번할뿐만 아니라 탐색 조건에 따라 새로운 경로탐색 알고리즘이 추가될 수 있다.
    • 따라서, 내비게이션 기능에 차, 도보 등 각각의 경로탐색 알고리즘을 직접 사용하지 않고, 동일한 경로탐색 인터페이스로 묶어서 참조한다. 내비게이션 기능은 사용자가 선택하는 경로탐색 알고리즘에 따라서 실행될 수 있다.

 

패턴 다이어그램

Strategy Interface와 그 구현체인 Strategy, 인터페이스를 통해 구현체를 실행하는 Context로 구성된다.

 


Spring(Java) 예시

JDBC 연결을 예로 들어보자.

Strategy interface

Context가 전략을 실행하는 데 사용하는 메서드를 선언
(해당 예시는 함수형 인터페이스 사용)

@FunctionalInterface
public interface ConnectionCreator {

	Connection createConnection();
}

 

Context

전략 인터페이스를 통해서만 전략 객체와 통신
→ context가 strategy에 의존하지 않음
⇒ 새 알고리즘(전략) 수정, 추가 용이

public class JDBCRepository {
	
	private ConnectionCreator creator;
	
	public JDBCRepository(ConnectionCreator creator) {
		this.creator = creator;
	}

	public Map<String, Object> selectOne(String sql, List<String> columns){
		
		Map<String, Object> res = new LinkedHashMap<>();
		
		Connection conn = null;
		PreparedStatement pstm = null;
		ResultSet rset = null;
		
		try {
			conn = creator.createConnection();	// 호출; 어떤 알고리즘이 적용되는지 신경 쓰지 않아도 됨
			pstm = conn.prepareStatement(sql);
			rset = pstm.executeQuery();
			
			while(rset.next()) {
				for (String col : columns) {
					res.put(col, rset.getObject(col));
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return res;
	}
}

 

Client

  • 특정 전략 객체를 만들어 Context에 전달
    (해당 예시는 람다식으로 익명 클래스와 익명 함수를 구현해서 전달)

  • 런타임 중 알고리즘(전략) 변경 가능

public class App {
	
	public void start() {
		
		JDBCRepository jdbcRepository = new JDBCRepository(() -> {
			
			String url = "jdbc:h2:./test;MODE=MySQL;DATABASE_TO_LOWER=TRUE";
			Connection conn = null;

			try {
				conn = DriverManager.getConnection(url, "sa", "sa");
				conn.setAutoCommit(false);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			return conn;
		});
		
        System.out.println(
        	jdbcRepository.selectOne(
        		"select * from member"
        		, List.of("user_id","password")));
	}
}

 


*참고 사이트
https://refactoring.guru/ko/design-patterns/strategy

profile
해보자구

0개의 댓글