전체 글

11.1 값이 없는 상황을 어떻게 처리할까 클래스 내부에 필드로 객체를 가지는 상황에서 객체가 비어 있고, 해당 필드에 접근하려 하면 NullPointerException이 발생한다. 보수적인 자세로 if (객체 == null)을 많이 사용하여 null을 피해 갈 수도 있을 것이다. 변수를 접근할 때마다 if가 늘어나고 코드 들여 쓰기가 늘어난다. 이와 같은 반복 패턴 코드를 ‘깊은 의심’이라고 한다. null 때문에 발생하는 문제 에러의 근원이다: NullPointerException은 가장 흔한 에러 코드를 어지럽힌다: null 확인 코드를 추가해야 하므로 아무 의미가 없다: null은 아무 의미도 표현하지 않는다. 자바 철학에 위배된다: 자바는 개발자로부터 모든 포인터를 숨겼지만 null은 예외 형..
step1 피드백 step2 피드백 함수형 인터페이스의 과용 입력과 출력을 담당하는 View 클래스들을 게임 흐름을 담당하는 컨트롤러에서 분리하고 싶어서 함수형 인터페이스를 사용했었다. 그럼 BlackJackGame을 사용하는 클라이언트인 컨트롤러 입장에서는 드가 매우 깔끔해진다. View의 메서드들을 람다로 함수형 인터페이스로 전달한 결과다. public static void main(String[] args) { BlackJackGame blackJackGame = new BlackJackGame( InputView.askNames(), InputView::askBet, new Deck(Card.getCards())); OutputView.printGamers(blackJackGame.getDeale..
· JAVA
자바의 Enum은 다양한 일을 할 수 있다. 예전 포스팅에서도 설명했지만 Enum은 당수 상수 모음이 아니라 고차원의 추상 개념을 완벽히 표현할 수 있을 뿐 아니라 각 상수 데이터와 연결 지어 다양한 일을 할 수 있다. 여러분은 Enum을 사용해 if문을 제거할 수 있나요? 예전에 수업에서 코치가 한 말이다. 당시에는 무슨 의미인지 정확히 몰랐지만 미션을 진행하다 아 이렇게 if 분기문을 없앨 수 있구나 깨달은 적이 있었다. 오늘은 우아한테크코스 블랙잭 미션에서 Enum을 어떻게 활용했는지 포스팅하고자 한다. 블랙잭 결과 도출 규칙 딜러와 플레이어가 대결해서 카드패의 숫자 합이 21을 넘지 않으면서 높으면 승리하는 게임 승리 조건 블랙잭 : 처음 받은 2장의 카드가 21이면 블랙잭이라고 한다. 블랙잭일 ..
자바가 람다를 지원하면서 API를 작성하는 방법이 크게 바뀌었다. 특히 함수형 인터페이스를 사용해 메서드마다 다른 동작을 메서드를 사용하는 클라이언트에서 지정해줄 수 있다. 이런 방식을 동작 파라미터화라고 한다. 이를 이용하면 변화하는 요구사항에 효과적으로 대응할 수도 있고 클래스와 클래스 간의 의존을 맺을 때 의존을 끊어줄 수도 있다. 변하는 요구사항에 대응하기 회원들의 리스트에서 어떤 조건에 따라 필터링을 해야 한다고 가정하자. public class Member { private final String name; private final int age; public Member(String name, int age) { this.name = name; this.age = age; } } 회원은 이름..
상속은 코드 중복을 제거하는 강력한 수단이지만 잘못 사용하면 오류를 내기 쉬운 소프트웨어를 만들게 된다. 상속의 문제점 상속은 캡슐화를 깨뜨린다. 하위 클래스가 가지는 상위 클래스에 대한 강한 의존성 때문에 상위 클래스의 구현에 따라 하위 클래스 동작이 의도와는 다르게 동작할 수도 있다. 게다가 상위 클래스의 변화가 하위 클래스까지 전파되어 변화에 맞춰 수정도 계속해주어야 한다. 예를 들어 HashSet을 상속 받는다고 가정하자. 상속받은 하위 클래스는 처음 생성된 이후 몇 개의 원소가 더해졌는지 횟수를 알고 싶어서 횟수를 알 수 있는 기능을 추가했다. public class InstrumentedHashSet extends HashSet { private int addCount = 0; @Overrid..
용어 정리 클래스와 인터페이스 선언에 타입 매개변수가 쓰이면, 이를 제네릭 클래스 혹은 제네릭 인터페이스라 한다. public interface List extends Collection { List 인터페이스는 E라는 원소 타입 매개변수를 받고 이러한 제네릭 클래스와 인터페이스를 통틀어 제네릭 타입이라 한다. 제네릭 타입은 매개변수화 타입을 정의한다. 예를 들어 List라고 했을 때 Integer가 리스트가 받을 수 있는 타입을 정의한 매개변수화 타입이다. 제네릭 타입에는 로 타입이라는 것도 있다. 로 타입이란 타입 매개변수를 사용하지 않은 제네릭 타입을 의미한다. List list; 그렇다면 이 로 타입을 사용하지 말아야 하는 이유는 무엇일까? 로 타입은 타입 안정하지 않다. List rawList ..
· Git
혼자 간단한 프로젝트를 만들었을 땐 깃의 브랜치를 거의 사용하지 않았었다. 하지만 큰 프로젝트나 여러 사람이 참여하는 프로젝트에서는 브랜치가 매우 중요하다. 각각 독립적인 영역 안에서 마음대로 소스코드를 변경하기 위해서는 분리된 작업 영역에서 작업하고, 나중에 작업물을 합쳐야 한다. 브랜치를 다루는 핵심적인 명령어 몇 가지와 브랜치를 분기한 뒤 합칠 때 사용하는 merge와 rebase의 차이점을 정리해보겠다. Branch 명령어 브랜치 생성 : 'step1'이라는 이름의 브랜치를 생성한다. $ git branch step1 브랜치 확인 : 현재 생성되어 있는 브랜치 목록을 보여준다. $ git branch * master step1 브랜치 이동 : 'step1' 브랜치로 이동 $ git switch s..
· JAVA
위키백과에 의하면 옵저버 패턴의 정의는 다음과 같다. 옵서버 패턴(observer pattern)은 객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태 변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버에게 통지하도록 하는 디자인 패턴이다. 좀 더 풀어서 말하면 어떤 이벤트가 발생했을 때 주제(Subject)라 불리는 객체가 다른 객체 리스트(옵저버)에 자동으로 알림을 보내야 하는 상황에서 사용한다. 예를 들어서 자신이 구독한 유튜브 채널에서 영상이 올라오면 구독자들에게 알림이 오는데 이런 상황에서 옵저버 패턴을 사용한다. 구독자(옵저버)들이 유튜버(주제 객체)를 관찰하고 있는 것이다. 옵저버 패턴 구조 Observer : 데이터의 변경을 통보받는 인터페이스..
더즈
DOES-LOG