Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kth/계산기 1차 코드 리뷰 #2

Open
wants to merge 98 commits into
base: kth/main
Choose a base branch
from

Conversation

xogns4909
Copy link
Contributor

@xogns4909 xogns4909 commented Aug 25, 2023

📌 과제 설명

선택 옵션 입력 : 1 :결과 조회 2 계산
1번을 선택했을 시 이전 결과를 전부 조회 할 수 있습니다.
2번을 선택했을 시 중위 표현식을 후위 표현식으로 변환하여 계산하고 저장합니다

👩‍💻 요구 사항과 구현 내용

  1. 객체를 크게 계산기, 누산기, 입력, 입력 뷰, 출력, 저장소로 나눴습니다.

  2. 입력 뷰와 출력은 콘솔이 아닌 다른 방식의 확장을 가정하여 인터페이스로 구현했습니다.

  3. 옵션 입력 try catch를 이용한 예외 처리와 정규식을 통한 화이트 리스트 방식으로 검증을 진행하였습니다.

  4. 식 입력 또한 try catch를 이용한 예외 처리와 정규식을 통한 화이트 리스트 방식으로 검증을 진행하였습니다.

  5. 식 입력 시 중위 표기법을 후기 표기법으로 변경하여 계산하는 방식으로 구현했습니다.

  6. 저장은 LinkedHashMap을 통해 구현했습니다.

  7. 테스트는 @ParameterizedTest를 이용하여 다양한 케이스의 예제를 테스트 했습니다.

  8. 커밋이 뒤죽박죽이라 아직 커밋 별로 정리하기는 좀 어려운거 같습니다. 익숙해 지도록 하겠습니다!

✅ 피드백 반영사항

맞춤법검사기 결과 영역

  1. 테스트 코드를 delimiter를 이용하여 구분하였습니다.
  2. Output 클래스가 Repository에 의존하고 있어 수정했습니다.
  3. 연산자 비교를 위한 Enum을 생성해서 재사용성을 높였습니다.
  4. 정규식을 통한 검증 로직을 util 클래스로 만들어 재사용성을 높였습니다.
  5. 입력 클래스에서 잘못된 예외 처리를 말해주셔서 throw Exeoption와 try catch 통해 예외를 처리했습니다.
  6. Input 클래스를 인터페이스로 수정해 콘솔이 아닌 다른 상황에서도 입력이 가능하게 했습니다.
  7. 각각의 메서드를 모듈화하여 책임을 줄였습니다.

✅ PR 포인트 & 궁금한 점

ConsoleInput Class에서 잘못된 입력 값이 들어왔을 때 서로 다른 메시지를 주기 위해서 같은 로직인 메서드를 2개 만들었습니다. 반복적인 코드가 좋지 않다고 생각이 들었는데요. 이걸 한 개의 메서드로 바꾸고 매개변수를 추가해서 잘못된 코드가 들어왔을 때 메시지를 추가해 주는 게 좋을까요?

잘못된 입력이 들어왔을 때 IllegalArgumentException을 던지는데 사실 저는 잘못된 매개변수 같은 경우는 컴파일 시점에서 다 잡아주니 저 예외보단 커스텀 예외를 만들어서 처리하는 게 더 직관적이라고 생각이 드는데 직렬화 문제와 실무에서 혼잡성 문제가 있다고 하셔서 사용하지 않았는데 뭐가 더 좋을까요?

람다를 사용하라고 하셨는데 간단하고 재사용성도 좋지만 함수형 인터페이스를 사용해서 람다를 쓰면 오히려 유지 보수에 안 좋지 않나요? 혹시 람다 사용을 추천해 주신 이유가 궁금합니다

피드백 해주셨을 때 코드 한줄 한줄 근거를 가지고 짜야 된다라고 말해주셨는데 기존엔 그냥 구현에만 중점을 두고 객체지향이란 점을 생각을 하지 않고 짰습니다. 리팩토링 하는 과정에서 제가 객체지향, SOLID, 디자인 패턴의 개념이 너무 부족하기도 하고 습관을 한순간에 바꾸려고 하는 부분에서 코딩에 대한 거부감이 너무 강하게 들었습니다. 또한 경험의 부족인건지 잘못된 공부법인지 모르겠는데 공부한 부분을 코드로 나타내기 힘들다고 느꼈습니다.좋은 방법 아시면 추천 부탁드려요! 조금씩 피드백 받으면서 변화해보도록 하겠습니다!

Comment on lines 20 to 26
private SelectValidation selectValidation = new SelectValidation();

private static InputView inputView = new ConsoleInputView();
private InputView inputView = new ConsoleInputView();

private static ExpressionInputValidation expressionInputValidation = new ExpressionInputValidation();
private ExpressionInputValidation expressionInputValidation = new ExpressionInputValidation();

private static Output output = new ConsoleOutput();
private Output output = new ConsoleOutput();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 객체들을 외부에서 주입받는 형식이 아닌 기본 생성자만 사용하여 내부에서 생성하는 형태네요. DI를 하지 않은 이유가 있을까요?

Comment on lines 18 to 19
private final int CHECK = 1;
private final int CALCULATE = 2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여긴 static을 지우신 이유가 뭘까요?

@@ -47,7 +47,7 @@ public static void run() {
}
}

private static void compute(String expression) {
private void compute(String expression) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금 보니 Calculator에 compute기능이 있네요.
compute 내부 메서드를 잘 살펴보시겠어요? 객체에게 메세지를 보내는 것 같나요..?

해당 객체들은 메서드가 호출되어 스택이 올라갈 떄마다 힙영역에 매번 새로운 객체가 저장하겠네요.
이러한 방법이 좋은 방법인 것 같나요?

태훈님 지금 피드백해드리는데 피드백 해주는 것만 보지마시고 저번에 말씀드렸던 것 처럼 태훈님은 전체적인 코드를 다 손봐야해요.
객체지향적으로 구조를 다시 잡으시죠

Comment on lines 10 to 13
// private static final String PLUS = "+";
// private static final String MINIS = "-";
// private static final String MULTIPLY = "*";
// private static final String DIVIDE = "/";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 주석들은 뭔가요?

Comment on lines 12 to 35
Stack<String> operatorStack = new Stack();
String[] splitExpression = expression.split(" ");
Arrays.stream(splitExpression).forEach(str -> {
String value = str;
int operatorPriority = operatorPriority(value);
Operator operator = Operator.stringToOperator(str);
int operatorPriority = operatorPriority(operator);
int value = Integer.parseInt(str);
if (operatorPriority == -1) {
postfix += value + " ";
} else if (operator.isEmpty()) {
operator.add((value + " "));
} else if (operatorStack.isEmpty()) {
operatorStack.add((value + " "));
} else {
while (!operator.isEmpty()
&& operatorPriority(operator.peek().substring(0, 1)) >= operatorPriority) {
postfix += operator.pop();
while (!operatorStack.isEmpty()
&& operatorPriority(Operator.stringToOperator(operatorStack.peek().substring(0, 1)))
>= operatorPriority) {
postfix += operatorStack.pop();
}
operator.add((value + " "));
operatorStack.add((value + " "));
}
});
while (!operator.isEmpty()) {
postfix += operator.pop();
while (!operatorStack.isEmpty()) {
postfix += operatorStack.pop();
}
return postfix;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

읽기 좋은 메서드란 메서드내에 코드가 5줄이면 가장 읽기 좋고 10줄 이내여야 합니다.
태훈님이 직접 코드를 읽어보세요. 바로 눈에 들어오나요?

Comment on lines 38 to 47
public int operatorPriority(Operator operator) {
switch (operator) {
case "+":
case "-":
case PLUS:
case MINUS:
return 1;
case "*":
case "/":
case MULTIPLY:
case DIVIDE:
return 2;
}
return -1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

각 상수 객체 별로 반환되어야 하는 값이 정해져있는 것 같아요.
이러한 값들도 enum 안에 넣는게 어떤가요?

public static boolean checkExpressionValue(String expression) {
Matcher matcher = EXPRESSIONREGEX.matcher(expression);
if (!matcher.matches()) {
throw new IllegalArgumentException("잘못된 식 입력입니다.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

띄어쓰기

public static boolean checkSelectValue(String select) {
Matcher matcher = OPTIONREGEX.matcher(select);
if (!matcher.matches()) {
throw new IllegalArgumentException("잘못된 옵션 선택입니다");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

띄어쓰기

public static boolean checkOperatorValue(String operator){
Matcher matcher = OPERATORREGEX.matcher(operator);
if (!matcher.matches()) {
return false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

띄어쓰기

Comment on lines +44 to +61
firstOperand = result.pop();
secondOperand = result.pop();
result.push(secondOperand + firstOperand);
break;
case MINUS:
firstOperand = result.pop();
secondOperand = result.pop();
result.push(secondOperand - firstOperand);
break;
case MULTIPLY:
firstOperand = result.pop();
secondOperand = result.pop();
result.push(secondOperand * firstOperand);
break;
case DIVIDE:
firstOperand = result.pop();
secondOperand = result.pop();
result.push(secondOperand / firstOperand);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

읽어보시면 중복되는 로직이고 이전에 연산자에 대한 연산 로직도 구현을 해두셨던 것 같은데 괴리감이 느껴지지않나요?


public class InfixToPostfixConverter {

private String postfix = "";
private StringBuilder postfix = new StringBuilder();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

변수명이 무엇을 저장하는건지 와닿지 않아요.

Copy link
Member

@bombo-dev bombo-dev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?? 커밋이 InputView OutputView 통합인데 통합된 부분이 안보이는데요..?

Comment on lines +14 to +56
"100 200 + 300 + : 600"}, delimiter = ':')
public void postFixAddCalculate(String expression, int expectResult) {
Accumulator postFixAccumulator = new PostFixAccumulator();
int result = postFixAccumulator.calculate(expression);
Assertions.assertEquals(expectResult, result);
}

@ParameterizedTest
@DisplayName("뺼셈")
@CsvSource(value = {"1 2 - 3 -: -4", "10 30 - 20 -: -40", "300 200 - 1 - : 99"}, delimiter = ':')
public void postFixMinusCalculate(String expression, int expectResult) {
Accumulator postFixAccumulator = new PostFixAccumulator();
int result = postFixAccumulator.calculate(expression);
Assertions.assertEquals(expectResult, result);
}

@ParameterizedTest
@DisplayName("곱셈")
@CsvSource(value = {"1 2 * 3 *: 6", "10 20 * 30 *: 6000",
"100 200 * 300 * : 6000000"}, delimiter = ':')
public void postFixMultiplyCalculate(String expression, int expectResult) {
Accumulator postFixAccumulator = new PostFixAccumulator();
int result = postFixAccumulator.calculate(expression);
Assertions.assertEquals(expectResult, result);
}

@ParameterizedTest
@DisplayName("나눗셈")
@CsvSource(value = {"100 10 / 1 / : 10", "10 2 / : 5", "10000 20 / 10 / : 50"}, delimiter = ':')
public void postFixDivideCalculate(String expression, int expectResult) {
Accumulator postFixAccumulator = new PostFixAccumulator();
int result = postFixAccumulator.calculate(expression);
Assertions.assertEquals(expectResult, result);
}

@ParameterizedTest
@DisplayName("사칙연산")
@CsvSource(value = {"5 3 2 * + 8 4 / - : 9", "7 4 * 2 / 3 + 1 - : 16",
"9 5 - 2 * 6 3 / +: 10"}, delimiter = ':')
public void PostFixCalculate(String expression, int expectResult) {
PostFixAccumulator calculator = new PostFixAccumulator();
int result = calculator.calculate(expression);
Assertions.assertEquals(expectResult, result);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given when then 분리해주세요


public class Repository {

private List<String> list = new ArrayList<>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음 이건 리스트로 그대로 가져가실 생각이신가봐요

}
}

private void selectOptions(ConsoleInput input, int select) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메서드 명은 분명히 selectOptions 무언가 반환하는게 아닌 내부에서 행위를 수행하고 있네요.

Comment on lines +16 to +18
selectInput = bufferedReader.readLine();
} catch (IOException e) {
throw new IllegalArgumentException("잘못된 옵션 선택입니다.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IOException이 뭔가요? 여기서 어떻게 잘못된 옵션 선택인지 알 수 있나요?

Comment on lines +27 to +30
expressionInput = bufferedReader.readLine();
} catch (IOException e) {
throw new IllegalArgumentException("잘못된 식 입력입니다.");
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 동일하네요

Comment on lines +17 to +22
for (Operator operator : Operator.values()) {
if (operator.getValue().equals(value)) {
return operator;
}
}
throw new IllegalArgumentException("잘못된 입력값 입니다.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것도 스트림으로 변경 할 수 있지 않을까요?


@Override
public void print(List<String> result) {
result.stream().forEach(System.out::println);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메서드 한줄에는 점 하나 지켜주세요

private List<String> list = new ArrayList<>();

public void store(String expression, String result) {
StringBuilder formattedExpression = new StringBuilder(expression).append(" = ").append(result);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

메서드 한 줄에 점하나 지켜주세요.


public class PatternValidator {

private static final Pattern EXPRESSIONREGEX = Pattern.compile(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수 표기시 단어 분리 시점은 _ 로 분리합니다.
ex ) EXPRESSION_REGEX

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

public class ChangToPostfixTest {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

클래스 명이 잘못되었네요. 또한 ChangeToPostfixTest로 할 의도였다면 저번에도 얘기했지만 클래스명은 명사입니다.


private Repository repository;


Copy link
Member

@bombo-dev bombo-dev Sep 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

쓸데없는 개행

});
}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

쓸데없는 개행

}

}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

쓸데없는 개행

System.out.print("선택 : ");
}


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

쓸데없는 개행

private void processToken(Stack<String> operatorStack, String token) {
if (PatternValidator.checkOperatorValue(token)) {
handleOperator(operatorStack, token);
} else if (!PatternValidator.checkOperatorValue(token)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ㅎㅎ.. 이 코드가 if else 랑 뭐가 다른가요

@bombo-dev
Copy link
Member

ConsoleInput Class에서 잘못된 입력 값이 들어왔을 때 서로 다른 메시지를 주기 위해서 같은 로직인 메서드를 2개 만들었습니다. 반복적인 코드가 좋지 않다고 생각이 들었는데요. 이걸 한 개의 메서드로 바꾸고 매개변수를 추가해서 잘못된 코드가 들어왔을 때 메시지를 추가해 주는 게 좋을까요?

  • 무슨 질문인지 이해가 안돼요, 만약 Input에서 예외메시지를 작성하는 부분이었다면 그 부분 자체가 잘못되어서 고민거리가 되지는 않겠네요. 외부에서 값을 받는다면
public static void print(Exception e) {
    System.out.println(e.getMessage());
}

정도로 가능하지 않을까싶어요.

잘못된 입력이 들어왔을 때 IllegalArgumentException을 던지는데 사실 저는 잘못된 매개변수 같은 경우는 컴파일 시점에서 다 잡아주니 저 예외보단 커스텀 예외를 만들어서 처리하는 게 더 직관적이라고 생각이 드는데 직렬화 문제와 실무에서 혼잡성 문제가 있다고 하셔서 사용하지 않았는데 뭐가 더 좋을까요?

  • 잘못된 매개변수를 컴파일 시점에서 어떻게 잡을까요. 컴파일 에러란 무엇일까요? 제대로 알고 용어를 사용하지 않는 것 같아요.
  • IllegalArgumentException 이라는 예외를 읽으면 개발자들은 모두 이 예외가 어떤 예외를 반환하는지 알고 있습니다. 잘못된 인자가 파라미터로 전달되었다는 말이지요. 그러나 Custom 예외를 사용하게 되면 InValidInputValueException 이 되거나 더 좋은 커스텀 예외명이 있으면 추천해주시면 좋을 것 같습니다. 해당 커스텀 예외를 봤을 떄 다른 개발자는 흠.. 이 예외가 무슨 예외지? 하고 예외를 한 번 더 들어가서 확인을 하는 상황이 발생됩니다. 개발에서 정답이 없는 부분은 많습니다. 무엇이 더 좋은 것 같을지는 태훈님만의 근거를 가지고 얘기해주시면 좋을 것 같아요.
  • ex) 커스텀 예외를 사용했을 때는 x의 장점과 단점이 있고, 표준화된 예외를 사용했을 때의 x의 장점과 단점이 있습니다. 하지만 이러한 부분은 xx를 통해서 해결이 가능하고 다음과 같은 상황이 저는 조금 더 이상적이라고 생각하기에 이를 사용했습니다. 와 같이 명백한 근거를 대주세요.

람다를 사용하라고 하셨는데 간단하고 재사용성도 좋지만 함수형 인터페이스를 사용해서 람다를 쓰면 오히려 유지 보수에 안 좋지 않나요? 혹시 람다 사용을 추천해 주신 이유가 궁금합니다.

  • 람다가 재사용성이 좋을까요? 람다를 얘기하시는 건지 함수형 인터페이스를 말씀하시는 건지 모르겠습니다. 용어를 혼동하시는 것 같아요.
  • 이 부분은 얘기 할 내용이 너무 많습니다. 자바 언어의 탄생배경 익명 클래스의 탄생 이유 , 함수형 프로그래밍의 패러다임 변화 등 내용이 깊어서
    https://mangkyu.tistory.com/111 링크 참조 드립니다.

피드백 해주셨을 때 코드 한줄 한줄 근거를 가지고 짜야 된다라고 말해주셨는데 기존엔 그냥 구현에만 중점을 두고 객체지향이란 점을 생각을 하지 않고 짰습니다. 리팩토링 하는 과정에서 제가 객체지향, SOLID, 디자인 패턴의 개념이 너무 부족하기도 하고 습관을 한순간에 바꾸려고 하는 부분에서 코딩에 대한 거부감이 너무 강하게 들었습니다. 또한 경험의 부족인건지 잘못된 공부법인지 모르겠는데 공부한 부분을 코드로 나타내기 힘들다고 느꼈습니다.좋은 방법 아시면 추천 부탁드려요! 조금씩 피드백 받으면서 변화해보도록 하겠습니다!

  • 부족함을 느꼈다면 거기서부터 출발입니다.
    Image
  • 제가 좋아하는 그래프입니다. 더닝크루거 곡선이라는 건데 저 솟아있는 부분이 우매함의 봉우리라고 나 좀 잘하는 것 같은데? 라고 느끼는 부분입니다. 그리고 실제로 교수님들이 있는 부분은 우측에 조금 올라가는 부분 저 언저리이구요. https://velog.io/@mir21c/%EB%8D%94%EB%8B%9D-%ED%81%AC%EB%A3%A8%EA%B1%B0-%EA%B3%A1%EC%84%A0 다른 사람의 회고를 보는 것도 도움이 될겁니다.

코딩에 대한 거부감이 너무 강하게 들었습니다.

  • 질문이 많아서 쪼갰습니다. 거부감이 드는 이유는 여러가지 복합적인 상황이 있을겁니다.
  1. 나는 잘한다고 생각했는데 아는게 하나도 없는 것 같다는 무력감
  2. 지금까지 공부해온 시간이 부정당하는 느낌
  3. 지금까지 체득 된 코딩 습관이 너무 몸에 배여서
  4. 등등...
  • 언러닝(UnLearning) 이라는 말이 있습니다. 잘못된 지식 혹은 오래된 지식이 몸에 배여있고 새로운 것을 배울 때 쉽사리 기존에 있는 지식이 교체되지 않는 다는 것이지요. 제일 좋은 방법은 기존에 있던 지식을 버리고 즉, 나는 아무것도 모른다는 생각으로 새로운 것을 받아들이는 방식이 제일 좋다고 합니다. 그리고 새로운 것을 배우고 이전에 내가 배웠던 것을 어디에 적어보면서 내가 무엇을 잘 못 알고 있었는지를 비교하면 그게 더 명확하게 다가오겠지요.
  • 태훈님과 저와의 차이점은 저는 책으로 공부하면서 스스로 내가 코딩을 잘못하고 있었구나 라는 것을 깨닫고 기존에 있는 지식을 그냥 내다버렸습니다. 그리고 새로운 지식으로 집어넣었구요. 그리고 태훈님의 고민들이 일반적으로 주니어 개발자 혹은 코딩을 처음 배우다가 객체지향이라는 개념을 제대로 배우는 순간 겪게 되는 많은 경험입니다. 뭐든 새로운 것을 배울 때에는 고되고 힘듭니다. 그리고 앞으로도 그런 일이 자주 있을 겁니다. 차근차근 배워나가서 내껄로 만드는게 가장 중요해요.

또한 경험의 부족인건지 잘못된 공부법인지 모르겠는데 공부한 부분을 코드로 나타내기 힘들다고 느꼈습니다.

  • 만약 구현을 하기 어렵다면, 코드를 생각하면서 짜는 습관이 안들여져있거나, 생각하고 난 이후 코드를 짜는 습관이 안 들여져있어서 그럴겁니다.
    이전에도 말씀드렸지만 신입 개발자로서 가장 중요한 것은 구현력입니다. 여기서 말하는 구현력이란 어떤 문제 상황을 맞닥드렸을 떄 그것을 해결하기 위한 방법은 코드로 구현하는 것을 얘기해요. 기업에서 코딩 테스트를 보는 이유가 그런 이유입니다. 카카오에서 포트폴리오 하나 없이 CS 지식, 코테 실력만 출중하다면 뽑는 이유가 그런 이유도 있겠지요.
  • 만약 객체지향적인 개발을 하기 어렵다면 이는 당연합니다. 새로운 것을 배우고 적용하는 과정은 원래 어렵고 힘든 길입니다. 또한 경험치 조차 부족하니 이는 더 힘들겠지요. 시니어 개발자들도 객체지향적으로 개발 할 때 많은 고민들을 한다고 합니다. 나는 배우자마자 바로 뚝딱 해낼거야! 라는 욕심을 버리세요. 태훈님은 지금까지 따라쓰기 코드를 많이 짜셔서 어떠한 생각 그리고 근거를 바탕으로 코드를 짜는 습관이 더 안들여져있어서 그럴 가능성이 크다고 생각해요.
  • 가장 좋은 방법은 코드를 잘 짜는 사람의 코드를 짜는 것. 그리고 어떠한 사고과정으로 객체지향적인 개발을 하는지 보는게 제일 좋을 것 같아서 포스팅 하나 남깁니다. 인프런의 CTO인 향로님이 7년전 객체지향적인 개발을 더 잘하기 위하여 작성한 포스팅입니다. 정말 좋은 내용들이 있으니 꼭 깊게 읽어보세요. https://jojoldu.tistory.com/62
  • 마지막으로 배움의 시작은 메타인지입니다. 먼저 자신이 무엇이 부족한지를 찾습니다. 그리고 부족한 부분을 하나 하나 채워나갑니다. 이게 끝입니다. 저 같은 경우는 더닝 크루거 곡선을 항상 상기하고는 해요. 제가 예전에도 말씀드렸지만 공부하다보면 이건 왜 이렇게 되지? 라는 부분이 생기기 마련입니다. 만약 이런 부분이 생기지 않는다면 생각하면서 공부를 안하시는거에요. 항상 생각하면서 공부하는 습관을 기르시길 바랍니다. 그리고 이러한 습관이 자리가 잡히게 되면 어 이건 왜? -> 나 이거 왜 모르지? 가 되고 자신이 스스로 찾아보면서 공부를 하게 됩니다.

질문이 많아서 얘기가 길어졌는데 태훈님이 지금 위에서 말씀하신 부족하다고 생각하는 부분. 그런 부분을 찾아서 공부하세요. 다만 디자인 패턴은 양이 많아요. 그리고 디자인 패턴을 익히기 가장 좋은 방법은 직접 코드로 해당 디자인 패턴을 안 보고 어디에 그림을 그려보고 코드로 구현해보는 겁니다. 자료구조를 처음 공부 할 때를 떠올리면 좋겠네요.

지금 태훈님에게 가장 중요한건 기존의 습관들을 버리고 새로운 습관들이 자리잡도록 하는 겁니다. 만약에 이게 너무 하기 싫다. -> 저 개발자 하기 싫어요. 랑 다를게 없습니다.

@@ -14,7 +14,7 @@ public void store(String expression, String result) {
}

public List<String> getResult() {
return list;
return new ArrayList<>(list);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new ArrayList를 이용하여 반환해주는 것도 좋지만 Collections.unModifiableList(list);
list.stream().toList(); 라는 것도 있습니다. 공부해보면 좋을 것 같아요.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants