사다리 타기 미션이 종료되었다..! 물론 끝난지 10일 정도 되가지만.. 미루고 미루다가 정리한다 ㅎ 나는 내가 학습한 것들을 나만의 언어로 작성하면 못배기는 성격이기에, 사다리 타기를 통해 배운 것들을 정리하고자 한다. 기능목록도 도메인 영역별로 이전까지는 요구사항을 조금 불친절하게 작성했던 것 같다. 문서는 나를 위해서만 존재하는 것이 아니다. 기능 목록을 도메인 영역별로, 상세히 작성하는 경우 다른 개발자가 시스템을 이해하기가 쉬워지며, 더불어 커밋 로그에 대한 가이드라인이 되기도 한다. 따라서 이 이후로는, 기능목록에 도메인 로직을 상세히 작성하기 시작했다. 현재는 다음과 같이 도메인 모델에 따라 기능을 분류하고 있다. 내려가기 규칙 내려가기 규칙에 대해서는 내가 프롤로그에 따로 작성해 둔 것이 ..
왜 Throwable을 알아야 하는가 모든 예외 및 에러는 Throwble의 하위 클래스이다. 또한, 모든 표준 예외 및 에러 클래스는 Throwable에 정의된 메소드 및 프로퍼티 이외에 아무것도 추가적으로 정의하지 않는다. 그저 Throwable의 생성자를 호출해 초기화만 명시할 뿐이다. 커스텀 예외는 어떻게 정의하느냐에 따라 추가적인 기능이 존재할수도 있습니다. 다음은 흔히 사용하는 IllegalArgumentException의 실제 내부 구현이다. 앞서 말했다시피, super 키워드를 통해 부모 클래스의 생성자만 호출할 뿐, 추가적인 기능은 없다. public class IllegalArgumentException extends RuntimeException { public IllegalArgum..
enum 객체는 compile time에 정의된다 우선 구현방식을 알아보기에 앞서 결론부터 말하자면, enum 객체는 compile time에 정의된다. 왜 그래야만 할까? 사실 enum은 Java에서 객체의 성질을 띠고는 있지만, 본질은 상수이다. 상수는 특성상 인스턴스마다 생성될 필요가 전혀 없다. 오히려 컴파일 타임에 한번만 바인딩되는 것이 바람직하다. 리터럴이나 매직 넘버를 상수화할 때도, static final 키워드를 사용하지 않는가? enum도 마찬가지로 상수의 특성이 강하기 때문에 compile time에 정의되는 것이라 예측할 수 있다. 어떻게 compile time에 정의되는 걸까? 내부적으로 어떤 구조이길래, 자꾸 compile time에 정의되는 것이라 하는걸까? 운송수단을 나타내는..
enum이 왜 필요할까? enum이 필요한 이유는 무엇일까? 우리는 프로그래밍하다 보면, 어떤 값에 의미를 부여해야 할 때가 있다. 매직 넘버, 리터럴 등은 코드를 읽는 클라이언트가 의미를 파악하기 힘들다. 따라서 우리는 상수를 사용해 값에 적절한 의미를 부여하는데, 상수는 의미적으로 군집되어 있는 경우가 많다. 예를 들어, 요일 별 메뉴를 반환하는 식단표 어플리케이션을 생각해보자. 식단표 어플리케이션 // 식단표 어플리케이션 public String getMenu(String day) { if (day.equals("MONDAY")) { return "순두부찌개"; } else if (day.equals("TUESDAY")) { return "짜장면"; } else if (day.equals("WEDN..
필요성 프로그램에서 일반적으로 '같다' 라는 의미를 어떻게 나타낼까? 가장 쉬운 방법은 동등 연산자(==)를 사용하는 방법이다. 그러나 이 방법은 원시형에 대해서만 유효하다. (원시형에 대해서는 나중에 따로 작성해보겠다) 원시형이 아닌 참조형에 대해 동등 연산자를 사용하는 경우는, 내부 값이 아닌 메모리 주소값에 대한 비교이다. 그렇다면 객체가 같다는 것은 어떻게 정의할 수 있을까? 이런 문제를 해결하기 위해 equals & hashCode가 등장했다. equals란 equals는 모든 객체들의 조상, Object에 정의되어 있는 메소드이다. 필요에 따라 모든 객체들은 이를 오버라이딩해 사용할 수 있다. equals는 어떤 객체가 다른 객체와 '동등한지'를 비교할 수 있는 수단이다. 여기서 동등하다는 키..
가독성 높은 코드 API를 적절히 사용하라 class Menus { public Menus(final List menus) { for (int i = 0; i < menus.size(); i++) { for (int j = 0; j < i; j++) { if (menus.get(i).equals(menus.get(j))) { throw new IllegalArgumentException("메뉴는 중복될 수 없습니다."); } } } } } class Menus { public Menus(final List menus) { if (menus.size() != menus.stream().distinct().count()) { throw new IllegalArgumentException("메뉴는 중복될 수 ..
사전적 의미 동일성(Identity)과 동등성(Equality)은 무엇이 다를까? 우선 사전적 의미를 살펴보겠다. 동일성(identity)은 다른 사물과 대립구분되면서 변함없이 똑같이 존재하는 개개의 성질을 말한다. 동등성(equality)은 두 가지 이상의 개체나 개념이 서로 동일한 것으로 취급될 수 있는 상태를 의미한다. 사전적 의미만 봐서는 쉽게 와닿지 않는 것 같지만, 그래도 의미를 유추해보자면.. 동일성의 경우, 두 사물이 완전히 똑같은 상태로 존재하는 경우라고 생각해볼 수 있다. 즉, 완전히 같은 경우이다. 동등성의 경우, 완전히 똑같은 사물은 아니지만 동일하게 취급될 수 있는 상태를 의미하는 것 같다. 예를 들어, 자동차 공장에서 자동차들은 '동등하다'고 할 수 있다. 하지만 그렇다고 해서 ..
가변 인자란? 가변 인자란, Java 5 이후로 도입되었으며, 임의의 수를 가진 파라미터를 받을 때 유용하게 사용할 수 있다. public int adder(int a1, int a2, int a3) { return a1 + a2 + a3; } 파라미터가 3개라면 위와 같은 덧셈 계산기를 만들 수 있다. 100개의 인자를 더하고 싶다면 어떻게 할까? 파라미터가 100개인 adder 메소드를 오버로딩할까? 파라미터가 10000개가 된다면? 이 시점에서 생각해볼 수 있는 것이, 배열 혹은 리스트이다. 배열 또는 리스트로 값을 받을 수만 있다면 iterator로 반복 접근도 가능하며, 오버로딩에 대해 걱정할 필요가 없다. 따라서 Varargs(가변 인자)를 사용한다. public int adder(int.....
유일하게 변하지 않는 것은 모든 것이 변한다는 사실뿐이다. 경로가 아닌 지도를 만들어라 어떤 사람이 A라는 마을로 이동하려고 하는데, 길을 모른다고 가정해보자. 지나가던 다른 사람에게 A라는 마을로 어떻게 가냐고 묻자, "저기서 오른쪽으로 가서, 200m정도 앞으로 간 뒤 ..." 라고 답한다. 결국 경로를 알려준 은인덕분에 A라는 마을에 도달할 수 있었다. 이것은 기능적이고 해결책 지향적인 접근법이다. A라는 마을에 도달하기 위한 해결책, 즉 기능만 제공한다. 반면 지도를 사용하는 경우는 어떨까? A 라는 마을 뿐만 아니라, B, C 라는 마을의 정보까지도 한 눈에 확인할 수 있다. 또한 추상화가 적절히 이루어졌기에 경로를 쉽게 파악할 수 있다. 지도는 구조적이고 문제 지향적인 접근법이다. 지도는 A ..
첫번째 미션이었던 자동차 경주 미션이 종료되었으므로 회고를 해보자 !! 회고 템플릿은 어떻게 할까 하다가, 유명한 KPT(Keep, Problem, Try) 로 해보기로 함. 🥸 Keep 빠른 시간 안에 구현을 완료했던 것! 코드 작성 중 문제가 생기더라도 페어(하디)와 의견을 많이 나눴던 것. MVC 모델에 맞춰서 구현을 마친 것. Problem 잡담은 경쟁력인데, 첫 미션이라 그런지 긴장을 많이 해서 하디와 잡담을 많이 하지 못했다.. ㅎ 조금은 쉬어가면서 해도 좋았을 걸, 급하게 달린 것 같기도 하다. 리팩토링 기간 후반부에는 마땅히 문제점이 보이지 않아 리팩토링을 거의 못했는데, 내가 알던 지식들이 맞나 다시 검증하는 시간을 가졌으면 어땠을까 싶다! Try 예외처리에 대한 나만의 방식 만들어보기...