1. 데이터 식별 번호 부여하기
1.1 데이터식별
- 회원, 프로젝트, 게시글에 대한 고유 번호 생성
- 배열 중간에 인스턴스를 삭제하여도 고유번호 유지
- static feild활용
class Counter {
static int count = 0;
Counter() {
this.count++;
System.out.println(this.count);
}
}
public class Sample {
public static void main(String[] args) {
Counter c1 = new Counter();
Counter c2 = new Counter();
}
}
- 스태틱 필드는 클래스의 고유 필드로 적용
- 따라서 인스턴스 메서드로 선언하는 것이 아닌 클래스 필드를 생성
- 전역변수와 같은 역할을 하게 된다.
1.2 데이터 클래스에 seqNo 적용
- 데이터 클래스에 시퀀스넘버를 생성
- 시퀀스넘버를 접근하는 getter 메서드 생성
- 인스턴스 필드에 스태틱필드값 (시퀀스넘버)를 전달할 메서드 생성
class Object{
//static 필드생성
private static int seqNo;
//인스턴스 필드생성
private int no;
//seqNo getter메서드
public int getSeqNo(){
return ++seqNo;
}
//no getter 및 setter 메서드
public setNo(int no){
this.no = no;
}
public getNo(){
return no;
}
}
- User class
package bitcamp.myapp2.vo;
public class User {
private static int seqNo;
private int no;
//기타 인스턴스 필드 생량//
public static int getSeqNo() {
return ++seqNo;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
//getter setter 생략//
}
}
- Board class. Project class 도 동일하다
- Board class
package bitcamp.myapp2.vo;
public class User {
private static int seqNo;
private int no;
//기타 인스턴스 필드 생량//
public static int getSeqNo() {
return ++seqNo;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
//getter setter 생략//
}
}
- Project class
package bitcamp.myapp2.vo;
public class User {
private static int seqNo;
private int no;
//기타 인스턴스 필드 생량//
public static int getSeqNo() {
return ++seqNo;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
//getter setter 생략//
}
}
1.2 Command 클래스 파일 수정
- addUser()메서드에 setNo()메서드 추가
- listUser()메서드에 for문 출력문에 getNo()메서드 추가
- findByNo()메서드에 userNo탐색 방법 변경
- 유효성검증 방식 변경(viewUser, updateUser, deleteUser)
- 인덱스 리턴 메서드 추가
- deleteUser() for 문 시작인덱스 변경
private static void addUser() {
User user = new User();
user.setNo(User.getSeqNo());
//이하 동일//
}
private static void listUser() {
System.out.println("번호 이름 이메일");
for (int i = 0; i < userLength; i++) {
User user = users[i];
// (i+1) -> user.getNo()로 변경
System.out.printf("%d %s %s\n", user.getNo(), user.getName(), user.getEmail());
}
}
public static User findByNo(int userNo) {
// if (범위) 탐색 -> for 문 탐색
for (int i = 0; i < userLength; i++) {
User user = users[i];
if (user.getNo() == userNo) {
return user;
}
}
return null;
}
//인덱스 리턴 메서드 추가
private static void viewUser() {
int userNo = Prompt.inputInt("회원번호?");
//유효성 검증 -> for문 탐색으로 user인스턴스 리턴
User user = findByNo(userNo);
if (user == null) {
System.out.println("없는 회원입니다.");
return;
}
//이하 동일//
}
public static int indexOf(User user){
for (int i = 0; i < userLength; i++){
if(users[i] == user){
return i;
}
}
return -1;
}
private static void deleteUser() {
int userNo = Prompt.inputInt("회원번호?");
User user = findByNo(userNo);
if (user == null) {
System.out.println("없는 회원입니다.");
return;
}
//해당 인덱스 리턴 메서드
int index = indexOf(user);
//userNo가 아닌 index+1로 시작
for (int i = index + 1; i < userLength; i++) {
users[i - 1] = users[i];
}
users[--userLength] = null;
System.out.println("삭제했습니다.");
}
- 다른 command 클래스도 동일하게 적용
2. High Cohesion 패턴 적용
2.1 GRASP 방법론
- GRASP(General Responsibility Assignment SofeWare Patters)
- 객체지향 설계에서 객체에게 책임을 할당하는 방법론
1. Information Expert (정보 전문가): 특정 작업을 수행하는 데 필요한 정보를 가지고 있는 객체에게 그 작업을 할당
2. Creator (생성자): 객체를 생성할 책임을 특정 객체에게 부여하고 생성자는 생성될 객체와 밀접한 관계가 있는 객체로 설정
3. Controller (컨트롤러): 시스템 이벤트를 처리할 책임을 가지며, 시스템의 주요 제어 흐름을 담당
4. Low Coupling (낮은 결합도): 객체 간의 의존성을 최소화
5. High Cohesion (높은 응집도): 객체가 담당하는 책임을 관련된 것들로 모아 하나의 주제로 결집
6. Polymorphism (다형성): 다형성을 사용하여 동일한 인터페이스를 통해 다양한 객체를 처리
7. Pure Fabrication (순수 가공): 설계 문제를 해결하기 위해 실제 도메인 모델에는 없는 추가적인 클래스를 만들어 사용
8. Indirection (간접화): 두 개체 간의 직접적인 연결을 피하고, 간접적인 연결을 통해 결합도를 낮춤
9. Protected Variations (변화 보호): 변화 가능성이 있는 부분을 캡슐화하여 외부의 영향을 최소화
2.2 High Cohesion(높은 응집도)
- 기존 command class의 구조 : 서브메뉴들의 흐름제어 + 데이터보관처리
- 하나의 객체가 2가지의 역할을 담당하고 있으므로 클래스 분리가 필요하다.
public class ProjectCommand {
//데이터보관 필드
private static final int MAX_SIZE = 10;
private static final Project[] projects = new Project[MAX_SIZE];
private static int projectLength = 0;
//UI처리 메서드
public static void excuteProjectCommand(String command){}
private static void addProject() {}
private static void listProject() {}
private static void viewProject() {}
private static void updateProject() {}
private static void deleteProject() {}
private static void addMembers(Project project) {}
private static void deleteMembers(Project project) {}
//데이터처리 메서드
private static Project findByNo(int projectNo) {}
private static int indexOf(Project project) {}
}
- 위 클래스를 2개의 클래스로 분리
- 데이터보관 및 처리 메서드 // UI처리 메소드
- 이를 통해 로직의 복잡성을 낮추고 유지 보수를 용이하게 한다.
public class ProjectList {
//데이터보관 필드
private static final int MAX_SIZE = 10;
private static final Project[] projects = new Project[MAX_SIZE];
private static int projectLength = 0;
//데이터처리 메서드
private static Project findByNo(int projectNo) {}
private static int indexOf(Project project) {}
}
public class ProjectCommand {
//UI처리 메서드
public static void excuteProjectCommand(String command){}
private static void addProject() {}
private static void listProject() {}
private static void viewProject() {}
private static void updateProject() {}
private static void deleteProject() {}
private static void addMembers(Project project) {}
private static void deleteMembers(Project project) {}
}
2.3 클래스 분리하기
- UserList 클래스 생성
- 유저정보를 저장하는 클래스 필드 생성
- 유저정보들을 저장하는 유저배열 생성 메서드
- 유효한 유저정보를 삭제하는 메서드
- 유효한 유저수만큼 배열 조정하는 메서드
- 유효한 유저 정보를 반환하는 메서드
- 유저 정보 인덱스를 반환하는 메서드
package bitcamp.myapp2.command;
import bitcamp.myapp2.vo.User;
public class UserList {
private static final int MAX_SIZE = 10;
private static final User[] users = new User[MAX_SIZE];
private static int userLength = 0;
public static void add(User user) {
users[userLength++] = user;
}
public static User delete(int userNo) {
User deleteUser = findByNo(userNo);
if (deleteUser == null) {
return null;
}
int index = indexOf(deleteUser);
for (int i = index + 1; i < userLength; i++) {
users[i - 1] = users[i];
}
users[--userLength] = null;
return deleteUser;
}
public static User[] toArray() {
User[] arr = new User[userLength];
for (int i = 0; i < arr.length; i++) {
arr[i] = users[i];
}
return arr;
}
public static User findByNo(int userNo) {
for (int i = 0; i < userLength; i++) {
User user = users[i];
if (user.getNo() == userNo) {
return user;
}
}
return null;
}
public static int indexOf(User user) {
for (int i = 0; i < userLength; i++) {
if (users[i] == user) {
return i;
}
}
return -1;
}
}
- UserCommand 클래스 수정
- 기존 Command 메서드 중 명령 관련 메소드로 구성
- addUser()메서드 추가
- viewUser() for문 호출 방식 변경
- deleteUser() 메서드 변경
package bitcamp.myapp.command;
import bitcamp.myapp.util.Prompt;
import bitcamp.myapp.vo.User;
public class UserCommand {
public static void executeUserCommand(String command) {
System.out.printf("[%s]\n", command);
switch (command) {
case "등록":
addUser();
break;
case "조회":
viewUser();
break;
case "목록":
listUser();
break;
case "변경":
updateUser();
break;
case "삭제":
deleteUser();
break;
}
}
private static void addUser() {
User user = new User();
user.setName(Prompt.input("이름?"));
user.setEmail(Prompt.input("이메일?"));
user.setPassword(Prompt.input("암호?"));
user.setTel(Prompt.input("연락처?"));
user.setNo(User.getNextSeqNo());
UserList.add(user);
}
private static void listUser() {
System.out.println("번호 이름 이메일");
for (User user : UserList.toArray()) {
System.out.printf("%d %s %s\n", user.getNo(), user.getName(), user.getEmail());
}
}
private static void viewUser() {
int userNo = Prompt.inputInt("회원번호?");
User user = UserList.findByNo(userNo);
if (user == null) {
System.out.println("없는 회원입니다.");
return;
}
System.out.printf("이름: %s\n", user.getName());
System.out.printf("이메일: %s\n", user.getEmail());
System.out.printf("연락처: %s\n", user.getTel());
}
private static void updateUser() {
int userNo = Prompt.inputInt("회원번호?");
User user = UserList.findByNo(userNo);
if (user == null) {
System.out.println("없는 회원입니다.");
return;
}
user.setName(Prompt.input("이름(%s)?", user.getName()));
user.setEmail(Prompt.input("이메일(%s)?", user.getEmail()));
user.setPassword(Prompt.input("암호?"));
user.setTel(Prompt.input("연락처(%s)?", user.getTel()));
System.out.println("변경 했습니다.");
}
private static void deleteUser() {
int userNo = Prompt.inputInt("회원번호?");
User deletedUser = UserList.delete(userNo);
if (deletedUser != null) {
System.out.printf("'%s' 회원을 삭제 했습니다.\n", deletedUser.getName());
} else {
System.out.println("없는 회원입니다.");
}
}
}
- 다른 클래스 파일도 동일하게 적용
'개발자 꿈나무의 하루 > 01_Boot Camp' 카테고리의 다른 글
(네이버클라우드 부트캠프) 22일차 - Java프로그래밍 기초(String, Wrapper),실습프로젝트(LinkedList) (0) | 2024.06.25 |
---|---|
(네이버클라우드 부트캠프) 21일차 - Java프로그래밍 기초(Object 클래스) (1) | 2024.06.24 |
(네이버클라우드 부트캠프) 18일차 - 실습프로젝트(게시판CRUD) (0) | 2024.06.19 |
(네이버클라우드 부트캠프) 17일차 - 실습프로젝트(CRUD구현하기) (0) | 2024.06.18 |
(네이버클라우드 부트캠프) 16일차 - Java프로그래밍 기초(클래스) (1) | 2024.06.17 |