포스팅 전 먼저 서론을 조금 써보자면, 보통 학교 교과목 숙제에서는 흔히 생기지 않는 일이지만, 공모전이나 조금 덩치가 있는 프로그램 혹은 일을 하다보면 가장 많이 생기는 것이 있는 것 같아요. 


그것은 바로 "변화" 라는 생각이 드는데요


회사에서도 일을 하다보면, 기획이나 디자인 혹은 개발과정 중 여러 상황 등 기타 이유로 인하여, 심심치 않게 변화가 등장함을 알 수 있습니다.


변화란 나쁜 것인가? 라고 생각했을 때 전 아닌 것 같습니다. 어디서 흔히 들은 이야기론,

 

"프로젝트의 변화가 나쁜 게 아니라, 변화에 적응하지 못하는 개발자의 무능함이 나쁘다" 


이런게 있습니다. "변화를 사랑하는 개발자가 됩시다. ㅡㅡ^"


서론 부분에 변화에 대한 이야기를 쓴 이유는 함수형 프로그래밍의 4번째 포스팅인 동작 파라미터화(Behavior parameterization)와 관련된 이야기와 조금 관련이 있어서 조금 꺼내봤습니다.


이 이야기와 비슷한 포스팅을 아마, 



이 곳에서 진행을 했었습니다. 이 곳에서 진행한 코드를 조금 더 디테일하게 리뷰해보고자 합니다. (귀찮아서 그러는게 아닙니다. ㅡㅡ^)


copy&paste가 변화에 유연하지 못함과 그렇기 때문에 이를 해결하기 위한 객체지향적 관점에서 여러 디자인 패턴이 등장했고, 지난번에는 그 중 추상화 과정을 통해 전략패턴을 사용해보았음을 알 수 있습니다.


그 중 우리가 다시한번 살펴볼 곳은, 아래 코드입니다. 


/**
     * 사과 객체를 분류하기 위한 함수
     * 
     * @param appleList
     * @param appleFilter
     * @return
     */
    public static List<Apple> GetFilterApple(List<Apple> appleList, AppleFilterAble appleFilter) {
        ArrayList<Apple> resultList = new ArrayList<>();
 
        for (Apple apple : appleList) {
            if (appleFilter.isContain(apple)) {
                resultList.add(apple);
            }
        }
 
        return resultList;
    }
cs


우리는 보다 GetFilterApple을 유연하게 사용하기 위해 interface를 만들어 inContain 에 대한 명세를 추상화하였고, 사용처에서 익명클래스로 할일에 대한 최종 명세를 표기하였습니다. 아래와 같이 말이죠.


1
2
3
4
5
6
7
GetFilterApple(inventory, new AppleFilterAble(){
    @Override
    public boolean isContain(Apple apple){
        return "green".equals(apple.getColor());
    }
});
 
cs


여기에서 우린 isContain이라는 동작을 파라미터화(이번 포스팅의 주제)하여, GetFilterApple 메소드로 넘기게 되었고, 보다 더욱 변화에 유연하게 사용할 수 있게 되었습니다.


그러나, 이 곳에서 우리는 단지, inContain 이란 메소드를 넘기기 위해, 인터페이스를 만들고, 객체로 한번 감싸 넘기고 있습니다. 이런 과정이 보다 복잡하고, 어려운 작업이 될 수 있지 않을까요? (복잡한 것을 좋아하는 사람은 없습니다. ㅡㅡ^)


그렇기 때문에 람다 표현식과 메소드를 코드로 넘기는 방법 같은 방법이 제시 되었음을 알 수 있습니다. 아래는 지난번에 했던 람다표현식을 통해, 함수만 넘기는 예제입니다.


1
GetFilterApple(inventory, (Apple a) -> "green".equals(a.getColor()));
cs


우리는 동작을 추상화하고, 파라미터로 넘기는 것이 변화에 대해 유연함을 줄 수 있다는 것을 알았고, 함수형 프로그래밍을 통해 간결함까지 사용할 수 있음을 알 수 있게 되었습니다. 단순히 람다가 등장하여 코드가 짧아졌다는 것만을 알게 아니라, 이러한 전과정을 모두 알면 좋을 것 같아서 코드에 대한 리뷰를 다시 해보게 되었습니다.^^;



자바 8 인 액션
국내도서
저자 : 라울-게이브리얼 우르마(RAOUL-GABRIEL URMA),마리오 푸스코(MARIO FUSCO),앨런 마이크로프트(ALAN MYCROFT) / 우정은역
출판 : 한빛미디어 2015.04.01
상세보기


반응형
Posted by N'

포스트의 제목은 현재 읽고 있는 책인 "JAVA8 IN ACTION"의 첫 목차입니다.


"JAVA8 을 눈여겨봐야 하는 이유 세번째 포스트" 로는 JAVA8 에 봐야할 추가된 개념 몇가지를 더 소개하고자 합니다.


1. 디폴트 메소드 (default method)


JAVA8 에서는 기존의 interface에 디폴트 메소드란 개념을 추가했습니다. "JAVA8 IN ACTION"의 내용에 따르면, 더 쉽게 변화할 수 있는 인터페이스를 만들 수 있도록 메소드를 추가했다고 합니다. (그러나 아마 stream의 개념을 기존 만들어진 collection 클래스들에 모두 추가할 수 없었던 문제가 가장 크기 않았을까요? interface에 메소드를 추가하면 모두 구현하던지 해야하니깐? ㅡㅡ^)


즉 이 메소드로 인하여, 미래의 변화에 유연하게 대처할 수 있게 되었습니다. (변화를 사랑하는 개발자가 됩시다.^^)  


사용방법은 interface에 default란 키워드를 붙여 사용할 수 있습니다. 이 default 메소드는 계속 함수형 프로그래밍에서 언급하던 동시실행에 대해서 안전합니다. 즉 이 개념을 사용하여 코드로 넘기는 함수로 많이 이용할 수 있을 것으로 보이네요.


다중상속의 문제가 있어보이지만 이를 피할 수 있는 방법이 있다고 합니다




2. Optional<T>


Optional<T>의 개념을 사용하여 NULL 예외를 피할 수 있다고 합니다. 이 객체는 값을 가지거나 안가질 수 있는 컨테이너 객체(이를테면 Collection 등..)로 값이 없는 상황을 명시적으로 처리 가능합니다. 


(즉 해당 기능으로 인하여, null에 대한 방어코드를 없앨 수 있기를 바랍니다.)




3. 구조적 패턴 매칭


객체지향 프로그래밍에서 극혐으로 하는 if-else-then 문제를 수학적으로 쉽게 명시할 수 있다고 합니다. (포스트 시, 업데이트 할 것)





자바 8 인 액션
국내도서
저자 : 라울-게이브리얼 우르마(RAOUL-GABRIEL URMA),마리오 푸스코(MARIO FUSCO),앨런 마이크로프트(ALAN MYCROFT) / 우정은역
출판 : 한빛미디어 2015.04.01
상세보기




반응형
Posted by N'

포스트의 제목은 현재 읽고 있는 책인 "JAVA8 IN ACTION"의 첫 목차입니다.


"JAVA8 IN ACTION"에서 언급하는 프로그래밍 개념은 크게 세가지 정도로 보고 있습니다.


1. 스트림 처리 

- 이번 포스트에서 이야기 할것


2. 동작 파라미터화 

이곳을 참고 -> 2016/07/21 - [개발이야기/함수형 프로그래밍] - JAVA8 을 눈여겨봐야 하는 이유1 (메서드에 코드를 전달하는 기법)


3. 병렬성과 공유되는 가변 데이터

- 이번 포스트에서 이야기 할것


"JAVA8 을 눈여겨봐야 하는 이유 두번째 포스트" 로는 스트림 처리를 하려 합니다.


현재 보고 있는 책인 "JAVA8 IN ACTION" 에서는 스트림API에 대하여 "데이터베이스 질의 언어에서 표현식을 처리하는 병렬 연산을 지원하는 API" 라 정의하였습니다. 이는 고수준언어에서 어떠한 질의를 표현하면, 저수준에서 최적의 방법을 실행함을 의미합니다. (SQL 역시 질의어만 잘쓰면, 알아서 데이터를 빠르게 찾아주죠? ㅎㅎ)


일단 스트림에 대하여 알아봅시다.

스트림은 한번에 한개씩 만들어지는 연속적인 데이터 항목들의 모임입니다.

모든 일들은 이 스트림 단위로 끊어져 명령을 수행을 하는데,보통 유닉스에서는 파이프를 이용해 이를 연결하여 작업을 할 수 있습니다. 스트림API는 이러한 유닉스의 파이프라인을 메소드로 만들 수 있게 해주는 것이라 볼 수 있을 것 같습니다. (즉 메소드로 한층 감싸, 쉽게 파이프질을 할 수 있다 ㅡㅡ^)


그렇다면 병렬은?

일단 스트림 API를 사용하면 스레드를 사용하지 않고도 병렬성을 가질 수 있다고 합니다. "JAVA8 IN ACTION"에서는 공짜로 병렬성을 가진다는 표현을 쓰고 있습니다. stream의 처리 방식은 먼저 큰 stream 자체를 작은 stream 단계(즉 병렬이 가능한 단계)까지 분할하여 병렬적으로 처리합니다.) 아래 사진과 같이 말이죠. (JAVA8 IN ACTION에서 그림 참고)



즉 기존 collection 방식은 데이터를 어떻게 저장하고, 접근하는가에 중점을 두었다면 stream은 어떻게 데이터를 계산하는가에 중점을 두었다고 볼 수 있습니다. (즉 이러한 for문에 의한 외부반복 대신 필요 시점에 연산되는 내부반복을 통해, 거대한 데이터를 효과적으로 처리할 수 있게 되었습니다.)


스트림을 사용하기 위해서는 코드로 넘길 메소드는 동시 실행에 있어서 안전해야 합니다. 이 뜻은 메소드 자체에 상태가 없어, 실행에 있어서, thread-safe 함을 의미한다고 볼 수 있습니다. 즉 넘기는 메소드 내부에서 공유된 데이터 목록을 건드리면 문제가 있을 수 있겠죠? (예를 들어 덧셈을 하는데, 중간 녀석을 지운다던지...) 

이 것은 기존의 sychronized 라는 비싼 비용을 어느정도 대체해 줄 수 있을 것 같습니다.


Stream API에 대한 포스팅은 이 곳에서부터...




자바 8 인 액션
국내도서
저자 : 라울-게이브리얼 우르마(RAOUL-GABRIEL URMA),마리오 푸스코(MARIO FUSCO),앨런 마이크로프트(ALAN MYCROFT) / 우정은역
출판 : 한빛미디어 2015.04.01
상세보기






반응형
Posted by N'