본문 바로가기
추상 클래스를 도입해보자 <10> 예전에, 계산기를 업그레이드 하기 전에 초반에는 구조가 이렇게 되어있었다.주목할 곳은 abstract operation이다. 당시의 나는 "왜 사칙연산밖에 못 하는데 추상 클래스를 4개나 나눠야 하는 거지?" 라고 생각했었고, 나눠져 있던 5개의 클래스를 하나의 enum으로 통합하고 뿌듯해했다.하지만 내 java에 대한 시야가 확장되면서 이젠 enum과 추상 클래스를 같이 사용하며'두 개의 연산자를 받아서' '다양한 복잡한 연산을 수행하는 기능' 을 '같은 구조로 손쉽게' 추가하는 기능을 도입해보려고 한다. 그럼 코딩을 하기 전, 이들이 얼마나 다른지 짚고 넘어가보자.1. enum만 사용한 operation: 열거형으로 단순하고 직관적이다. 한 파일 안에 모두 담긴다. 하지만, 확장성이 좋지 않다. 지금.. 2024. 11. 19.
트러블슈팅 : 검색 결과..아아... <9> 검색 결과를 제대로 불러오지 않는 오류가 있다. 하나만 오류가 난다면 쉽게 고칠텐데, 모든 기록에 대해 검색이 안 되어서 원인을 찾아봐야한다. 우선, "조건에 맞는 결과가 없습니다" 는 모든 검색을 다 실행한 후 검색결과가 비어있다면 출력되는 문장이다. result를 반환하는 부분의 콘솔을 찍어봤다. 음.. historyData는 비어있고, condition은 잘 모르겠지만 정상적으로 들어간 것 같다.(제발요)historyData가 빈 것이 문제니 그부분을 더 찾아보자. 클래스의 생성자부터 차근차근 하나씩 로그를 찍다 보면 원인이 나오지 않을까? !!! 생성자에 전달된 list가 컴파일 시점부터 비어있다. 정말 모르겠어서 튜터님께 찾아가니 HistoryDataSearch에서 생성자가 생성되는 시간이랑Hi.. 2024. 11. 18.
인터페이스, 추상클래스.. 사용 가능할 것 같은데? <8> 어제 리팩토링을 하고, 자기 전에 고민을 했다.과연 내 계산기에서 인터페이스나 추상 클래스를 사용할 곳이 한 군데도 없을까? 진짜로?사용할 수 있을 것 같은데? 해서, 인터페이스와 추상 클래스의 개념을 간단하게 다시 잡고, 방향성을 정했다.추상 클래스는 "공통적인 로직" 을 기반으로 하고, 인터페이스는 "확장성" 에 초점을 맞춘다.특징추상 클래스인터페이스목적코드 재사용, 공통 기능 제공설계 강제, 다양한 구현체 허용공통 로직 포함 여부가능 (메서드 구현, 필드 포함)불가능 (Java 8부터 default 메서드 허용)다중 상속불가능가능유연성제한적 (계층 구조를 강제)매우 유연 (다양한 구현 가능) 이보다 더 간단히 비유를 해 보자면,인터페이스는 "레고 블록은 이렇게 생겨야 한다" 라는 규정만 하고, 조립.. 2024. 11. 18.
<finish> 가 아니라 리팩토링.. 작업을 마무리하며,,, 리팩토링을 정말 열심히 했다.  CalculatorApp 클래스에서, 유저의 Input을 받는 요소들을 UserInput 클래스로 따로 분류하였다.History 클래스도 마찬가지로 좀 다듬어줬다.  코드가 엄청 짧아졌다. 뿌듯 ㅎㅎ  그리고 이제 봤는데..  계산기에 이런 조건이 있었다.하핫;;그나마 다행인 건 고유id를 부여해 id조회가 가능하다는 거다.그것도 lambda & stream을 적용해서 만든 거라 얻어걸렸다 핳;; 구조는 똑같으니 괜찮지 않을까?  여기서 마무리 하고 다른 공부 해야겠다~!(근데 github 실수로 main branch에 commits가 26개나 생겼다.........아아......) https://github.com/roqkfchqh/Calculat.. 2024. 11. 17.
트러블슈팅: 왜 저장이 두번 되니? <7> 저장 기능을 만들고 테스트 하던 중에 치명적인 버그를 발견했다.로그를 찍어보니 저장 횟수가 연속계산 횟수에 비례한다는 걸 알 수 있었다. ㅋㅋ 반복할 때 마다 늘어나는 값이 있다는건데.. 제일 수상한 건 역시 calculate 메서드니까 콘솔을 군데군데 찍어보자.//Calculator App 의 number List 를 calculationFormula 로 명명 public double calculate(List calculationFormula) { //numbers List 에 있는 짝수번째 값 -> 숫자 List numbers = IntStream.range(0, calculationFormula.size()) .filter(i -> i % .. 2024. 11. 15.
Interface? or Method? <6> import java.util.ArrayList;import java.util.List;import java.util.Scanner;public class CalculatorApp { Calculator calc = new Calculator(); Parser parser = new Parser(); //Calculator class 에 사용되는 List 생성 List numbers = new ArrayList(); public void start(){ Scanner calculation = new Scanner(System.in); while(true){ try{ System.out.println("첫 번.. 2024. 11. 15.
Generic을 도대체 왜 쓸까? <5> 이번 프로젝트를 하면서 제일 힘든 순간이다.일단 자바를 공부하기 이전엔 한번도 들어본 적 없는 기능인데다가, 왜 쓰는지는 알겠는데 내 코드에 적용하기 가장 힘들었다.어설프게 대충 끼워넣다가는 유지보수할때 힘들 게 뻔했다. https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A0%9C%EB%84%A4%EB%A6%ADGenerics-%EA%B0%9C%EB%85%90-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%B3%B5%ED%95%98%EA%B8%B0 ☕ 자바 제네릭(Generics) 개념 & 문법 정복하기제네릭 (Generics) 이란 자바에서 제네릭(Generics)은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법을 의미한다. 객체별로 다른.. 2024. 11. 15.
Parser.java의 중요성을 깨달음 <4> 계산기에 parser.java를 다시 추가했다. 초반에는 정말 필요없을 줄 알았는데 머쓱해진다.. 하하하그 이유는,지금 내 계산기는 값을 list에 저장된 값들을 짝수와 홀수로 구별해서 각각 number와 operator에 넣는다.문제는, 사용자가 값을 잘못 입력하면이런식으로 홀수번째 인덱스에 숫자가 들어가게 된다.list의 값을 초기화 할 수도 있지만 좀 번거롭기도 하고 잘못된 타입을 걸러내는 것이 꼭 필요한 기능인 것 같아서 원래 있던 코드인 parser.java를 재사용하기로 했다.삭제했었기 때문에 깃허브에서 주섬주섬..복사해왔다.처음에는 단순하게 calaulator에서 parser로 보내고, parser에서 에러가 발생하면 calculator의 numbers를 초기화하도록 했는데이게 그 유명한 스.. 2024. 11. 15.
트러블슈팅: Reducing a Stream <3> 연속으로 계산할 경우 이전 연산의 계산결과와 더해져야 하는데, 이전에 입력했던 값과 연산을 수행하는 버그가 있다.문제가 될만한 부분은 .reduce 메소드의 람다식 부분이다.reduce의 사용법을 내가 잘못 알고 사용했다. 1, a,b - > b로 사용하면 다음 첫번째 요소에 이전 연산 결과가 들어가는 줄 알았는데,이전 연산에서의 b값이 첫번째 요소에 들어가는 것 같다.구글링을 여러 번 했는데 이해도 잘 안되고 정확한 정보를 알 수 없어서 공식 문서로 찾아갔다.https://docs.oracle.com/en/java/javase/23/docs/api/java.base/java/util/stream/Stream.html#reduce(java.lang.Object,java.util.function.Binar.. 2024. 11. 15.