후기

1주차 우테코 프리코스 후기

잼추 2024. 10. 20. 23:41
# 🔢문자열 덧셈 계산기

<br/>

## 🔍기본 과제 요약

1. 기본 구분자로 ;와 ,를 사용합니다.
2. 커스텀 구분자를 추가할 수 있습니다.
3. 입력된 숫자들의 합을 계산하여 반환합니다.

<br/>

## 🔧 미션 구현 방식
1. 입력 문자열 검증
2. 커스텀 구분자 추가 여부 확인
3. 커스텀 구분자 추출 후 추가
4. 구분자를 이용해 문자열 분리
5. 분리된 문자열을 숫자로 반환 및 유효성 검사
6. 숫자들의 합 계산
7. 결과 반환

<br/>

## 📂 파일 구조도
``` 
└─src
    ├─main
    │  └─java
    │      └─calculator
    │          │  Application.java
    │          │
    │          ├─constant
    │          │      ValidConstants.java
    │          │      ViewConstants.java
    │          │
    │          ├─controller
    │          │      CalculateController.java
    │          │
    │          ├─exception
    │          │      InputValidationException.java
    │          │
    │          ├─model
    │          │      Numbers.java
    │          │      Separator.java
    │          │
    │          ├─service
    │          │      CalculateService.java
    │          │      SplitService.java
    │          │
    │          ├─validator
    │          │      InputValid.java
    │          │
    │          └─view
    │                  InputView.java
    │                  OutputView.java
    │
    └─test
        └─java
            └─calculator
                    ApplicationTest.java
                    ControllerTest.java
                    ServiceTest.java
                    ViewTest.java

```


## 📚 패키지 설명

1. **calculator**: 메인 패키지
    - `Application.java`


2. **constant**: 상수 정의
    - `ValidConstants.java`: 유효성 검사 관련 상수
    - `ViewConstants.java`: 입 출력 관련 상수
   

3. **controller**: 사용자 입력 처리 및 비즈니스 로직 연결
    - `CalculateController.java`: 계산 전 과정 제어


4. **exception**: 사용자 정의 예외
    - `InputValidationException.java`: 입력 유효성 검사 예외 메시지


5. **model**: 데이터 모델
    - `Numbers.java`: 숫자 데이터 관리
    - `Separator.java`: 구분자 관리


6. **service**: 비즈니스 로직
    - `CalculateService.java`: 실제 계산 수행
    - `SplitService.java`: 문자열 분리 로직
   

7. **validator**: 입력 유효성 검사
    - `InputValid.java`: 사용자 입력 검증
    

8. **view**: 사용자 인터페이스
    - `InputView.java`: 사용자 입력 처리
    - `OutputView.java`: 결과 출력

<br/>


## 🧪 테스트 설명

1. **ApplicationTest.java** : 전체 애플리케이션의 통합 테스트
    - 사용자 입력부터 결과 출력까지의 전체 흐름을 테스트
   

2. **ControllerTest.java** : 컨트롤러 로직 테스트
    - 사용자 입력 처리와 서비스 계층 연동이 올바르게 작동하는지 확인
   

3. **ServiceTest.java** : 비즈니스 로직 테스트
    - 계산 및 문자열 분리 로직이 동작 검증
   

4. **ViewTest.java**: 사용자 인터페이스 테스트
    - 입력 처리와 결과 출력이 올바르게 이루어지는지 확인


<br/>

## ✅ 유효성 검사

```java
public static void checkStringLength(String str) {
    if (str.length() > ValidConstants.MAX_TOTAL_LENGTH) {
        throw new IllegalArgumentException(InputValidationException.TOO_LONG_STRING.getMessage());
    }
    if (str.isEmpty()) {
        throw new IllegalArgumentException(InputValidationException.EMPTY_STRING.getMessage());
    }
}
```

### 상수 관리

- 유효성 검사에 사용되는 상수들은 `ValidConstants` 클래스에서 관리

### 예외 메시지

- 예외 메시지는 `InputValidationException` enum 클래스에서 관리


## 🔄 DI - singleton
- 주요 service 클래스와 controller 클래스에 싱글톤 패턴 적용

```java
    private static CalculateService instance;

    private CalculateService() {
    }

    public static CalculateService getInstance() {
        if (instance == null) {
            instance = new CalculateService();
        }
        return instance;
    }
```

 

여기서 부터 찐찐 후기 ㅎㅎ

 

이번 과제에서는 몇가지의 고민사항들이 있었습니다.
특히 커스텀 구분자를 분리하는 부분에서 가장 큰 문제가 있었습니다.  "//.\n"와 같은 정규식을 사용하여 커스텀 구분자를 식별하고자 하였으나, \n 이 일반적인 문자열로 인식되지 않아 게속 예외를 발생 시켰습니다.
    public static final Pattern CUSTOM_SEPARATOR_PATTERN = Pattern.compile("^//(.*)\\\\n(.*)");
그래서 앞에 \\ 두개를 더 추가해 주어 문장 띄우기가 아닌 문자로 인식 할 수 있었습니다.
두번째 문제는 입력 받은 String 값을 확인하고 커스텀 구분자를 추출하여 구분자 리스트에 추가하는 작업을 어떤 클래스에서 처리 해 주어야 하는가에 대한 고민이었습니다. 덧셈 부분만 비즈니스로직으로 처리해주려고 하였으나, 분리 하는 부분도 따로 분리해 주어야 할 것 같아 후에 split service를 추가해주었습니다.
세번째는 각 클래스들을 싱글톤으로 처리할 필요가 있는지 였습니다. 이 과제들을 MVC패턴을 준수하여 구현되었지만, 컴포넌트 간의 의존성 주입 방식에 대해 고민하게 되었습니다. 특히 생성자 주입방식이 적절한지에 대한 의문이 있었고,  일관된 상태 관리와 리소스 효율성을 높이는 데 유효하다고 판단하여 싱글톤으로 주요 클래스들을 구현하였습니다.
마지막으로는 각종 제한 사항과 범위였습니다. 숫자가 아닌 다른 문자를 입력받거나 너무 긴 문자열, 너무 많은 숫자 입력 등 다양한 문제 점이 발생 할 것 같다고 판단하였습니다. 하지만 문제에서는 대부분의 제한사항을 개인에게 일임하고 있어, 해당 부분을 구현 할 때 많은 많은 고민을 하였습니다.
최대한 예상치 않은 exception이 발생 하지 않도록 처리하였습니다.