함수는 기억력이 없기 때문에 getParamAsInt() 함수를 호출 할 때마다 cmd를 해체하는 작업을 반복해야 한다.
예를 들어 "삭제?id=23&age=55"라는 cmd를 입력받았을 때 id를 추출하기 위해 getParamAsInt(cmd, "id",0)을 실행한 뒤 age를 추출하기 위해 또 다시 getParamAsInt(cmd, "age", 0)을 실행하여 그 때마다 queryString을 해체하는 작업을 해야할 것이다.
이 문제를 해결하기 위해 request, 줄여서 rq 객체를 만들고 그 객체에게 해체 작업을 맡겨보자.
public class Rq {
String cmd;
String queryString;
String action;
Map<String, String> paramsMap;
Rq(String cmd) {
//삭제?id=23&age=55
paramsMap = new HashMap<>();
this.cmd = cmd;
String[] cmdBits = cmd.split("\\?", 2);
action = cmdBits[0].trim(); //삭제
queryString = cmdBits[1].trim(); //id=23&age=55
String[] queryStringBits = queryString.split("&"); //["id=23","age=55"]
for (int i = 0; i < queryStringBits.length; i++) {
String queryParamStr = queryStringBits[i];
String[] queryParamStrBits = queryParamStr.split("=", 2);
String paramName = queryParamStrBits[0]; //id
String paramValue = queryParamStrBits[1]; //22
paramsMap.put(paramName, paramValue);
}
}
String getAction() {
return action;
}
int getParamAsInt(String paramName, int defaultValue) {
String paramValue = paramsMap.get(paramName);
if(paramValue != null) {
try {
return Integer.parseInt(paramValue);
} catch (NumberFormatException e) { }
}
return defaultValue;
}
}
package com.ll;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class App {
Scanner scanner;
int lastQuotationId;
List<Quotation> quotations;
App() {
scanner = new Scanner(System.in);
lastQuotationId = 0;
quotations = new ArrayList<>();
}
void run() {
System.out.println("== 명언 앱 ==");
while (true) {
System.out.print("명령) ");
String cmd = scanner.nextLine();
Rq rq = new Rq(cmd);
switch(rq.getAction()) {
case "종료" :
return;
case "등록" :
actionWrite();
break;
case "목록" :
actionList();
break;
case "삭제" :
actionRemove(rq);
break;
case "수정" :
actionModify(rq);
break;
}
}
}
void actionWrite() {
System.out.print("명언 : ");
String content = scanner.nextLine();
System.out.print("작가 : ");
String authorName = scanner.nextLine();
lastQuotationId++;
int id = lastQuotationId;
Quotation quotation = new Quotation(id, content, authorName);
quotations.add(quotation);
System.out.printf("%d번 명언이 등록되었습니다.\n", lastQuotationId);
}
void actionList() {
System.out.println("번호 / 작가 / 명언");
System.out.println("----------------------");
if (quotations.isEmpty())
System.out.println("등록된 명언이 없습니다.");
for (int i = quotations.size() - 1; i >= 0; i--) {
Quotation quotation = quotations.get(i);
System.out.printf("%d / %s / %s\n", quotation.id, quotation.author, quotation.content);
}
}
void actionRemove(Rq rq) {
int id = rq.getParamAsInt("id", 0);
if (id == 0) {
System.out.println("id를 정확히 입력해주세요.");
return; // 함수를 끝낸다.
}
System.out.printf("%d번 명언을 삭제합니다.\n", id);
}
void actionModify(Rq rq) {
int id = rq.getParamAsInt("id", 0);
if (id == 0) {
System.out.println("id를 정확히 입력해주세요.");
return; // 함수를 끝낸다.
}
System.out.printf("%d번 명언을 수정합니다.\n", id);
}
}
이제 App.java에서 rq객체를 생성하면 생성자에 의해 cmd가 해체되어 paramsMap(id, age 등)과 action(수정, 삭제 등)이 저장된다.