[인프런 워밍업 클럽] 과제3

Jiwon·2024년 5월 2일
post-thumbnail

📚 인프런 강의와 스터디를 바탕으로 한 과제를 풀이한 포스트입니다.

[키워드]

익명 클래스(Anonymous Class)

  • 이름이 없고, 주로 단일 인스턴스를 생성하고 해당 인스턴스를 사용하는 간단한 작업에 사용된다. 인터페이스를 구현하는 익명 클래스가 가장 흔하다.

  • 익명 클래스를 사용하는 이유: 프로그램 내에서 일시적(단발성)으로 한번만 사용되어야 하는 객체일 경우 익명 클래스로 구현하는 것이 효율적이다. 일반 클래스를 사용하는 것의 장점인 '재사용성', '확장성' 측면에서 불리할 때는 익명 클래스를 이용하는 것이 합리적이며 유지 보수에 유리하다.

  • 주요 특징
    1) 이름 없음: 클래스 정의와 동시에 인스턴스를 생성한다.
    2) 인터페이스 구현: 주로 인터페이스를 구현하는데 사용되며, 인터페이스를 구현함으로써 해당 인터페이스에 선언된 메서드들을 구현할 수 있다.
    3) 인스턴스 생성: 클래스 정의와 함께 바로 인스턴스를 생성하는 방식이므로 단 한번의 사용을 목적으로 한다.
    4) 지역적인 성격: 주로 특정 메서드 내에서 인터페이스를 구현하고 사용하는데 자주 사용되며, 이는 해당 클래스가 지역적인 성격을 가짐을 의미한다.

아래는 Spring에서 Database를 사용할 때, 사용자가 입력한 sql을 query를 이용해UserResponse 타입으로 바꿔주는 익명 클래스를 구현한 코드이다.

@GetMapping("/user")
public List<UserResponse> getUsers() {
	String sql = "SELECT * FROM user";
    // 유저 정보를 우리가 선언한 타입인 userResponse로 바꿔준다.
	return jdbcTemplate.query(sql, new RowMapper<UserResponse>() {
		@Override
		public UserResponse mapRow(ResultSet rs, int rowNum) throws SQLException {
			long id = rs.getLong("id");
			String name = rs.getString("name");
			int age = rs.getInt("age");
			return new UserResponse(id, name, age);
		}
	});
  • query() 메서드로 전달된 인자로 익명 클래스를 생성한다. 이 익명 클래스는 UserResponse 타입의 RowMapper 인터페이스를 구현한다.

  • 익명 클래스에서는 mapRow(ResultSet rs, int rowNum)을 오버라이드한다. 메서드에서의 ResultSet 객체에는 결과가 담겨있다. 이 객체에 getType("필드이름") 을 사용해서
    실제 값을 가져온다.

  • id, name, age를 받는 UserResponse의 생성자를 만든다.

람다

  • 람다식: 메서드를 하나의 식으로 표현한 것. 기존 메서드보다 훨씬 간략하게 표현할 수 있게 되고, 메서드의 이름과 반환값이 없어지므로 익명함수라고도 한다.

앞에서의 익명 클래스를 람다식으로 바꾸면 다음과 같다.

@GetMapping("/user")
    public List<UserResponse> gerUser() {
        String sql = "SELECT * FROM user";
        // 유저 정보를 우리가 선언한 타입인 userResponse로 바꿔준다.
        return jdbcTemplate.query(sql, (rs, rowNum) -> {
            long id = rs.getLong("id");
            String name = rs.getString("name");
            int age = rs.getInt("age");
            return new UserResponse(id, name, age);
        });
    }
  • 위 코드에서 알 수 있듯 익명 클래스에서의 반환타입, 메서드 이름을 모두 생략하고 매개 변수만 사용하여 람다식을 작성했다. 그 후의 과정은 익명 클래스에서와 동일하다.

함수형 프로그래밍

  • 대입문이 없는 프로그래밍
  • 가독성을 높이고 유지보수를 용이하게 프로그래밍하는 것
  • 함수형 프로그래밍은 부수효과(Side Effect)가 없기 때문에 안전성을 보장받는다.
  • Java에서 함수형 프로그래밍을 돕는 것 중 대표적인 것에 Stram API, 람다식, 함수형 인터페이스다.

스트림 API

  • 데이터를 추상화하고, 처리하는데 자주 사용되는 함수들이 정의되어 있다.
  • 데이터의 종류에 상관없이 일관적으로 데이터를 처리할 수 있으므로 재사용성을 높일 수 있다.
  • 즉 원본의 데이터를 변경하지 않고 간략하게 작성할 수 있다.

@FunctionalInterface

  • 함수형 인터페이스: 1개의 추상 메서드를 갖는 인터페이스
  • 함수형 인터페이스는 @FunctionalInterface 어노테이션을 사용한다. 해당 인터페이스가 함수형 인터페이스 조건에 맞는지 검사해준다.
  • 일반적으로 자주 쓰이는 형식의 메서드를 함수형 인터페이스로 미리 정의해 놓은 패키지
  • 이 패키지의 인터페이스를 적절히 활용하면 재사용성을 높일 수 있고 유지보수 측면에서도 좋다.

주요 함수형 인터페이스

  • Predicate: 인자 하나를 받아서 boolean 타입 리턴.
  • Consumer: 인자 하나를 받고 아무것도 리턴하지 않음.
  • Supplier: 인자를 받지 않고 T 타입의 객체 리턴.
  • Function: T 타입 인자를 받아서 R 타입 리턴.
  • Comparator: T 타입 인자 두 개를 받아서 int 타입 리턴.
  • Runnable: 객체를 받지 않고 리턴도 하지 않음. 이름 그대로 실행만 할 수 있음.
  • Callable: 객체를 받지 않고 T 타입 객체를 리턴.

메소드 참조(method reference)

  • 람다식이 단 하나만의 메소드를 호출하는 경우에 해당 람다식에 불필요한 매개변수를 제거하고 사용할 수 있도록 해준다.
  • 예를 들어, (base, exponent) -> Math.pow(base, exponent); 다음과 같은 람다식을
    Math::pow; 메소드 참조를 사용하면 이렇게 작성할 수 있다.

[질문]

자바의 람다식은 왜 등장했을까?

  • 익명 클래스가 갖는 장점에 더해 기존 메서드보다 씬 간략하게 코드를 작성할 수 있다.

람다식과 익명 클래스는 어떤 관계가 있을까? - 람다식의 문법은 어떻게 될까?

  • 익명 클래스를 간략화하여 표현한 것이 람다식으로, 익명 클래스 작성시 필요한 반환타입, 메서드 이름 등을 생략하여 작성할 수 있다.

[Reference]

profile
écoute les murmures du cœur

0개의 댓글