본문 바로가기

전체 글

(69)
람다 표현식을 활용한 디자인패턴 - 팩토리 패턴 디자인 패턴은 유용하다. 람다 표현식을 디자인 패턴에 적용한다면 더 간결하게 구현할 수 있다. 팩토리 패턴 팩토리 패턴을 사용하면 객체를 인스턴스화 할때 로직을 클라이언트에 노출하지 않을 수 있다. 코드로 살펴보자. 게임 캐릭터를 만들려고 하는데 두 가지 직업이 있다.(전사, 마법사) 팩토리 패턴을 이용하여 구현하면 다음과 같다. 1 2 3 4 5 6 7 8 9 10 11 12 public class CharacterFactory { public static Character createCharacter(String character) { switch (character) { case "warrior": return new Warrior(30, 20); case "wizard": return new Wi..
람다 표현식을 활용한 디자인패턴 - 의무 체인 패턴 디자인 패턴은 유용하다. 람다 표현식을 디자인 패턴에 적용한다면 더 간결하게 구현할 수 있다. 의무 체인 패턴 한 객체가 어떤 작업을 처리하고 다른 객체로 결과를 전달하여 또 다른 작업을 처리할 때 사용된다. 자동차 객체가 있다고 가정하자. 자동차 객체는 연비와, 속도, 사이즈의 필드변수를 가지고 있다. 코드로 살펴보자. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class Car { private int fuelEfficiency; private int speed; private int size; public Car(final int fuelEfficiency, final int speed, final int size) { t..
람다 표현식을 활용한 디자인패턴 - 옵저버 패턴 디자인 패턴은 유용하다. 람다 표현식을 디자인 패턴에 적용한다면 더 간결하게 구현할 수 있다. 옵저버 패턴 어떤 이벤트가 발생했을 때 한 주체가되는 객체가 다른 옵저버가 되는 객체에게 알림을 보내야 하는 상황에 사용된다. 예를 들어 유튜브 구독자에게 알림이 가능 상황을 예시로 들 수 있겠다. 다음 예제에서는 주식시장에서 주식 가격에 따라 자동으로 주식을 사고 파는 상황을 간단하게 구현해 보겠다. 첫째로 주체가 되는 객체를 구현하면 다음과 같다. 1 2 3 4 public interface Subject { void registerObserver(Observer o); void notifyObservers(int money); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public..
람다 표현식을 활용한 디자인패턴 - 템플릿 메서드 디자인 패턴은 유용하다. 람다 표현식을 디자인 패턴에 적용한다면 더 간결하게 구현할 수 있다. 템플릿 메서드 알고리즘 개요를 제시하고 알고리즘의 일부를 수정할 필요가 있을때 템플릿 메서드를 사용한다. 예를들어 라면을 끓이는 과정을 코딩해보자. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public abstract class 라면 { public void cook(){ prepareWater(); inputPowder(); inputNoodle(); } protected void prepareWater(){ System.out.println("물을 넣는다."); } protected abstract void inputPowder(); protected void inputNo..
람다 표현식을 활용한 디자인패턴 - 전략 패턴 디자인 패턴은 유용하다. 람다 표현식을 디자인 패턴에 적용한다면 더 간결하게 구현할 수 있다. 전략패턴 먼저, 다음과 같이 인풋에 대해 유효성을 검증을 전략패턴을 통해 구현할 수 있다. 1 2 3 4 public interface ValidationStrategy { boolean validate(String s); } 1 2 3 4 5 6 7 8 9 10 11 public class MyValidator { private final ValidationStrategy validationStrategy; public MyValidator(final ValidationStrategy validationStrategy) { this.validationStrategy = validationStrategy; } ..
스트림 활용 정리 1. 필터링 1.1 프레디케이트로 필터링 filter 의 인수로 프레디케이트를 받는 방법이 있다. List vegetarianMenu = menu.stream() .filter(Dish::isVegetarian) .collect(toList()); 1.2 고유 요소 필터링 스트림은 고유 요소르 이루어진 스트림을 반환하는 distinct 메서드도 지원한다. List numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4); numbers.stream .filter(i -> i % 2 == 0) .distinct() .forEach(System.out::println); 위 코드는 filter 를 통해 2, 2, 4 요소들이 필터링되고 distinct() 를통해 2, 4 만 전달이 된..
스트림 기본 정리 1. 스트림은 무엇인가? 스트림은 자바 8 API에 새로 추가된 기능이다. 스트림을 사용하면 다음과 같은 이점이 있다. 멀티스레드 코드를 구현하지 않아도 데이터를 투명하게 병렬로 처리할 수 있다. 선언형으로 코드를 구현 할 수 있다. 즉, 루프와 if 조건문 등의 제어 블록 없이 원하는 로직을 만들어 낼 수 있다. 여러 빌딩 블록 연산을 연결할 수 있다. 예)filter 연산 후 sorted 연산 후 map 연산을 하는 파이프라인을 만들 수 있다. 스레드와 락을 걱정할 필요가 없다. 요약: 스트림은 더 간결하고 가독성이 높아지고 유연성이 좋고 성능이 좋다 2. 컬렉션과 스트림 컬렉션과 스트림 사이에는 다음과 같은 차이점이 있다. 컬렉션 스트림 데이터를 언제 계산하는지 적극적 생산 (현재 자료구조가 포함하..
테스트하기 어려운 코드 요구사항 1 - 테스트를 위한 메소드 제거 chess.Board 객체는 체스판을 추상화한 객체이다. 이 객체를 보면 체스판을 초기화하기 위해 initialize(), initializeEmpty()가 존재한다. initialize()는 체스 게임을 시작하기 위해 체스판을 초기화하는 메소드이고, initializeEmpty()는 테스트를 위한 목적으로 구현했다. 테스트를 위한 initializeEmpty()가 Board에 있는 것이 적합하지 않다. 구조를 변경해 테스트 목적으로 추가한 initializeEmpty() 없이도 테스트 가능하도록 리팩토링한다. 힌트: 인터페이스를 활용한다. 요구사항 2 - 테스트하기 어려운 코드를 테스트 가능한 구조로 변경 다음 Car 객체의 move() 메소드의 이동/정지를 ..