티스토리 뷰

  • 자바9의 모듈 시스템은 모듈을 정의하는 문법을 제공한다.
  • 이를 이용해 패키지 모음을 포함하는 모듈을 정의할 수 있다.
  • 자바8에서는 인터페이스를 쉽게 바꿀 수 있도록 디폴트 메서드를 지원한다.
  • 메서드 본문을 클래스 구현이 아니라 인터페이스의 일부로 포함시킨다.
  • 하나의 예시로 List라는 인터페이스에 디폴트 메서드 sort()가 추가되어 List에 바로 sort를 할 수 있게 되었다.
  • 자바8 이전에는 List를 구현하는 모든 클래스가 sort를 구현해야 했지만 자바8이후부터는 디폴트 sort를 구현하지 않아도 된다.
  • 이런 경우 다중상속이 문제가 될 수 있다. 다이아몬드 상속과 같은 경우가 발생할 수 있다는 것이다. 이에 대한 해결책은 나중에 알아보도록 하자.
  • 자바8에서는 Optional<T> 클래스를 제공한다. 널포인터 예외를 피할 수 있도록 도와주는 클래스이다.

<챕터 2>

동적 파라미터화를 활용하면 자주 바뀌는 요구사항에 효과적으로 대응할 수 있다.

동적 파라미터화는 아직 어떻게 실행할 것인지 결정하지 않은 코드 블록을 의미한다.

public class Apple {
    private Integer weight;
    private Color color;

    public Apple(Integer weight, Color color) {
        this.weight = weight;
        this.color = color;
    }

    public Integer getWeight(){
        return weight;
    }

    public Color getColor(){
        return color;
    }
}
public enum Color {
    RED,
    GREEN
}

public static List<Apple> filterGreenApples(List<Apple> inventory){
        List<Apple> result = new ArrayList<>();
        for(Apple apple: inventory){
            if(GREEN.equals(apple.getColor())){
                result.add(apple);
            }
        }
        return result;
    }

위 코드에서는 초록색을 가진 사과들만 골라 result에 넣고 있다.

만약 빨간색, 혹은 다른 다양한 색들을 골라내는 함수가 필요하다면 함수를 계속 만드는 것은 부적절하다.

public static List<Apple> filterApplesByColor(List<Apple> inventory, Color color){
        List<Apple> result = new ArrayList<>();
        for(Apple apple: inventory){
            if(color.equals(apple.getColor())){
                result.add(apple);
            }
        }
        return result;
    }

이렇게 파라미터에서 color를 받아와 비교를 하면 좀 더 나은 코드가 된다.

List<Apple> greenApples = filterApplesByColor(inventory, GREEN);
List<Apple> redApples = filterApplesByColor(inventory, RED);

이제 이렇게 함수를 호출할 수 있게된다.

하지만 만약 무게와 같은 다른 필드를 비교하고 싶다면, 이 방법은 좋은 방법이 아니게 된다. 소프트웨어공학의 DRY(같은 코드를 반복하지 말 것) 원칙을 어기게 되는 것이다.

  • 동적 파라미터화

사과의 어떤 속성에 기초해 불리언값을 반환하는 방법이 있다.(사과가 초록색인가? 와 같은 것)

참 또는 거짓을 반환하는 함수를 프레디케이트라고 한다. 선택 조건을 결정하는 인터페이스를 정의하자.

public interface ApplePredicate {
    boolean test(Apple apple);
}
public class AppleHeavyWeightPredicate implements ApplePredicate {

    @Override
    public boolean test(Apple apple) {
        return apple.getWeight() > 150;
    }
}
public class AppleGreenColorPredicate implements ApplePredicate {

    @Override
    public boolean test(Apple apple) {
        return GREEN.equals(apple.getColor());
    }
}
public static List<Apple> filterApplesByColor(List<Apple> inventory, ApplePredicate p){
        List<Apple> result = new ArrayList<>();
        for(Apple apple: inventory){
            if(p.test(apple)){
                result.add(apple);
            }
        }
        return result;
    }

이제 어떤 종류의 필드를 비교하고 싶어도 하나의 메서드로 활용가능하다.

public class AppleRedAndHeavyPredicate implements ApplePredicate {
    @Override
    public boolean test(Apple apple) {
        return RED.equals(apple.getColor()) && apple.getWeight() > 150;
    }
}

이렇게 여러개의 필드를 비교하는 기능까지 하나의 함수 내에 적용시킬 수 있게된다.

List<Apple> redApples = filterApples(inventory, new ApplePredicate(){
            public boolean test(Apple a){
                return RED.equals(a.getColor());
            }
        });

익명 클래스를 활용해보았다.

많은 공간의 코드를 익명클래스가 차지하고, 많은 프로그래머들이 익명클래스에 익숙하지 않다. 코드의 장황함은 나쁜 특성이다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
글 보관함