본문 바로가기
Java/series

[Java 4편] 객체지향, 함수형프로그래밍, 람다식

by 무대포 개발자 2022. 7. 27.
728x90
반응형

목차는 Java series 에 있습니다.

[Java 4편] 객체지향, 함수형프로그래밍, 람다식

객체란?

  • 객체란 식별 가능한 개체 또는 사물입니다. 자동차처럼 구체적인 사물일 수도 있고, 시간처럼 추상적인 개념일 수 있습니다.
  • 객체는 구별 가능한 식별자, 행동, 변경 가능한 상태를 가질 수 있습니다.
    • Java 에서 식별자는 변수를 의미하며, 행동은 method, 변경 가능한 상태는 변수입니다.
    • 변경 가능한 상태를 통해 객체 간 통신을 할 때, 현실세계의 요구사항을 반영할 수 있습니다.
  • 객체는 다른 객체의 상태에 직접적으로 접근할 수도, 상태를 변경할 수도 없습니다.
    • 자바에서는 캡슐화를 통해 이를 제어할 수 있으며, 캡슐화를 이용하여 객체 지향 프로그래밍의 복잡성을 낮출 수 있습니다.
    • 예를 들어, 객체가 다른 객체에 접근해서 상태를 변경한다고 가정하면, 해당 상태를 변경하는 것을 추적하기 위해 많은 시간을 들여야합니다.
    • 객체가 다른 객체의 상태를 변경하기 위해서는 method (=행위) 을 통해 가능합니다.

객체지향 프로그래밍이란?

  • 객체가 중심이 되는 프로그래밍 방식이며, 객체 간의 행위를 통해 데이터를 처리하고 현실세계의 요구사항을 처리합니다.

예시

  • 커피숍에서 커피주문을 한다고 가정하겠습니다.
  • 손님은 커피를 주문하는 역할과 책임이 있습니다.
  • 캐시어는 주문을 받고 알리는 역할과 책임이 있습니다.
  • 바리스타는 커피주문을 받아 제조하는 역할과 책임이 있습니다.
  • 위 내용을 바탕으로 클래스는 3개가 나와야하고 (손님, 캐시어, 바리스타) 각 클래스에는 역할과 책임에 따른 상태와 행위가 있어야 합니다.

public class Customer {

}


public class Cashier {

    public xxx order(); 
}

public class Barista {

    public xxx makeCoffee();
}

장점

  • 객체 간의 행위를 통해 현실세계의 요구사항을 반영한다는 측면에서 이해하기 쉽다는 장점이 있습니다.
  • 행위와 상태를 통해 요구사항을 반영함으로써 강한 응집력과 약한 커플링을 가질 수 있습니다.

단점

  • 객체가 많아질수록 상태와 행위가 복잡해지며, 이는 시스템 복잡도가 커지는 것을 의미합니다. 즉, 새롭게 뭔가를 추가하거나 수정할 떄, side-effect 가 커질 수 있습니다.

함수형 프로그래밍이란?

  • 함수처럼 y = f(x) 에서 x 값이 동일하면 y 값도 동일하게 나옵니다.
  • 이 말을 프로그래밍에 적용해보면 함수의 조합으로 현실세계의 요구사항을 반영하는 것입니다.
  • 위와 같이 프로그래밍 한다면 상태와 행위를 고려할 필요 없으니 side-effect 가 줄어듭니다.

함수형 프로그래밍 특징

1급 객체

  • 함수를 변수나 데이터 구조 안에 담을 수 있습니다.
  • 함수를 파라미터로 전달할 수 있습니다.
  • 함수를 반환 값으로 사용할 수 있습니다.

고차 함수

  • 다른 함수를 인자로 받거나 다른 함수를 리턴하는 함수를 말합니다.
  • 일급 객체와 유사한 개념이지만 1급 객체는 함수를 변수처럼 다룬다는 것을 의미하고 고차 함수는 함수를 인자로 받거나 리턴하는 함수 자체를 뜻합니다.

불변성

  • 함수형 프로그래밍에서는 데이터가 변할 수 없는데, 이를 불변성 데이터라고 합니다.
  • 데이터 변경이 필요한 경우, 원본 데이터 구조를 변경하지 않고 그 데이터를 복사본을 만들어 그 일부를 변경하고, 변경한 복사본을 사용해 작업을 진행합니다.
  • 위와 같이 하는 이유는 멀티 스레드 환경에서 스레드 세이프를 보장하기 위함입니다.
  • int count = 0; new Thread(() -> { System.out.println(count); // compile 가능 } )
int count = 0;
new Thread(() -> {  
    count++; // compile error

    int tmp = count;
    tmp++; // compile O

}
)  

순수 함수

  • 동일한 입력에는 항상 같은 값을 반환해야 합니다.
    • 객체지향에서는 이를 장담할 수 없습니다. 상태에 따라 값이 달라질 수 있기에
    • 이런 측면에서 함수형 프로그래밍은 side-effect 가 없는 것입니다.
  • 함수의 실행은 프로그램의 실행에 영향을 미치지 않아야 합니다.

람다

  • 람다는 함수를 식으로 표현한 것입니다.

장점

  • () -> {} 와 같이 식으로 표현하며, 불필요한 코드를 줄이고 가독성을 높이기 위해 나왔습니다.
// 기존 자바
new Thread(new Runnable() {
   @Override
   public void run() { 
      System.out.println("Hello World..."); 
   }
}).start();

// 람다식
new Thread(()->{
      System.out.println("Hello World...");
}).start();
  • 람다식은 익명함수이며, 재활용이 안됩니다. 익명함수이기에 일급함수이며, 변수나 매개변수로 사용이 가능합니다. 즉, 함수형 프로그래밍과 같이 사이드 이펙트가 줄어들게 됩니다.
  • 병렬 처리에 좋습니다.

단점

  • 디버깅이 어렵습니다.
  • 익명함수이기에 재활용이 어렵습니다.

함수형 인터페이스

  • 함수형 인터페이스의 목적은 함수를 변수처럼 선언할 수 있다는 것입니다.
  • 람다식으로 생성된 함수는 함수형 인터페이스를 통해서 선언이 가능하며, 재활용이 가능해집니다.

댓글