데브코스 백엔드 3기 3일차


1. 전통적인 Interface의 기능

호출하는 쪽의 dependency를 끊어주고 의존성을 역전시켜주어서 결합도를 낮추는 효과

  1. 구현을 강제
  2. 다형성 제공
  3. 결합도를 낮추는 효과(의존성을 역전)
public interface Login {
    void login();
}
public class UserService implements Login{

    private Login login;

    public UserService(Login login) {
        this.login = login;
    }

    @Override
    public void login() {
        login.login();
    }
}
  • login.login() : Login interface를 구현하고 있는 구상체를 이용해서 로그인함 -> Login에 의존
  • public UserService(Login login) { : 호출하는 쪽의 dependency를 끊음
  • UserService와 Login 은 결합성을 가짐 => 추상체(Login)와 결합 = 결합도가 낮다
    • Login 대신 KakaoLogin, NaverLogin 등의 구상체와 결합하게 되면 강한 결합성을 가지게 됨
public class Main {
    public static void main(String[] args) {
        UserService userService = new UserService(new KakaoLogin());
        userService.login();
    }
}
  • 다형성을 통해 의존성을 외부에 맡기는것 = 의존성을 낮춘다
    => 여러가지 기능을 수행할 수 있는 잠재성


1

2

  • implements를 통해 화살표방향이 반대로 됨 -> Dependency Inversion 의존역전
    => 중간에 추상체를 통해서 결합하자 = 의존성을 역전해서 의존하자
    => 결합도가 낮아지니까



2. default method

Java 8부터 기능개선 -> 인터페이스가 구현체를 가질 수 있게 됨
=> default method를 갖는 interface를 어떤 클래스가 구현하면, 그 클래스에서 interface의 default method를 오버라이드 하지 않아도 기능을 사용할수 있음


default method 존재이유

  • 자바의 신책에서
    zz
    • 기존에 존재하던 interface를 구현한 class 사용중
      interface 보완과정에서 추가구현해야 할 혹은 필수적으로 존재해야 할 메소드가 있다면?
    • 이미 이 인터페이스를 구현한 클래스와의 호환성이 떨어지게 됨
      => 이러한 경우 default 메소드 추가하면 -> 하위 호환성은 유지 + interface의 보완 진행가능
      => OCP(개방 폐쇄 원칙)에서 확장에 개방되어 있고, 변경에 닫혀있는 코드 설계가능


interface MyInterface {
    void method1();
    void method2();

    default void sayHello() {
        System.out.println("Hello World");
    }
}
  • Adapter 역할
    • implements MyInterface 하게되면 구현하지 않는 빈 메서드를 다 가질 필요 없는데도 다 가질 수 밖에 없게 됨
      MyInterface -> Interface를 구현한 MyInterfaceAdapter -> A extends MyInterfaceAdapter 를 통해 필요한 메서드만 오버라이딩해서 해결
    • default method -> Adapter 역할하는 구현체 불필요
  • 구현 변경 없이 기능확장 가능
    • implements MyInterface 추가만으로 구현의 변경없이 기능을 추가할 수 있음(이미 기능이 들어가있으니까)


static method 도 가질 수 있음

함수(function)제공자가 됨

  • method : class 안에서 구현된(종속된) 함수
  • function : java 8부터~, 독립적으로 존재하는 함수, 여러 문장들이 하나의 기능을 구현하도록 구성한 것



3. Functional Interface

함수형 인터페이스 : 추상메서드가 하나만 존재하는 인터페이스
Functional Interface에 있는 추상메서드를 함수라고 부름 (default, static method 존재해도 추상메서드는 하나라면 Functional Interface)
=> 익명 클래스를 만들 수 있다

@FunctionalInterface
public interface MySupply {
    String supply();
}
  • @FunctionalInterface
  • Interface는 new 불가 -> 구현한 구현체를 만들어서 new해야 그안의 기능 사용가능
    • 구현한 구현체(임시적인 클래스)를 생성해야함
    • interface를 임시 생성한다면?
  • interface 임시 생성하기 : 익명클래스를 사용해서 -> interface의 instant를 생성하고 구현을 바로 정의한다!


  • 구현체 A클래스 생성한 경우를
public class Main {
    public static void main(String[] args) {
    
        new class A implements MySupply{
            @Override
            public String supply() {
                return "Hello World";
            }
        }.supply();    
    }
}
  • 익명클래스를 이용해서 interface instant 임시생성
new MySupply(){
    @Override
    public String supply() {
        return "Hello World";
    }
}.supply();

or

MySupply mySupply = new MySupply(){
    @Override
    public String supply() {
        return "Hello World";
    }
};

mySupply.supply();
- 호출된다는 것은 그 인터페이스 타입 객체가 구현된 곳에 있음 의미


=> java.util.function package


java.util.function package

4가지 API 함수형 인터페이스

  • Function<T, R> : 작업으로 타입 변환할 때
    • apply() : 1개 인자값 받고 1개 객체 return
  • Consumer : 작업은 하되 딱히 리턴되는 것이 없을 때
    • accept() : 인자값 존재, 반환값은 존재 안함
  • Predicate : 작업하면서 true, false 작업 필요할 때
    • predicate() : 인자값을 받고 boolean return
  • Supplier : 작업을 지연시켜야할 때 혹은 특정 시점에만 작업될 수 있도록 할 때
    • suplly() : 인자값은 없고 결과값은 나오는



4. Lamda 표현식

익명 메서드를 사용해서 표현하는 방법

  • FunctionalInterface의 경우 사용가능
    • 구현해야 하는 메서드 어차피 하나 => 뻔한거 다 지우자 => 간결하게 표현가능


MySupply mySupply = new MySupply(){
    @Override
    public String supply() {
        return "Hello World";
    }
};
mySupply.supply();

=> 익명메서드를 사용해서 간결한 interface instant 생성
(곰튀김님 : “override 할거, public String supply() 뻔하니까 지우고, new MySupply 할거 뻔하니까 지우고!”)

MySupply mySupply2 = () -> {
    return "Bye World";
};


Lamda 장점

  • 불필요한 코드를 줄여 코드 간결, 가독성 높임
  • 람다는 지연연산 수행 -> 불필요한 연산 최소화 + 멀티쓰레드 활용하여 병렬처리 가능


Lamda 단점

  • 람다를 사용하면서 만든 익명함수는 재사용 불가능
    -> 비슷한 함수 코드가 중복되어 오히려 코드의 가독성을 해칠 수도 있음


Generic

JDK 1.5 이전 : 여러 타입을 사용하는 대부분의 클래스나 메소드에서 인수나 반환값으로 Object 타입 사용
-> 반환된 Object 객체를 원하는 타입으로 타입 변환해야함(오류가 발생할 가능성)
=> 하지만 JDK 1.5부터 도입된 제네릭 -> 컴파일 시 미리 타입이 정해짐
  타입 검사나 타입 변환과 같은 번거로운 작업 생략가능

@FunctionalInterface
public interface MySupply<T> {
    T supply();
}
@FunctionalInterface
public interface MySupply<T> {
    void supply(T t);
}
@FunctionalInterface
public interface MySupply<IN, OUT> {
    OUT supply(IN t);
}
  • 위와 같이 선언된 generic class 생성 시, 타입 변수 자리에 사용할 실제 타입 명시해야 함
MySupply<Integer> mySupply = () -> "Hello World";


Method Reference

불필요한 매개변수를 제거하고 다음과 같이 :: 기호를 사용하여 표현

  • 입력값을 변경없이 바로 사용하는 경우 사용 = 입력값을 변경하지 말라는 코딩방식
    => 개발자의 개입차단 -> 안정성 얻음
DoubleUnaryOperator oper;

oper = (n) -> Math.abs(n); // 람다 표현식
oper = Math::abs; // 메소드 참조


함수형 프로그래밍

  • 저자 John Hughes, ‘Why Functional Programming Matters’

zzz



일기(회고)

  • 1,2주차는 널널한 주라고 하는데 난 왜 안 널널하지?
    • 오늘은 강의를 너무 오래들었다
    • TIL 작성하면서 구글링 하다보니 또 오래걸렸다
    • 계산기 과제부터 시작하기


  • 흑9님이 PR규칙과 과정에 대해 알려주셨다
    처음해보는 PR
    얼른 과제해서 코드리뷰 받아야지


  • IntelliJ 단축키 파악하면서 실습을 따라가려고 하니까 조금 오래걸리지만 직접 해보니 빠르게 익숙해진다(아마도 ㅎㅎ)


  • IntelliJ 콘솔에 한글깨짐 -> Editor File Encoding setting 변경 후 Gradle re-build 전 clean 한번 해주기
    • Gradle과 같은 빌드도구를 사용하는 경우 컴파일을 한 번 실행한 후 변경된 내용이 없다면 재컴파일 하지 않음
      따라서 한글 깨짐 현상이 발생한 경우 초기화 명령을 실행한 후 다시 컴파일하기
      참고
    • Transparent native-to-ascii conversion : 유니코드로 된 한글도 인코딩이 필요한 경우 체크하기


  • Interface에 대해 강의를 듣는데 default method, Functional Interface, Lamda 개념만 알고 써본적이 없어서 낯설게 느껴졌다
    Interface를 사실 AOP때문에 써본거 빼곤 써본적이 없었다
    이번 계산기과제에서는 사용해보아야g,,
    default method의 존재이유와 Functional Interface, Lamda의 장점에 대해 의문이 들어서 추가로 찾아보았다


  • 오늘의 단체사진
    • 다들 단디 꾸미고온거부터 귀여움

1019


  • 오늘의 귀여움
    • 다른팀 놀러가겠다고 줄 선 우리 귀엽ㅎ

1019-3



Reference
데브코스 백엔드 강의
https://velog.io/@heoseungyeon/%EB%94%94%ED%8F%B4%ED%8A%B8-%EB%A9%94%EC%84%9C%EB%93%9CDefault-Method
https://siyoon210.tistory.com/95
http://ruaa.me/why-functional-matters/
https://jinbroing.tistory.com/229

업데이트: