MyungHoon_Ju

static keyword with OOP

1. declarative and imperative

a) 다음은 명령형과 선언형 작성방식의 차이를 보여준다.

imperative style

public static int between(int l, int r, int x) {
  return Math.min(Max.max(l, x), r);
}

작성하는 순간 바로 연산을 처리하여 값을 얻게된다

int y = Math.between(5, 9, 13);

declarative style

class Between implements Number {
  private final Number num;
  Between(Number l, Number r, Number x) {
    num = new Min(new Max(l, x), r);
  }

  @Override
  public int intValue() {
    return num.intValue();
  }
}

중간값을 구한다라는 선언을 하였다.
아직 CPU에게 연산을 수행하라 명령하지 않았다.
intValue() 가 정말 필요한 시점에 호출하여 사용할 수 있다.

Number y = new Between(5, 9, 13);


b) 만약 중간값을 구하는 방식을 변경하고 싶다면?

class Between implements Number {
  private final Number num;
  Between(Number l, Number r, Number x) {
    this(new Min(new Max(l, x), r));
  }

  Between(Number num) {
    this.num = num;
  }
}

declarative - 다른 객체와 “조합” 할 수 있다(다형성)

Integer x= new Between(new IntegerWithOtherWay(5, 9, 13));

imperative - 재작성 외에 방법이 없다

int y = Math.between(5, 9, 13);


c) 가독성 & 응집력은 어떤 것이 더 좋을까?

List evens = new ArrayList<>();
for (int num : numbers) {
 if (num % 2 == 0) {
  evens.add(num);
 }
}

List evens = new Filtered(...)

List evens = new Filtered ( numbers,   new Predicate() {     @Override     public boolean suitable(Integer number) {       return number % 2 == 0;     }   } );

2. utility and singleton

Utility(helper)

Singleton pattern

class Math {
  private static Math INSTANCE = new Math();
  private Math() {}
  public static Math getInstance() {
    return Math.INSTANCE;
  }
  public static void setInstance(Math other) {
    INSTANCE = other;
  }
  public int max(int a, int b) {
    if (a < b) {
      return b;
    }
    return a;
  }
}

다음은 어떤점이 다른가?

Math.max(1, 2); //Utility
Math.getInstance.max(1, 2); //Singleton

둘의 차이점은 setInstance() 사용하여 캡슐화된 객체를 교체가능한 것 외에 다를 것이 없다
둘의 공통점은 global scope 로서 존재한다