kosta 클라우드 네이티브 애플리케이션 개발 과정 day 11
객체가 또 다른 객체를 필요로 할때 혹은 포함할 때
=> 객체간의 관계
class Video{}
class GeneralMember{
....
Video rentalVideo;
}
멤버가 있고 비디오가 있을 때
멤버가 비디오를 객체의 필드로 갖는다.
멤버가 복수의 비디오를 빌리는 코드로 리팩토링하기
리스트를 사용하면 편하지만 일단은 배열을 사용한다.
private Video videoRented;
private final Video[] videosRented = new Video[10];
private int rentedCounts = 0;
public void showAll() {
System.out.println(
String.format("""
회원의 아이디: %s
회원의 이름: %s
회원의 주소: %s
%s
""",
id, name, address, "-".repeat(15))
+ getAllVideos()
+ "-".repeat(30)
);
}
private String getAllVideos(){
return Arrays.stream(this.getVideosRented())
.filter(Objects::nonNull)
.map(Video::getInfo)
.toList()
.toString()
.replaceAll("[,\\[\\]]", "")
;
}
메인 메서드
package kosta.mission2.Mission2_08.solution;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Video video1 = new Video("1", "탑건2", "톰크루즈");
Video video2 = new Video("2", "아바타2", "who?");
Video video3 = new Video("3", "해리포터", "헤르미온느");
GeneralMember generalMember = new GeneralMember("a", "홍길동", "가산");
generalMember.rentalVideo(video1);
generalMember.showEach();
generalMember.rentalVideos(video1, video2, video3);
Arrays.stream(generalMember.getVideosRented())
.filter(Objects::nonNull)
.map(Video::getInfo)
.forEach(System.out::println);
generalMember.showAll();
}
}
비디오 클래스
package kosta.mission2.Mission2_08.solution;
public class Video {
private String videoNo;
private String title;
private String actor;
public Video() {
}
public Video(String videoNo, String title, String actor) {
this.videoNo = videoNo;
this.title = title;
this.actor = actor;
}
public String getInfo() {
return String.format(
"""
회원이 대여한 비디오: %s
회원이 대여한 비디오 제목: %s
회원이 대여한 비디오 주인공: %s
""",
videoNo, title, actor);
}
public void show() {
System.out.println(String.format(
"""
회원이 대여한 비디오: %s
회원이 대여한 비디오 제목: %s
회원이 대여한 비디오 주인공: %s
""",
videoNo, title, actor));
}
public String getVideoNo() {
return videoNo;
}
public void setVideoNo(String videoNo) {
this.videoNo = videoNo;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getActor() {
return actor;
}
public void setActor(String actor) {
this.actor = actor;
}
}
멤버 클래스
package kosta.mission2.Mission2_08.solution;
import java.util.Arrays;
import java.util.Objects;
public class GeneralMember {
private String id;
private String name;
private String address;
private Video videoRented;
private final Video[] videosRented = new Video[10];
private int rentedCounts = 0;
public GeneralMember() {
}
public GeneralMember(String id, String name, String address) {
this.id = id;
this.name = name;
this.address = address;
}
public void rentalVideo(Video videoRented) {
this.videoRented = videoRented;
rentedCounts++;
}
public void rentalVideos(Video... videoRented) {
for (Video video : videoRented) {
this.videosRented[rentedCounts++] = video;
}
}
public Video[] getVideosRented() {
return videosRented;
}
public void showEach() {
System.out.println(
String.format("""
회원의 아이디: %s
회원의 이름: %s
회원의 주소: %s
""",
id, name, address)
+ videoRented.getInfo()
+ "-".repeat(30)
);
}
public void showAll() {
System.out.println(
String.format("""
회원의 아이디: %s
회원의 이름: %s
회원의 주소: %s
%s
""",
id, name, address, "-".repeat(15))
+ getAllVideos()
+ "-".repeat(30)
);
}
private String getAllVideos(){
return Arrays.stream(this.getVideosRented())
.filter(Objects::nonNull)
.map(Video::getInfo)
.toList()
.toString()
.replaceAll("[,\\[\\]]", "")
;
}
}
팩토리 메서드 및 상속으로 구현한 코드
package kosta.mission2.Mission2_08;
public class Video {
private static int videoNo = 0;
private String title;
private Actor actor;
private String type;
public Video(String title, Actor actor) {
this(title, actor, "video");
}
private Video(String title, Actor actor, String type) {
this.title = title;
this.actor = actor;
this.type = type;
Video.videoNo++;
}
public static Video valueOf(String title, Actor actor, String type) {
return switch (type.toLowerCase()) {
case "drama" -> new Drama(title, actor, type);
case "movie" -> new Movie(title, actor, type);
default -> new Video(title, actor);
};
}
public int getVideoNo() {
return videoNo;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Actor getActor() {
return actor;
}
public void setActor(Actor actor) {
this.actor = actor;
}
@Override
public String toString() {
return String.format("""
title : %s
actor : %s
""",
title, actor.getName());
}
}
class Drama extends Video {
private String type;
public Drama(String title, Actor actor, String type) {
super(title, actor);
this.type = type;
System.out.printf("this is %s\n", type);
}
@Override
public String toString() {
return super.toString() + String.format("""
type : %s
""",type);
}
}
class Movie extends Video {
private String type;
public Movie(String title, Actor actor, String type) {
super(title, actor);
this.type = type;
System.out.printf("this is %s\n", type);
}
@Override
public String toString() {
return super.toString() + String.format("""
type : %s
""",type);
}
}
order practice를 구현해보자
Member : 이름, 주소
Item : 모델명, 가격
Order : 회원내역, 제품내역, 수량, 주문금액
결과 ->
회원이름 : 홍길동
회원주소 : 가산
주문한 상품 모델명 : 갤럭시 23
주문한 상품 가격 : 100원
주문 수량 : 10개
주문 금액 : 1000원
멤버 객체
package kosta.mission2.Mission2_09.order;
public class Member {
private String name;
private String address;
private Item item;
private int orderCounts;
private double orderPrice;
public Member(String name, String address) {
this.name = name;
this.address = address;
}
public void order(Item item, int orderCounts, double orderPrice){
this.item = item;
this.orderCounts = orderCounts;
this.orderPrice = orderPrice;
}
public void show(){
System.out.println(
String.format("""
회원이름 : %s
회원주소 : %s
주문항 상품 : %s
주문한 상품 가격 : %f
주문 수량 : %s
주문 금액 : %s
""", name, address, item.getModelName(), item.getPrice(), orderCounts, orderPrice)
);
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
public Item getItem() {
return item;
}
public int getOrderCounts() {
return orderCounts;
}
public double getOrderPrice() {
return orderPrice;
}
}
item 객체
package kosta.mission2.Mission2_09.order;
public class Item {
private String modelName;
private double price;
public Item(String modelName, double price) {
this.modelName = modelName;
this.price = price;
}
public String getModelName() {
return modelName;
}
public double getPrice() {
return price;
}
}
order 객체
package kosta.mission2.Mission2_09.order;
public class Order {
private Member member;
private Item item;
private String orderNo;
private int amount;
private double totalPrice;
public Order(Member member, Item item, String orderNo, int amount) {
this.member = member;
this.item = item;
this.orderNo = orderNo;
this.amount = amount;
this.totalPrice = amount * item.getPrice();
}
public void show(){
System.out.println(
String.format("""
회원이름 : %s
회원주소 : %s
주문항 상품 : %s
주문한 상품 가격 : %f
주문 수량 : %s
주문 금액 : %s
""", member.getName(), member.getAddress(), item.getModelName(), item.getPrice(),
amount, totalPrice)
);
}
}
main 객체
package kosta.mission2.Mission2_09.order;
public class Main {
public static void main(String[] args) {
Item galaxy23 = new Item("갤럭시23", 100);
Member member = new Member("홍길동", "가산");
member.order(galaxy23, 10, 1000);
member.show();
Order order = new Order(member, galaxy23, "1", 1000);
order.show();
}
}
for문을 이용하지 않고 api를 이용해서 array를 카피해보자.
System.arraycopy(oldCustomers, 0, newCustomers, 0, customersNum);
bank CRUD 구현
쟁점사항 :
bank 클래스에서 add Customer 메서드를 통해 Customer 객체를 생성할 때
customers 필드 배열에 바로 new를 통해 생성한다.
이때 customer 클래스에서 생성자를 호출하며 직접 user의 input을 받는다.
package kosta.mission2.Mission2_10.bank.customer;
import kosta.mission2.Mission2_10.bank.bank.Bank;
import kosta.mission2.Mission2_10.bank.ui.InputView;
import kosta.mission2.Mission2_10.bank.ui.OutputView;
import java.util.Objects;
public class Customer {
private final String id;
private final String name;
private final Account account;
public Customer() {
this.id = requestId();
this.name = requestName();
this.account = new Account(id, requestAmount());
OutputView.consolePrint(OutputView.ADD_ACCOUNT_SUCCESS);
}
private String requestId() {
return validate(InputView.getId());
}
private String requestName() {
return validate(InputView.getName());
}
private Long requestAmount() {
return validate(InputView.getBalance());
}
private Long validate(Long userInput) {
if (userInput < 0) {
try {
throw new InvalidCustomerInputException(InvalidCustomerInputException.INVALID_NUMBER_UNDER_ZERO);
} catch (InvalidCustomerInputException ignored) {
}
}
return userInput;
}
private String validate(String userInput) {
try {
validateNullOrEmpty(userInput);
validateProperWord(userInput);
} catch (InvalidCustomerInputException ignored) {
}
return userInput;
}
private void validateNullOrEmpty(String userInput) throws InvalidCustomerInputException {
if (Objects.isNull(userInput) || userInput.isEmpty()) {
throw new InvalidCustomerInputException(InvalidCustomerInputException.NULL_OR_EMPTY_EXCEPTION);
}
}
private void validateProperWord(String userInput) throws InvalidCustomerInputException {
if (!userInput.matches("[a-zA-z\\u3131-\\u314e|\\u314f-\\u3163|\\uac00-\\ud7a3]*")) {
throw new InvalidCustomerInputException(InvalidCustomerInputException.INVALID_WORD_EXCEPTION);
}
}
public String getId() {
return id;
}
public Object getName() {
return null;
}
public Account getAccount() {
return account;
}
@Override
public String toString() {
return String.format("""
Customer Number: %d
id: %s
name: %s
account id: %s
account balance: %s
%s
""", Bank.getCustomerNumber(), id, name,
account.getId(), account.getBalance(), "-".repeat(20));
}
}
validation을 검증할 때 발생하는 에러를 해당 객체까지 throw 하고 try를 통해 잡아준다.
하지만 이와 같이 exception을 도중에 끊어버리면 다시 입력을 받는 로직을 구현하지 못한다.
따라서 throw를 통해 do while 문의 시작점까지 exception을 던져줘야 하고 이를 받아야 한다.
연속 throw로 던져주는 방식
하지만 이렇게 throw를 계속해서 넘겨주는 방식이 맞는 것인가에 대한 의문이 생긴다.
'교육 > Java&Spring' 카테고리의 다른 글
kosta 클라우드 네이티브 애플리케이션 개발 과정 day 13 (0) | 2023.01.05 |
---|---|
kosta 클라우드 네이티브 애플리케이션 개발 과정 day 12 (0) | 2023.01.04 |
kosta 클라우드 네이티브 애플리케이션 개발 과정 day 10 (0) | 2023.01.02 |
java & spring 2 (1) | 2022.12.31 |
kosta 클라우드 네이티브 애플리케이션 개발 과정 day 9 (0) | 2022.12.30 |