- Document 클래스의 객체를 생성하기 위해서는 File 및 FileVersion 객체를 함께 생성해야 합니다. Document 객체만 생성해서는 쓸모가 없기 때문입니다.
- Document 클래스 내에 File 및 FileVersion 객체를 생성할 수 있으나, 소프트웨어 설계 시에 가급적 KISS (Keep It Simple Stupid!) 원칙을 기억해야 합니다. 한번에 많은 기능을 구현할 수도 있고, 때로는 그런 방식으로 작업하는 것이 생산성이 높다고 여겨질 수 있습니다. 그러나, 소프트웨어는 살아있는 생명이며, 최초에 모든 요구사항(기능명세)을 명확히 결정하고 코딩할 수 없습니다. 따라서, 각각의 클래스는 최소한의 기능을 담도록 하고 변경이 발생할 가능성이 줄어들게끔 적은 라인의 코드를 담는 것이 좋습니다. 작은 모듈은 더 이상 필요 없을 때 폐기하는데도 유리합니다.
- 따라서, Document 클래스 자체는 문서를 표현하는 데이터를 담는 역할만 수행하도록 제한하고, 문서와 그에 따른 부가적인 객체를 생성하는 역할을 별도의 빌더(builder) 클래스로 분리했습니다.
- 나아가, 빌더 자체도 Document, File, FileVersion 을 생성하는 역할로 제한했습니다. 문서를 분석하고, 키워드, 요약, 체크섬 등을 생성하는 작업은 ContentAnalyzer 클래스로 분리했습니다.
ContentAnalyzer.java
DocumentBuilder.java
public class DocumentBuilder {
...... 중략 .....
public Document createDocument() {
// ---- 필수 항목 점검 및 analyzer 준비 ----
if(location == null) {
throw new IllegalStateException("location property is not specified");
}
if(writer == null) {
throw new IllegalStateException("writer property is not specified");
}
ContentAnalyzer contentAnalyzer = new ContentAnalyzer(location);
contentAnalyzer.analyze();
// ---- 입력 값이 없는 항목에 대한 대체 처리 -----
if(createDate == null) {
createDate = new Date(Calendar.getInstance().getTimeInMillis());
}
if(title == null) {
title = contentAnalyzer.getFileName();
}
// -- FileVersion, File, Document 순서로 빌드 -----
FileVersion fileVersion = new FileVersion(1, createDate, description);
File file = new File(location, contentAnalyzer.getChecksum(), contentAnalyzer.getSize(), fileVersion);
Document document = new Document(title, writer, keywords,
contentAnalyzer.getAbstraction(), location, contentAnalyzer.getFormat());
document.addFile(file);
return document;
}
}
package docar.archive.document;
/**
* 문서 파일을 분석하는 클래스.
*
* @author "Sunny Kwak"
*/
public class ContentAnalyzer {
private static final String HTTP_PROTOCOL = "http";
private URL location;
private String fileName;
private long fileSize;
private String checksum;
public ContentAnalyzer(URL location) {
this.location = location;
}
public void analyze() {
InputStream inputStream = null;
try {
String protocol = location.getProtocol();
if (protocol == null
|| !protocol.toLowerCase().equals(HTTP_PROTOCOL)) {
inputStream = new FileInputStream(new java.io.File(location.toURI()));
} else {
inputStream = location.openConnection().getInputStream();
}
fileName = location.getFile();
fileSize = 0L;
checksum = getMD5Checksum(inputStream);
} catch (IOException e) {
// FIXME add logging
e.printStackTrace();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException ignored) {
// do nothing
}
}
}
}