일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 파일
- System Requirement Specification
- Database
- analysis
- 네크워크
- FIle
- 제안서
- vision document
- 메소드
- 이클립스 설정
- 설정
- 소켓
- custom Tag
- srs
- sequence diagram
- java
- 게시판 제작
- Eclipse
- js꼬리
- 자바
- jdbc
- 게시판
- workspace
- network
- Ecilpse
- 클래스
- 데이터베이스
- jdk설치
- IO
- mindmap
- Today
- Total
공적's life
3-2 클래스로 분리 본문
우리는 이제 클래스로 분리 하려고 합니다. 저번에는 메소드로 분리하였는데
어느 정도 분업이 가능했지만 이제는 좀더 진화한 분업을 위하여 클래스로
분리하여 각자 클래스를 작성할 수 있게 해보겠습니다.
일단 기능 별로 분리 해보도록 하죠^^;
제가 제일 처음 한일은 먼저 패키지를 작성하였습니다. 이제는 패키지로 관리 해볼까 해서요^^;
일단 우리가 작성하는 패키지의 이름은 com.tistory.melpis.board 입니다. 어디서 많이 보던
이름이죠? 일반적으로 패키지는 주소를 꺼꾸로 잡습니다. 간단하죠? 만약에 꺼꾸로 하지 않으면
묶이질 않고 서로 따로 놀게 됩니다.
그 다음에 한일은 Board의 클래스 이름을 변경 하였습니다. 일단은 BoardExecution 라고 했네요,
그리고 메소드들을 전부 BoardManager클래스를 생성하여 옴 겼습니다.
일단 컴파일 에러 하나씩 잡아볼까요?
그전에 다른, 클래스에서 참조 할 수 있도록 private static을 제거해보죠.
제거하고 나서
//3.3 클래스 생성
BoardManager boardManager = new BoardManager();
if (userAction.equals("RF")) {
boardManager.registDoumentForm();
} else if (userAction.equals("RD")) {
boardManager.registDocument(outputData);
} else if (userAction.equals("VD")) {
boardManager.viewDocument(outputData);
} else if (userAction.equals("VL")) {
boardManager.viewDocumentList();
} else if (userAction.equals("DD")) {
boardManager.deleteDocument(outputData );
} else if (userAction.equals("EF")) {
boardManager.editDocumentForm(outputData);
} else if (userAction.equals("ED")) {
boardManager.editDocument(outputData);
} else {
System.out.println("잘못 입력하셨습니다");
}
}
이렇게 바꾸니까 BoardExecution 란 클래스에 컴파일에러는 전부 제거 되었네요.
자아 이제 BoardManger클래스에 컴파일에러를 잡아 볼까요?
BoardExecution 에 있던 property를 옴 기니까 그냥 해결되네요^^;
아 쉽네요.
그리고 BoardManger 생성 할 때는 while문 밖에서 생성해야 합니다. 안 그러면 돌 때 마다 생성해서
데이터가 리셋이 되요.
음 그 다음에는 깔끔하지 못한 BoardManager를 손볼 시간입니다.
static영역을 사용하는 것은 안전하지 못하기 때문에
static대신 다른 것을 해보도록 하고, 이제는 데이터를 좀더 체계적으로 관리하기 위해서
단순히 타입으로 저장하는 것이 아니라 이것도 클래스로 옴 겨서 따로 관리해보도록 하죠.
그리고 기존에 SEQ번호를 루프를 통해서 검색했지만 색인을 만들어서 빠르게 검색해보도록 하죠.
잠깐 진행된 사항을 살펴볼까요?
public class BoardDataBase {
private static int systemSeq = 0;
private List<Map<String, String>> tableData = null;
public BoardDataBase() {
this.tableData = new ArrayList<Map<String,String>>();
}
public static int getSystemSeq(){
systemSeq+=1;
return systemSeq;
}
public void setTableData(Map<String,String> tableData){
this.tableData.add(tableData);
}
public List<Map<String,String>> getTableData(){
return this.tableData;
}
}
이제 생성자라는 것을 사용하게 되네요. 무언가 초기화 시켜줄 일이 있으면 사용한다고
생각하시면 됩니다. 여기서 한가지 알아야 할 점은 객체를 사용할 때 생성해주는 것이 좋아요.
일단은 선언만 해놓고 나중에 객체 생성하는 거죠. 하지만 세상에 반드시 라는 말은 잘 존재 하지 않기
때문에 여기에도 꼭 늦게 생성해줘야 하는 것은 아닙니다. 예외는 나중에 알아 보도록 하고요.
이 클래스는 어떻게 추출됐는가 하면요. 데이터를 다루는 것을 단지 이쪽으로 옴 긴 것뿐입니다.
자아 다시 진행해볼까요?
public class BoardManager {
private BoardDataBase boardDataBase = null;
public BoardManager(){
this.boardDataBase = new BoardDataBase();
}
public void registDocument(String[] outputData) {
// 6. 문서 번호 가져오기
int systemSeq = BoardDataBase.getSystemSeq();
this.boardDataBase.setTableData(documentSave);
}
}
코드에 일부분만 발취했습니다. 모든 메소드에서 BoardDataBase를 사용하기 때문에
Property로 이동되었고, SystemSeq는 단순히 번호만 주기 때문에 static으로 작성하였습니다.
이렇게 단순하게 사용 할 때는 static을 사용하시면 됩니다.
하지만 여기서 끝난 것이 아닙니다. 아직도 BoardManage클래스에서 데이터를 다루는 부분이 있네요.
이것들을 다시 BoardDataBase로 옴 겨 보도록 하죠^^;
public class BoardManager {
private BoardDataBase boardDataBase = null;
public BoardManager(){
this.boardDataBase = new BoardDataBase();
}
// 문서 등록 폼
public void registDoumentForm() {
// 1. 등록 폼출력
System.out.println("제목: ");
System.out.println("내용: ");
}
// 문서 등록
public void registDocument(String[] outputData) {
// 1.1 제목 추출
String userInputTitle = outputData[1];
// 1.2 내용 추출
String userInputContent = outputData[2];
// 2. 유효성 검사
if (userInputTitle.length() < 1 && userInputTitle.length() > 600) {
return;
}
if (userInputContent.length() < 1 && userInputContent.length() > 2000) {
return;
}
// 3. 등록
this.boardDataBase.insert(userInputTitle, userInputContent);
// 4. 결과 출력
System.out.println("등록 완료");
}
// 문서 상세 보기
public void viewDocument(String[] outputData) throws ParseException {
// 사용자가 입력한 문서 번호 가져오기
String userInputSeq = outputData[1];
int parameterSeq = Integer.parseInt(userInputSeq);
// 일치할경우 저장할 Map타입
Map<String, String> documentSave =this.boardDataBase.select(parameterSeq);
if (documentSave != null) {
String tempSeq = documentSave.get("SEQ");
int seq = Integer.parseInt(tempSeq);
String title = documentSave.get("TITLE");
String content = documentSave.get("CONTENT");
String tempRegistDate = documentSave.get("REGIST_DATE");
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy.MM.dd HH:mm:ss", Locale.KOREA);
Date registDate = dateFormat.parse(tempRegistDate);
String tempHit = documentSave.get("HIT");
int hit = Integer.parseInt(tempHit);
System.out.println("글번호 : " + seq);
System.out.println("제목 : " + title);
System.out.println("등록일 : " + registDate);
System.out.println("조회수 : " + hit);
System.out.println("내용 : " + content);
}
}
public void viewDocumentList()
throws ParseException {
//DataBase클래스에서 데이터 가져오기
List<Map<String, String>> tableData = this.boardDataBase.selectList();
for (int indexI = 0; indexI < tableData.size(); indexI++) {
Map<String, String> documentSave = tableData.get(indexI);
String tempSeq = documentSave.get("SEQ");
int seq = Integer.parseInt(tempSeq);
String title = documentSave.get("TITLE");
String content = documentSave.get("CONTENT");
String tempRegistDate = documentSave.get("REGIST_DATE");
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy.MM.dd HH:mm:ss", Locale.KOREA);
Date registDate = dateFormat.parse(tempRegistDate);
String tempHit = documentSave.get("HIT");
int hit = Integer.parseInt(tempHit);
System.out.println("글번호 : " + seq);
System.out.println("제목 : " + title);
System.out.println("등록일 : " + registDate);
System.out.println("조회수 : " + hit);
System.out.println("내용 : " + content);
}
}
public void deleteDocument(String[] outputData) {
// 사용자가 입력한 문서 번호 가져오기
String userInputSeq = outputData[1];
int parameterSeq = Integer.parseInt(userInputSeq);
this.boardDataBase.delete(parameterSeq);
System.out.println("삭제 되었습니다");
}
public void editDocumentForm(String[] outputData) throws ParseException {
// 사용자가 입력한 문서 번호 가져오기
String userInputSeq = outputData[1];
int parameterSeq = Integer.parseInt(userInputSeq);
// 일치할경우 저장할 Map타입
Map<String, String> documentSave = this.boardDataBase.select(parameterSeq);
// null 경우 처리 하지 않음
if (documentSave != null) {
String tempSeq = documentSave.get("SEQ");
int seq = Integer.parseInt(tempSeq);
String title = documentSave.get("TITLE");
String content = documentSave.get("CONTENT");
String tempRegistDate = documentSave.get("REGIST_DATE");
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy.MM.dd HH:mm:ss", Locale.KOREA);
Date registDate = dateFormat.parse(tempRegistDate);
String tempHit = documentSave.get("HIT");
int hit = Integer.parseInt(tempHit);
System.out.println("글번호 : " + seq);
System.out.println("제목 : " + title);
System.out.println("등록일 : " + registDate);
System.out.println("조회수 : " + hit);
System.out.println("내용 : " + content);
}
}
public void editDocument(String[] outputData) {
// 사용자가 입력한 문서 번호 가져오기
String userInputSeq = outputData[1];
String userInputTitle = outputData[2];
String userInputContent = outputData[3];
int parameterSeq = Integer.parseInt(userInputSeq);
this.boardDataBase.update(parameterSeq,userInputTitle,userInputContent);
System.out.println("수정완료 하였습니다");
}
}
전보다 간단해진 BoardManager클래스입니다. 이 클래스는 데이터를 넘겨주거나 혹은 출력하거나
이 두 가지 일만 한답니다. 저 두 개도 분리 해내고 싶지만 여기까지 하겠습니다.
이제 BoardDataBase를 제대로 만들어 볼까요? 이전까지 완성된 BoardDatabase입니다.
public class BoardDataBase {
private static int systemSeq = 0;
private List<Map<String, String>> tableData = null;
public BoardDataBase() {
this.tableData = new ArrayList<Map<String,String>>();
}
private static int getSystemSeq(){
systemSeq+=1;
return systemSeq;
}
//등록 (insert)
public void insert(String title, String content){
// 1. 문서 번호 가져오기
int systemSeq = BoardDataBase.getSystemSeq();
// 2. 등록일 가져오기
Date systemDate = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy.MM.dd HH:mm:ss", Locale.KOREA);
String sysDate = dateFormat.format(systemDate);
// 3. 조회수 입력
int configHit = 0;
Map<String, String> saveData = new HashMap<String, String>();
// 4. 등록
saveData.put("SEQ", String.valueOf(systemSeq));
saveData.put("TITLE", title);
saveData.put("CONTENT", content);
saveData.put("REGIST_DATE", sysDate);
saveData.put("HIT", String.valueOf(configHit));
this.tableData.add(saveData);
}
// 한건 조회 (select)
public Map<String,String> select(int seq){
//DataBase클래스에서 데이터 가져오기
List<Map<String, String>> tableData = this.tableData;
//String 타입으로 변환
String userInputSeq = String.valueOf(seq);
//return 해 줄 데이터
Map<String,String> returnData= null;
// 검사
for (int indexI = 0; indexI < tableData.size(); indexI++) {
Map<String, String> checkData = tableData.get(indexI);
if (userInputSeq.equals(checkData.get("SEQ"))) {
int updateHit = Integer.parseInt(checkData.get("HIT")) + 1;
checkData.put("HIT", String.valueOf(updateHit));
returnData = checkData;
break;
}
}
return returnData;
}
//여러건 조회 selectList
public List<Map<String,String>> selectList(){
return this.tableData;
}
//삭제 (delete)
public void delete(int seq) {
String userInputSeq = String.valueOf(seq);
// 검사
for (int indexI = 0; indexI < tableData.size(); indexI++) {
Map<String, String> checkData = tableData.get(indexI);
if (userInputSeq.equals(checkData.get("SEQ"))) {
this.tableData.remove(indexI);
break;
}
}
}
//수정 (update)
public void update(int seq,String title,String content){
// 일치할경우 저장할 Map타입
Map<String, String> saveData = null;
String userInputSeq = String.valueOf(seq);
//DataBase클래스에서 데이터 가져오기
List<Map<String, String>> tableData = this.tableData;
// 검사
for (int indexI = 0; indexI < tableData.size(); indexI++) {
Map<String, String> checkData = tableData.get(indexI);
if (userInputSeq.equals(checkData.get("SEQ"))) {
checkData.put("TITLE", title);
checkData.put("CONTENT", content);
Date systemDate = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy.MM.dd HH:mm:ss", Locale.KOREA);
String sysDate = dateFormat.format(systemDate);
checkData.put("REGIST_DATE", sysDate);
break;
}
}
}
}
뭐 실상 전에 BoardManager에서 하던 것을 이리로 옴 긴 것뿐입니다. 별거 없어요.
이제 색인을 만들어서 빠르게 찾거나 삭제 해보도록 할까요?
public class BoardDataBase {
private static int systemSeq = 0;
private List<Map<String, String>> tableData = null;
private List<String> index = null;
public BoardDataBase() {
this.tableData = new ArrayList<Map<String,String>>();
this.index = new ArrayList<String>();
}
private static int getSystemSeq(){
systemSeq+=1;
return systemSeq;
}
private void addIndex(int seq){
this.index.add(String.valueOf(seq));
}
private void updateIndex(int seq){
this.index.remove(String.valueOf(seq));
}
private int getIndex(int seq){
int dataLoaction = this.index.indexOf(String.valueOf(seq));
return dataLoaction;
}
//등록 (insert)
public void insert(String title, String content){
// 1. 문서 번호 가져오기
int systemSeq = BoardDataBase.getSystemSeq();
// 2. 등록일 가져오기
Date systemDate = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy.MM.dd HH:mm:ss", Locale.KOREA);
String sysDate = dateFormat.format(systemDate);
// 3. 조회수 입력
int configHit = 0;
Map<String, String> saveData = new HashMap<String, String>();
// 4. 등록
saveData.put("SEQ", String.valueOf(systemSeq));
saveData.put("TITLE", title);
saveData.put("CONTENT", content);
saveData.put("REGIST_DATE", sysDate);
saveData.put("HIT", String.valueOf(configHit));
this.tableData.add(saveData);
addIndex(systemSeq);
}
// 한건 조회 (select)
public Map<String,String> select(int seq){
//return 해 줄 데이터
Map<String,String> returnData= null;
// index에서 위치 찾아옴
int dataLoacation = getIndex(seq);
//table에서 데이터 꺼내옴
returnData = this.tableData.get(dataLoacation);
return returnData;
}
//여러건 조회 selectList
public List<Map<String,String>> selectList(){
return this.tableData;
}
//삭제 (delete)
public void delete(int seq) {
int dataLocation = getIndex(seq);
this.tableData.remove(dataLocation);
updateIndex(seq);
}
//수정 (update)
public void update(int seq,String title,String content){
// 일치할경우 저장할 Map타입
Map<String, String> saveData = null;
int dataLoaction = this.getIndex(seq);
saveData = this.tableData.get(dataLoaction);
saveData.put("TITLE", title);
saveData.put("CONTENT", content);
Date systemDate = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy.MM.dd HH:mm:ss", Locale.KOREA);
String sysDate = dateFormat.format(systemDate);
saveData.put("REGIST_DATE", sysDate);
}
}
클래스가 색인(index) 하나로 간단해졌죠?
이제 잠깐 인덱스 이야기를 해야 할듯하네요. 현재 상태에서는 tableData와 index 의 줄 즉 사이즈는
동일합니다. 예를 들어서 보죠.
Seq |
Title |
위치 |
1 |
하이 |
0 |
2 |
안녕하세요 |
1 |
3 |
방가요 |
2 |
이런 식으로 tableData를 구성되어있습니다.
1 |
위치[0] |
2 |
위치[1] |
3 |
위치[2] |
여기는 index입니다. Index는 List타입으로 seq를 저장합니다. 만약에 한 건의 데이터가
index에서 seq로 검색합니다. indexOf란 메소드를 사용해서 던져준 seq가 어떤 위치에 있는지
알아 냅니다. 그 다음은 그냥 tableData에서 꺼내 오기만 하면 끝입니다.
여기까지는 별로 문제가 안됩니다. 다음은 삭제 할 때를 살펴보죠.
Seq가 2인 것을 지워 봅니다.
Seq |
Title |
위치 |
1 |
하이 |
0 |
3 |
방가요 |
1 |
이렇게 됩니다. 이제 index도 고쳐볼까요?
1 |
위치[0] |
3 |
위치[1] |
이렇게 됩니다. tableData와 index가 항상 같은 사이즈를 유지 하는 것이 중요하고
같은 위치에 같은 seq를 가져야 합니다.
코드를 보면 사실 별거 없습니다. 생각만 조금하시면 금방 할 수 있어요.
자 오늘로써 java 버전 문서 관리를 끝내보고 I.O와 file을 해보도록하죠^^;
오늘은 코드량이 많아서 압축해서 올리게요. 스크롤 압박이 장난이 아닐거 같아서요 ^^;
'Programing > Java programing' 카테고리의 다른 글
4-1 I.O and File (0) | 2010.07.31 |
---|---|
3-3 메소드, 클래스 분리 회고 (0) | 2010.07.26 |
3-1 메소드로 분리 (0) | 2010.07.24 |
2-6 다음 진행을 위한 회고 (0) | 2010.07.23 |
2-5 문서관리 (수정) (0) | 2010.07.22 |