연락처 관리 프로그램 ver.2.0
VO(Value Object) 클래스, DAO(Data Access Object) 인터페이스&클래스, 메뉴 인터페이스, 메인클래스로 구성됨.
- 데이터 모델 : name, phone, email
- 기능 : 연락처 등록, 전체검색, 상세검색, 연락처 수정
- UI 구조 :
0.종료 | 1. 등록 | 2.전체검색 | 3.상세검색 | 4.수정
- 업그레이드 내용 : singleton 객체로 데이터 이동. 기능별 클래스 분리 후 멤버변수 private 사용. interface 활용.
public class ContactVO {
//멤버변수
private String name, phone, email;
//생성자
public ContactVO() {}
public ContactVO(String name, String phone, String email) {
this.name = name;
this.phone = phone;
this.email = email;
}
//getter setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
//메소드
@Override
public String toString() {
return "[name=" + name + ", phone=" + phone + ", email=" + email + "]";
}
}
DAO 인터페이스를 작성하고 implements한 클래스에서 인터페이스에서 작성한 메소드를 구현합니다.
DAO클래스의 인스턴스를 계속 생성하지 않고 singleton 인스턴스를 사용해 데이터 흐름을 하나의 객체로 사용합니다.
전체 연락처 정보를 담는 배열을 private로 선언해 클래스안에서만 데이터가 저장되고 반환될 수 있도록 기능을 구현합니다.
public interface ContactDAO {
//등록, 전체검색, 상세검색, 수정 메소드 생성
public abstract int insert(ContactVO vo);
//등록-입력된 인스턴스를 저장하고 저장결과 리턴하기
public abstract ContactVO[] select();
//전체검색-전체리스트를 리턴하기
public abstract ContactVO select(int index);
//상세검색-인덱스를 받아서 인덱스의 정보 리턴하기
public abstract int update(int index, ContactVO vo);
//수정-인덱스를 받아서 입력된 인스턴스 저장하고 저장결과 리턴하기
}
public class ContactDAOImple implements ContactDAO{
//사용할 singleton 객체
private static ContactDAOImple instance=null;
private ContactDAOImple() {};
public static ContactDAOImple getInstance() {
if(instance==null) {
instance=new ContactDAOImple();
}
return instance;
}
//전체 연락처를 담고있는 배열
private static final int MAX=100;
private ContactVO[] list = new ContactVO[MAX];
//배열의 인덱스 정보
private int count=0;
public int getCount() {
return count;
}
@Override //등록-입력된 인스턴스를 저장하고 저장결과 리턴하기
public int insert(ContactVO vo) {
list[count]=vo;
count++;
return 1;
}
@Override //전체검색-전체리스트를 리턴하기
public ContactVO[] select() {
return list;
}
@Override //상세검색-인덱스를 받아서 인덱스의 정보 리턴하기
public ContactVO select(int index) {
return list[index];
}
@Override //수정-인덱스를 받아서 입력된 인스턴스 저장하고 저장결과 리턴하기
public int update(int index, ContactVO vo) {
list[index].setPhone(vo.getPhone());
list[index].setEmail(vo.getEmail());
return 1;
}
}
메뉴에서 사용할 상수를 인터페이스로 만들어두고 사용하겠습니다.
public interface Menu {
public static final int QUIT=0; //종료
public static final int INSERT=1; //등록
public static final int SELECT_ALL=2; //전체검색
public static final int SELECT_BY_INDEX=3; //상세검색
public static final int UPDATE=4; //수정
}
메인클래스에서 UI를 구성합니다. 사용할 Scanner와 DAO 객체를 선언 및 정의하고 DAO 싱글톤 인스턴스를 사용해 데이터를 사용자 화면으로 출력하거나 저장합니다.
public class ContactMain {
//입력받는 Scanner와 싱글톤 인스턴스는 전역변수로 선언
private static Scanner sc;
private static ContactDAO dao;
public static void main(String[] args) {
System.out.println("<<연락처 Version 2.0>>");
//Scanner와 싱글톤 정의
sc = new Scanner(System.in);
dao = ContactDAOImple.getInstance();
//메인메뉴창 - 메뉴 선택. 종료를 누르기 전까지 메뉴 반복
boolean run=true;
while(run) {
showMainMenu();
int choice=sc.nextInt();
sc.nextLine();
switch (choice) {
case Menu.QUIT:
System.out.println(">>프로그램을 종료합니다.");
run=false;
break;
case Menu.INSERT:
ContactInsert();
break;
case Menu.SELECT_ALL:
ContactSelectAll();
break;
case Menu.SELECT_BY_INDEX:
ContactSelectByIndex();
break;
case Menu.UPDATE:
ContactUpdate();
break;
default:
System.out.println(">>다시 선택하세요.");
break;
}
}
}//end main()
private static void showMainMenu() {
System.out.println();
System.out.println("----------------------------------------------");
System.out.println(" 0.종료 | 1.등록 | 2. 전체검색 | 3.상세검색 | 4. 수정");
System.out.println("----------------------------------------------");
System.out.print("선택>");
}//end showMainMenu()
private static void ContactInsert() {
//이름,번호,이메일 입력받아 저장하기
System.out.println();
System.out.println(">>1. 연락처 등록");
System.out.print("이름 입력>");
String name=sc.nextLine();
System.out.print("전화번호 입력>");
String phone=sc.nextLine();
System.out.print("이메일 입력>");
String email=sc.nextLine();
ContactVO vo=new ContactVO(name, phone, email);
int result=dao.insert(vo);
if(result==1) {
System.out.println(">>연락처를 등록했습니다.");
}else {
System.out.println(">>등록에 실패했습니다.");
}
}//end ContactInsert()
private static void ContactSelectAll() {
//반환받은 전체 리스트를 출력하기
int count=((ContactDAOImple)dao).getCount();
ContactVO[] list = dao.select();
System.out.println();
System.out.println(">>2. 전체 연락처 ("+count+")");
for(int i=0;i<count;i++) {
System.out.print(i+"번>>");
System.out.println(list[i]);
}
}//end ContactSelectAll()
private static void ContactSelectByIndex() {
//인덱스 입력받아 해당 인덱스의 정보 출력
System.out.println();
System.out.println(">>3. 연락처 검색");
System.out.print("검색할 연락처 번호 입력>");
int index=sc.nextInt();
sc.nextLine();
int count=((ContactDAOImple)dao).getCount();
if(index>=0 && index<count) {
ContactVO vo=dao.select(index);🔍
System.out.print(index+"번>>");
System.out.println(vo);
}else {
System.out.println(">>없는 연락처입니다.");
}
}//end ContactSelectByIndex()
private static void ContactUpdate() {
//수정할 인덱스와 변경할 전화번호, 이메일을 입력받아서 저장하기
System.out.println();
System.out.println(">>4. 연락처 수정");
System.out.print("수정할 연락처 번호 입력>");
int index=sc.nextInt();
sc.nextLine();
int count=((ContactDAOImple)dao).getCount();
if(index>=0 && index<count) {
System.out.print("수정할 이름 입력>");
String name=sc.nextLine();
System.out.print("수정할 전화번호 입력>");
String phone=sc.nextLine();
System.out.print("수정할 이메일 입력>");
String email=sc.nextLine();
ContactVO vo = new ContactVO();
vo.setPhone(phone);
vo.setEmail(email);
int result=dao.update(index, vo);
if(result==1) {
System.out.println(">>연락처를 수정했습니다.");
}else {
System.out.println(">>수정에 실패했습니다.");
}
}else {
System.out.println(">>없는 연락처입니다.");
}
}//end ContactUpdate()
}//end ContactMain
index를 입력받았으니 바로 index값을 넘겨야겠다! 생각하고 해당 코드를 if문보다 먼저 작성할 경우 0~(count-1) 이외의 값이 입력되면 에러 발생!
=> index에 그 이외의 값도 들어가게 되기 때문입니다. 그래서 index의 값이 정상적인 index의 범위인지 확인한 후(예외처리) 인스턴스를 생성해주세요!