자바를 잘하는 법은 뭘까? 우아한테크코스 프리코스를 진행하면서 자바를 잘하는 것은 결국엔 리팩토링에 능숙한 것 이라고 생각이 들었다. 더 나아가면 리팩토링 하기도 전에 처음부터 패키지 관리를 잘해서 유지 보수가 쉬운 코드를 만들 수 있는 것이라고 생각들었다.
그러던 중에 소프트웨어 공학 수업을 들으면서 GOF패턴에 대해서 알게 되었다.그중에 두가지 중요한 패턴, Strategy pattern, Template pattern 이 인상 깊었다. 이 두가지를 알면 자바를 마스터 할 수 있을 것 같았다.
프리코스를 진행하면서 가장 힘들었던 것이 어떤 문제를 MVC패턴으로 나누고, 테스트를 진행하면서 오류가 있는 코드를 고치는 것이었다. 고치는 과정에서 어떤 소스코드에 있는지도 잘 모르겠었고, 성능도 안좋아서 실행하는데 오래 걸렸다.
소프트웨어 공학 수업은 유지 보수가 쉬운 technic을 배우는 수업이었는데
이 두가지 패턴 내용이 어려운건 아니다. 문제는 어떤 랜덤한 상황이 닥쳤을 때 수학문제 푸는 것 처럼 빠르게 적용을 해서 유지 보수가 쉬운 코드를 만드는 사고를 해야한다는 것이다.
다음 코드를 template method를 이용해서 리팩토링을 하시오.
public class Application {
public boolean open(String fileName) {
boolean canRead = false;
// check whether the file can be read!
if ( fileName.toUpperCase().endsWith(".doc") ) {
canRead = checkDocFile(fileName);
}
else if ( fileName.toUpperCase().endsWith(".xls") ) {
canRead = checkXlsFile(fileName);
}
if ( canRead == false ) return false;
boolean result = false;
// read and process the file
if ( fileName.toUpperCase().endsWith(".doc") ) {
result = processDoc(fileName);
}
else if ( fileName.toUpperCase().endsWith(".xls") ) {
result = processXls(fileName);
}
return result;
}
private boolean processXls(String fileName) {
return false;
}
private boolean processDoc(String fileName) {
// 주어진 file이 DOC 파일의 내용을 처리함
return false;
}
private boolean checkXlsFile(String fileName) {
// 주어진 file이 XLS 파일의 내용을 처리함
return false;
}
private boolean checkDocFile(String fileName) {
// 주어진 file이 DOC의 format인지 확인함
return false;
}
}
주어진 문제는 open()메소드를 가진 application을 template method 를 이용해 refactoring하는것
package org.example;
public abstract class FileProcessor {
public boolean open(String fileName) {
boolean canRead = false;
if(isValidFileFormat(fileName)){
canRead = checkFile(fileName);
}
if(!canRead){
return false;
}
return processFile(fileName);
}
public abstract boolean checkFile(String fileName);
public abstract boolean processFile(String fileName);
protected abstract boolean isValidFileFormat(String fileName);
}
package org.example;
public class doc extends FileProcessor{
@Override
public boolean checkFile(String fileName) {
// 주어진 file이 DOC의 format인지 확인함
return false;
}
@Override
public boolean processFile(String fileName) {
// 주어진 file이 DOC 파일의 내용을 처리함
return false;
}
@Override
protected boolean isValidFileFormat(String fileName) {
return fileName.toUpperCase().endsWith(".doc");
}
}
package org.example;
public class xls extends FileProcessor {
@Override
public boolean checkFile(String fileName) {
// 주어진 file이 XLS 파일의 내용을 처리함
return false;
}
@Override
public boolean processFile(String fileName) {
// 주어진 file이 XLS 파일의 내용을 처리함
return false;
}
@Override
protected boolean isValidFileFormat(String fileName){
return false;
}
}

나는 왜 application에서 fileName.toUpperCase().endsWith(".doc")를 통해서 fileName을 체크하지 않고 바로 check()로 canRead 변수를 초기화 했을까. 버젓이 적혀있는데 말이다.
isValidFormat함수 자체를 만들지 않고, 두 함수만 override했다.
곰곰히 생각해보니 'check'라는 함수를 override하니까, 그 안에 fileName을 체크하는 것도 들어가지 않을까? 라는 생각을 한거 같다.
근데 문제에서 구체적으로 주어진 조건이고, 그 말은 따로 그 기능을 발휘하는 것을 만들어야한다는 의도인데, 생각하지 못한 것이 아쉽다.