본문 바로가기
교육/Java&Spring

kosta 클라우드 네이티브 애플리케이션 개발 과정 day 11

by Renechoi 2023. 1. 3.

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 구현 

 

https://github.com/renechoi/Cloud_Native_Application_Java_Course/tree/main/workspace/JavaWork/practiceJava/src/main/java/kosta/mission2/Mission2_10/bank

 

GitHub - renechoi/Cloud_Native_Application_Java_Course

Contribute to renechoi/Cloud_Native_Application_Java_Course development by creating an account on GitHub.

github.com

 

 

 

쟁점사항 : 

 

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를 계속해서 넘겨주는 방식이 맞는 것인가에 대한 의문이 생긴다. 

 

 

반응형