스터디가 현재로서는 1주차에 작성했던 <학점 계산기>를 개선해 나가는 방향으로
진행되고 있어,
2주차는 1주차에 작성했던 <학점 계산기> 코드를 개선하는 방향으로 코드를 수정해 보았다!
코드 수정 방향은
정도였다.
사실 일급 컬렉션 만들기는, 과제 처음 할 당시에는 이해를 잘 못해서 구현을 못했었다..ㅠ
그래서 과제 초안에는...
Class 기반으로 옮기기
원시값 포장하기
그리하여 작성된 2주차 과제!
week2
│ index.ts
│
└───calculator
│ │ calculator.ts
│ │ grades.ts
│
└───constants
│ │ gradeScore.ts
│
└───interface
│ │ grade.ts
│
└───primitive
│ │ courseName.ts
│ │ credit.ts
│ │ score.ts
우선 다음과 같이 파일 구조를 분리하였다!
import { Grade } from '../interface/grade'
import { Grades } from './grades';
//학점계산기
export class GradeCalculator {
private _sampleGrade:Grade[];
constructor(sampleGrade:Grade[]) {
this._sampleGrade = sampleGrade;
}
public printResult():void {
const grades = new Grades(this._sampleGrade, 0, 0, 0);
grades.calc();
const gradeResult = grades.getGradeResult();
const totalCredit = grades.getTotalCredit();
console.log(`${totalCredit}학점에 ${gradeResult}입니다.`)
}
}
GradeCalculator(학점 계산기)를 Class로 만들어, calculator.ts로 따로 분리해 주었다.
Grade는 역시 따로 분리한 interface 디렉토리에 grade.ts에서 가져오는 방식으로 바꾸어 분리하였다.
P.S 관련 자료를 찾다 보니 인터페이스에 관해 정말 잘 정리해 주신 분이 계셔서
해당 글을 참고하면 좋을 것 같다!
import { Grade } from "../interface/grade";
import { Score } from "../primitive/score";
import { Credit } from "../primitive/credit";
import {CourseName} from '../primitive/courseName';
import { GRADE_SCORE } from "../constants/gradeScore";
export class Grades {
private _grades:Grade[];
private _totalScore:number;
private _totalCredit:number;
private _gradeResult:number;
constructor(grades:Grade[], totalScore:number, totalCredit:number, gradeResult:number) {
this._grades = grades;
this._totalScore = totalScore;
this._totalCredit = totalCredit;
this._gradeResult = gradeResult;
}
public calc():void {
for (let {성적, 학점, 과목명} of this._grades) {
const score = new Score(성적);
const credit = new Credit(학점);
const courseName = new CourseName(과목명);
const validatedScore = score.validate();
const validatedCredit = credit.validate();
const validatedCourseName = courseName.validate();
this._totalScore += GRADE_SCORE[validatedScore] * validatedCredit ;
this._totalCredit += validatedCredit;
}
this._gradeResult = parseFloat((this._totalScore/this._totalCredit).toFixed(2));
}
public getGradeResult():number {
return this._gradeResult;
}
public getTotalCredit():number {
return this._totalCredit;
}
}
피드백 + 다른 팀원분들의 코드를 참고해서..
grades.ts 파일로 일급 컬렉션을 만들어 보고자 했는데..
사실 추가 피드백을 받기 전이라 개념을 제대로 이해한 건지, 이게 맞는지는 잘 모르겠다..
Grades라는 일급 컬렉션을 만들어서,
계산의 책임을 일급 컬렉션에 옮기는 것이 핵심이었던 것 같긴 함!
그래서 계산 로직을 grades.ts로 옮기는 방향으로 우선 코드를 수정해 보았고,
const score = new Score(성적);
const credit = new Credit(학점);
const courseName = new CourseName(과목명);
const validatedScore = score.validate();
const validatedCredit = credit.validate();
const validatedCourseName = courseName.validate();
이 부분에서는 원시값 포장 개념을 적용하여 유효성을 검사하고자 해 보았다.
export class CourseName {
private _courseName:string;
constructor(courseName:string) {
this._courseName = courseName;
}
validate() {
const regex = /[!@#$%^&*+=]/
if (!(regex.exec(this._courseName))) {
return this._courseName;
}
throw new Error('강의명은 특수문자를 포함하지 않습니다.')
}
}
export class Credit {
private _credit:number;
constructor(credit:number) {
this._credit = credit;
}
validate() {
if (this._credit > 0 && this._credit < 4) {
return this._credit;
}
throw new Error('학점은 1 ~ 3 까지의 값입니다.')
}
}
export class Score {
private _grade:string;
constructor(grade:string) {
this._grade = grade;
}
validate() {
const regex = /[ABCDF]\+?/;
if (regex.test(this._grade)) {
return this._grade;
}
throw new Error('유효한 성적이 아닙니다.')
}
}
위 세 개의 파일에서는 각각 강의명, 학점, 성적(A+ ~ F)를 원시값 포장하였다!
validate라고 이름지은 함수를 통해 유효성을 검사했는데,
학점과 강의명에서는 정규표현식을 사용해 보았다!
Typescript에서 정규표현을 사용해 본 것은 처음이었는데,
정규표현을 처음 배웠던 Python과 크게 다르진 않아서!
문법이 자잘하게 다른 부분 정도만 구글링해서 적용하였다.
import { GradeCalculator } from "./calculator/calculator";
import {SAMPLE_GRADE_ONE, SAMPLE_GRADE_TWO, SAMPLE_GRADE_THREE} from '../mock/index'
const gradeResultOne = new GradeCalculator(SAMPLE_GRADE_ONE);
const gradeResultTwo = new GradeCalculator(SAMPLE_GRADE_TWO);
const gradeResultThree = new GradeCalculator(SAMPLE_GRADE_THREE)
gradeResultOne.printResult();
gradeResultTwo.printResult();
gradeResultThree.printResult();
뚝딱뚝딱 파일을 분리해서 만든 학점 계산기 Class를 가져와서
GradeCalculator 객체를 만들고 printResult 함수로 결과를 출력해 주는 것으로 마무리 ! :)
그래도 그만큼 여러 가지를 배울 수 있는 과정이 되기를 바라며 :)