2015. 3. 14. 22:52
  • 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
				}
			}
		}

	}


Posted by 곽중선