안녕하세요! 조엘입니다! 🤞🤞
우아한테크코스에서는 미션을 PR로 제출하고, 해당 미션에서 배운 것을 학습로그로 기록하고 있어요.
레벨 1의 학습 목표는 다음과 같았는데요.
- 자바 프로그래밍 언어에 대한 기본 문법을 익혀 프로그래밍하는 경험을 한다.
- 읽기 좋은 코드를 구현하는 것이 왜 중요한지와 코드를 개선해 읽기 좋은 코드로 변경해 보는 경험을 한다.
- 자신이 구현한 코드에 대해 단위 테스트와 리팩토링하는 경험을 한다.
- 웹 프론트엔드에서 웹 백엔드까지 프로그래밍해 웹 애플리케이션을 개발하는 경험을 한다.
학습로그를 정리하면서 레벨 1에서 배워야 할 부분 중 단위 테스트에 대한 공부가 조금 모자랐다는 생각이 드네요!
물론 테스트 코드를 작성하고 TDD 기반으로 미션을 진행하려고 노력은 했습니다만,,,
단위 테스트의 장점에 대해 설명해보라고 하면 횡설수설 할 것 같아요 🤔
레벨 2에서는 Spring을 배우는데요.
Spring에서 테스트 코드를 작성해 나가면서, 테스트에 어떠한 장점이 있는지 더 느껴보도록 하겠습니다. 💪
[미션 정리]
미션명 | PR 링크 |
자동차 경주 <1단계> | github.com/woowacourse/java-racingcar/pull/183 |
자동차 경주 <2단계> | github.com/woowacourse/java-racingcar/pull/234 |
로또 <1단계> | github.com/woowacourse/java-lotto/pull/271 |
로또 <2단계> | github.com/woowacourse/java-lotto/pull/331 |
블랙잭 <1단계> | github.com/woowacourse/java-blackjack/pull/146 |
블랙잭 <2단계> | github.com/woowacourse/java-blackjack/pull/193 |
체스 <1,2,3단계> | github.com/woowacourse/java-chess/pull/172 |
체스 <4,5단계> | github.com/woowacourse/java-chess/pull/236 |
[학습 로그 정리]
[OOP] 일급 컬렉션 - 3
내용
- 비즈니스에 종속적인 자료구조 생성
- 불변성을 보장함으로써 부작용 최소화
- 상태와 행위를 한 곳에 관리하도록 함
- 이름이 있는 컬렉션으로, 의미 부여 가능
링크
[OOP] 정적 팩토리 메서드 - 3
내용
- 객체 생성의 역할을 하는 클래스 메서드
- 이름이 있어, 가독성이 좋아짐
- 호출할 때마다 새로운 객체 생성하지 않아도 됨
- 객체 생성을 캡슐화 할 수 있음
링크
- https://johngrib.github.io/wiki/static-factory-method-pattern/
- https://velog.io/@ljinsk3/%EC%A0%95%EC%A0%81-%ED%8C%A9%ED%86%A0%EB%A6%AC-%EB%A9%94%EC%84%9C%EB%93%9C%EB%8A%94-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C
[OOP] DTO - 2
내용
- 계층 간 통신 용도로 오가는, 데이터 교환을 위한 객체
- 로직이 없는 순수한 데이터 객체로, getter와 setter만을 가짐
링크
[JDK] BigDecimal - 2
내용
- 부동 소수점 연산을 정확하게 수행하도록 지원
- 돈을 다룬다면 필수로 써야함
링크
- http://javamoods.blogspot.com/2009/03/how-big-is-bigdecimal.html
- https://www.geeksforgeeks.org/bigdecimal-class-java/
- https://jsonobject.tistory.com/466
[JDK] Stream API - 3
내용
- Stream API를 활용한 데이터 처리
링크
[Design Pattern] 전략 패턴 - 2
내용
- 랜덤한 값을 테스트하기 위해 인터페이스로 분리, 테스트 가능한 구조로 변경
- 구조
- Context: 갖고 있는 전략 콘크리트에 따라 행동이 달라짐
- Strategy: 제공하는 알고리즘에 대한 공통의 연산들을 interface로 정의
- Strategy Concrete Class: 실제 알고리즘
- 장점
- 상속을 사용하지 않음
- if문의 제거를 가능하게 한다
- 구현의 선택이 가능해진다
- 단점
- 객체 수 증가
- 서로 다른 전략을 이해해야 함
링크
- https://velog.io/@lxxjn0/%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EB%A5%BC-%EB%B6%84%EB%A6%AC%ED%95%98%EC%97%AC-%ED%85%8C%EC%8A%A4%ED%8A%B8%ED%95%98%EA%B8%B0-%EC%A2%8B%EC%9D%80-%EB%A9%94%EC%84%9C%EB%93%9C%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0
- https://www.youtube.com/watch?v=zGJzEBOELoU
[OOP] 응집도와 결합도 - 2
내용
- 응집도: 모듈 내부의 기능적인 집중 정도
- 결합도: 모듈과 모듈간의 상호 의존 정도
- 독립적인 모듈이 되기 위해서는 응집도는 강하고, 결합도는 약해야 한다
링크
- https://raisonde.tistory.com/entry/%EA%B2%B0%ED%95%A9%EB%8F%84Coupling%EA%B3%BC-%EC%9D%91%EC%A7%91%EB%8F%84Cohension
- https://medium.com/@shaul1991/%EC%B4%88%EB%B3%B4%EA%B0%9C%EB%B0%9C%EC%9E%90-%EC%9D%BC%EC%A7%80-%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4-%EB%AA%A8%EB%93%88%EA%B3%BC-%EB%AA%A8%EB%93%88%ED%99%94-%EA%B2%B0%ED%95%A9%EB%8F%84-%EC%9D%91%EC%A7%91%EB%8F%84%EC%9D%98-%EC%9D%B4%ED%95%B4-44af52e03a91
[JDK] Stream.forEach vs Collection.forEach - 2
내용
- Stream.forEach
- Stream 객체를 생성한 후에 forEach 메서드 호출
- 따라서 중간 연산에 해당하는 로직과 함께 써야 유의미하게 Stream을 사용한 것
- 반복 도중에 다른 쓰레드에 의해 수정될 수 있다
- parallelStream을 통해 여러 쓰레드에서 스트림을 실행할 수 있다
- 무조건 요소의 끝까지 반복을 돌게 된다.
- Stream 객체를 생성한 후에 forEach 메서드 호출
- Collection.forEach
- 따로 객체를 생성하지 않고 forEach 메서드 호출
- forEach 메서드는 Iterable 인터페이스의 default 메서드
- Collection 인터페이스에서 Iterable 인터페이스를 상속하기에 바로 사용한다.
- 인터페이스는 인터페이스를 상속 받을 수 있다 (다중 상속도 가능하다!)
- 멀티쓰레드 환경에서 락이 걸려있기에 더 안전하게 사용할 수 있다
- 따로 객체를 생성하지 않고 forEach 메서드 호출
링크
- https://woowacourse.github.io/javable/post/2020-09-30-collection-stream-for-each/
- https://woowacourse.github.io/javable/post/2020-05-14-foreach-vs-forloop/
[OOP] Enum 활용 - 1
내용
- 정의
- 관련한 상수 Singleton 객체의 모음집
- 컴파일 당시, 가능한 모든 값을 안다면 Enum 활용을 고려할 것
- 장점
- Java의 Enum은 상태와 행위를 동시에 관리할 수 있다
- 컴파일 시에 정의한 타입 이외의 타입에 대해 오류를 발생시킨다
링크
- https://limkydev.tistory.com/50
- https://github.com/PapimonLikelion/woowacourse-TIL/blob/master/Level1/2021-02-19.md#%EC%9E%90%EB%B0%94-enum
- https://www.youtube.com/watch?v=AVVWaRg6Q3A&t=327s
[JDK] new ArrayList<>() vs Arrays.asList() - 2
내용
- new ArrayList<>()
- java.util.ArrayList 소속
- List에 대한 모든 operation을 쓸 수 있음
- new로 생성해주기에, 넘겨받은 원본 리스트에 대한 참조는 끊는다
- 여기서 참조를 끊는다는 것은, 새로운 주소에 List를 만들고, 넘겨받은 List들의 원소를 하나하나 복사해주어 만들어 반환한다는 것
- 넘겨준 원본 List에 add, remove등의 연산을 해도 새롭게 만든 ArrayList에는 영향이 가지 않는다
- 하지만 List안에 들어있는 객체들은 그대로 얕은 복사가 되기 때문에 넘겨준 원본 List에서 원소로 가지고 있는 객체의 필드값을 조작하면, 새롭게 만든 ArrayList 내의 원소로 포함된 객체에도 영향을 미친다.
- Arrays.asList()
- java.util .Arrays.ArrayList 소속
- 읽기만 가능한 List
- add(), remove() 메서드를 통해 해당 list에 원소를 추가/삭제하려고 하면...
- "UnsupportedOperationException"을 반환
- 원본 배열의 참조도 끊지 않는다. 즉 얕은 복사로 주소를 공유한다.
- List 형태로 배열을 포장한 것이라고 보면 됨
링크
- https://unluckyjung.github.io/java/2021/03/07/Java-Arrays.asList-VS-newArrayList/
- https://github.com/PapimonLikelion/woowacourse-TIL/blob/master/Level1/2021-03-09.md#arraysaslist-vs-new-arraylist
[JDK] HashMap vs LinkedHashMap - 3
내용
- HashMap
- 중복된 원소를 허용하지 않으며, 순서도 고려되지 않음
- HashMap은 key와 value를 저장하는 두개의 배열로 구성되어 있음
- Key값이 어디에 저장될지는 다음과 같이 정의됨
- Key값으로 저장할 Object의 hashCode()를 구한다
- 정수로 반환된 hashCode() 값을 버킷의 수로 나눈 나머지를 구한다 (초기 버킷 수는 16개)
- 그렇게 구한 값이 배열의 index가 된다
- 해당 index에 Object를 저장한다
- LinkedHashMap
- HashMap과 동일하게 데이터를 저장
- 하지만 Doubly-Linked-List를 통해 데이터 저장 순서를 동시에 기록함
- 따라서, 데이터가 저장된 순서대로 접근할 수 있음
링크
- https://github.com/PapimonLikelion/woowacourse-TIL/blob/master/Level1/2021-03-09.md#hashset-vs-treeset-vs-linkedhashset
- https://d2.naver.com/helloworld/831311
[JDK] 함수형 인터페이스 - 3
내용
- 람다식
- 메서드를 하나의 "식"으로 표현한 것
- 따라서 메서드의 역할을 람다식으로 대체할 수 있음
- 이는 일급객체로, 변수처럼 다루게 되었음
- Java의 모든 메서드는 클래스/인터페이스 내에 포함되어 있어야 호출할 수 있다
- 람다식의 소속 클래스는 익명 클래스이다
- 익명 클래스: 클래스의 선언과 객체 생성을 동시하는, 한 번만 사용될 수 있고 오직 하나의 객체만을 생성할 수 있는 일회용 클래스
- 람다식의 소속 클래스는 익명 클래스이다
- 하나의 메서드가 선언된 인터페이스를 정의하여, 람다식을 다루게 된다
- @FunctionalInterface 어노테이션 추가하여 정의
- 하나 이상의 메서드를 인터페이스에 추가하려는 경우, 컴파일 에러 발생
- 결국 해당 인터페이스를 매개변수로 넘겨주고, 인터페이스 내부에 있는 하나의 메서드를 실행하는 방식으로 사용
- 메서드를 하나의 "식"으로 표현한 것
- java.uti.function 패키지
- 자주 쓰이는 형식의 메서드를 함수형 인터페이스로 정의해놓음
- 재사용성/유지보수를 위해 가능한 이 패키지의 함수형 인터페이스를 활용하자
- https://github.com/woowacourse/java-blackjack/pull/193/commits/d472685930c7ccd0a9f7ec03a918de237e6549b1
- 해당 커밋에서 사용한 BiFunction<Integer, Integer, Boolean> 함수형 인터페이스는...
- 두 개의 Integer 형식의 매개변수를 받아, Boolean 타입의 결과를 반환하는 함수
- 나머지 사용법은 아래 링크 참조
링크
[OOP] VO - 3
내용
- 정의
- 도메인에서 한 개 혹은 그 이상의 속성들을 묶어서 "특정 값"을 나태내는 객체
- ex) 좌표, 금액, 날짜 등
- 도메인에서 한 개 혹은 그 이상의 속성들을 묶어서 "특정 값"을 나태내는 객체
- 특징
- equals, hashCode 메서드를 재정의 할 것
- 값 자체를 나타내는 객체이기에, 내부의 속성과 타입이 같다면 같은 VO로 보는 것이 타당하다
- 불변객체로 만들 것
- VO는 속성값 자체가 해당 객체의 고유한 식별값으로, 내부 속성값을 바꿀 수 있게 하면 안 된다
- equals, hashCode 메서드를 재정의 할 것
링크
[Design Pattern] 상태패턴 - 3
내용
- 정의
- 기능이 "상태"에 따라 다르게 동작해야 할 때 사용하는 패턴으로, 가능한 "상태"들을 Class로 정의해 놓은 것!
- "상태" 객체가 필요한 "기능"을 제공하게 된다.
- 기능이 "상태"에 따라 다르게 동작해야 할 때 사용하는 패턴으로, 가능한 "상태"들을 Class로 정의해 놓은 것!
- 구현
- 상태 사용자(context): 클라이언트로 부터 기능 실행 요청을 받으면, 상태 객체에게 해당 기능 처리를 위임한다
- 상태(state): 구체화된 여러 상태들의 기능들을 추상화함으로써, 변화하는 부분을 담당한다
- 상태 콘크리트(Concrete state): 실제 상태의 기능들을 구현
- 장점
- 상태에 따른 if - else 분기를 안 만들어도 된다.
- 유지보수가 쉬워지고, 단일 책임 원칙을 준수하기도 수월해진다.
- 상태별로 동작 수정이 쉬워짐
- 상태에 관련된 코드가 한 곳에 모여있어 안전하고 빠른 구현이 가능하다
- 상태에 따른 if - else 분기를 안 만들어도 된다.
링크
- 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴
- https://github.com/PapimonLikelion/woowacourse-TIL/blob/master/Level1/2021-03-15.md#%EC%83%81%ED%83%9C-%ED%8C%A8%ED%84%B4
[JDK] hashCode & equals 의 동치성 - 3
내용
- HashSet/HashMap 같은 경우, hashCode와 equals 가 같다면, 같은 Key값으로 인지
- 2개의 "같아야 하는"객체를 HashMap에 넣었는데, hashCode/equals가 다르게 정의되어 있다면,
- 즉, hashCode는 같고 equals는 다르다면
- 2개의 객체는 각각 다른 Key값으로 HashMap/HashSet에 저장된다.
- 해당 방식은 결국 고유한 Key값을 통한 Value의 접근을 방해하는 Side Effect를 발생시킨다.
- 따라서 객체의 고유함을 보장할 수 있도록, hashCode와 equals가 같이 동작하도록 정의해야 한다.
링크
- https://github.com/PapimonLikelion/woowacourse-TIL/blob/master/Level1/2021-03-24.md#hashcode%EC%99%80-equals%EC%9D%98-%EB%8F%99%EC%B9%98%EC%84%B1-%EB%B3%B4%EC%9E%A5
- https://papimon.tistory.com/74
[OOP] 객체 생성의 캡슐화 - 2
내용
- 체스에 필요한 팀 객체를 인스턴스화 하기 위해, Team 클래스의 생성자를 통해 각 팀을 생성해주었다.
- 하지만 생각해보니까, 체스에는 블랙팀, 화이트팀만 있으면 된다.
- 그러면 굳이 생성자를 열어두지 말고(물론 열어줘도 됨), BlackTeam을 만드는 정적 팩토리 메서드와 WhiteTeam을 만드는 정적 팩토리 메서드를 만들어 보는 것은 어떨까?
- 해당 방식으로 코드를 리팩토링 했더니, Team 생성에 필요한 정보를 생성자를 통해 외부로 공개하지 않고, 체스에 필요한 팀을 만드는 역할을 충분히 하게 되었다.
링크
- https://github.com/PapimonLikelion/woowacourse-TIL/blob/master/Level1/2021-03-24.md#hashcode%EC%99%80-equals%EC%9D%98-%EB%8F%99%EC%B9%98%EC%84%B1-%EB%B3%B4%EC%9E%A5
- https://velog.io/@ljinsk3/%EC%A0%95%EC%A0%81-%ED%8C%A9%ED%86%A0%EB%A6%AC-%EB%A9%94%EC%84%9C%EB%93%9C%EB%8A%94-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C
[OOP] SOLID 원칙 중 LSP - 2
내용
- 리스코프 치환 원칙 정의
- 상위 타입의 객체를 하위 타입의 객체로 치환해도, 상위 타입을 사용하는 프로그램은 정상적으로 동작해야한다
- OCP를 뒷받침 하는 "다형성"에 관한 원칙
- LSP 위반 신호
- isInstanceOf는 전형적인 LSP 위반 신호
- 상위 타입을 그대로 쓰지 못하고, 하위 타입 인스턴스 인지 검사하는 것 자체가, 상위 타입으로 프로그램을 정상 작동 못시킨다는 것!
- 이를 해결하려면, 더 "추상화" 시켜볼 것
- "구체적 구현에 따라 변화하는 기능"으로 만들어 일을 처리해보자...!
- isInstanceOf는 전형적인 LSP 위반 신호
링크
- https://github.com/PapimonLikelion/woowacourse-TIL/blob/master/Level1/2021-03-22.md#%EC%84%A4%EA%B3%84%EC%9B%90%EC%B9%99-solid
- 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴 (최범균)
[Architecture] Service Layer
내용
- Layer가 필요한 이유
- Layer를 통해 역할을 추상화 할 수 있음
- 다른 계층 끼리 부품을 갈아끼우듯 변환 가능
- 컴포넌트들의 의존 계층 관계 유지 가능
- Service Layer
- 어플리케이션의 비즈니스 로직을 캡슐화하고, transaction을 조절하는 역할
링크
[JS] fetch API
내용
- Ajax
- 비동기 방식으로 데이터를 주고받는 JS 기술
- 페이지 새로 고침 없이 서버에 요청하고, 응답을 받을 수 있음
- fetch
- Ajax 기술의 복잡도를 낮춰 사용할 수 있도록 fetch 보급
- Promise를 반환함
- 따라서, then() 메서드에 응답 처리하는 콜백함수 추가할 것
링크
[JDBC] 자원 반환
내용
- Connection, Statement/PreparedStatement, ResultSet 들을 모두 close() 해줘야 한다
- 그렇지 않다면...
- Statement가 제대로 안 닫히면, 생성된 Statement의 갯수가 증가하여, 더 이상 Statement를 생성할 수 없게 됨
- close() 하지 않으므로, 불필요한 자원을 낭비하게 됨 (네트워크/메모리)
- 커넥션 풀을 사용하지 않는 상황에서 Connection 안 닫아주면 DBMS에 새로운 Connection을 만들 수 없음
- 해결 방법으로 커넥션을 관리하는 class를 생성하거나, try-with-resource를 사용할 수 있다
링크
- https://javacan.tistory.com/entry/78
- https://github.com/PapimonLikelion/woowacourse-TIL/blob/master/Level1/2021-04-05.md
[Java] 멀티 스레드 환경에서 고려할 것
내용
- 만약 인스턴스 변수가 있는 클래스에서 멀티 스레드 환경을 지원한다면, 해당 인스턴스 변수에 대해 쓰레드 동기화를 확보해야함
- synchronized 예약어로 필요한 영역을 임계 영역으로 지정할 수 있음
- 이렇게 된다면, 하나의 쓰레드만 접근/처리 가능하여 성능이 떨어질 것임
- 만일 클래스를 stateless하게 만든다면, race-condition이 일어날 인스턴스 변수가 없다
- 멀티 스레드 환경을 쉽게 지원할 수 있음
링크
- https://github.com/PapimonLikelion/woowacourse-TIL/blob/master/Level1/2021-04-05.md
- https://github.com/PapimonLikelion/woowacourse-TIL/blob/master/Level1/2021-04-08.md
+) 공부에 도움 주신 선배 개발자 분들 감사합니다!
반응형
'외부 활동 > 우아한테크코스' 카테고리의 다른 글
Level3 학습 로그 정리 (2) | 2021.08.26 |
---|---|
Level2 미션 + 학습 로그 정리 (2) | 2021.06.22 |
저는 모든 게 처음이라니까요? (2) | 2021.02.22 |
우아한테크코스 3기 최종 합격 (5) | 2020.12.30 |
우아한테크코스 3기 프리코스를 마치며 (2) | 2020.12.15 |
댓글