부트캠프/코트스테이츠 백엔드 코스

회고 13일차

태태코 2023. 3. 2. 17:36
반응형

객체지향의 가장 중요한 원리인 추상화 다형성 상속 캡슐화에 대해 모두배우고 이 원리를 모두 적용해 간단한 프로그램을 제작했다.

여기서 깨달은 아주 중요한 원칙 3가지를 확인하면서 설명하겠다.

 

1. 한 클래스는 하나의 역할만 하게 끔 설계한다.

ex) 장바구니 클래스는 주문의 역할을 맞게 할 필요가없다.

 

2. 한 클래스가 다른 클래스와 관계를 맺고 있을 때 그 다른 클래스의 직접적인 정보에 대해 알게 할 필요가 없다.

ex) 자동차와 바퀴가 연관을 맺을 때 바퀴가 현대 바퀴인지 기아 바퀴인지 자동차 클래스가 알게끔 하면 안된다.

 

3. 공통적인 특성이나 속성을 모아 추상 클래스나 인터페이스로 모아 구현, 상속받게 한다.

ex) 현대 자동차, 기아 자동차등 속성이 비슷한 상황이라면 중복코드를 줄이기 위해 위와 같은 방법을 실행한다.

 

 

1. 

위와 같이 메뉴의 역할을 하는 클래스에게 주문의 역할을 맞게 해서는 안된다는 것이다.

 

package com.codestates.seb.kiosk_program;

import com.codestates.seb.kiosk_program.product.*;

public class Menu {

    Product[] products;

    public Menu(Product[] products) {
        this.products = products;
    }

    public void printMenu(){
        System.out.println("[안내]원하시는 메뉴의 번호를 입력하여 주세요.\n");
        printKimbab(true);
        printDduckbooki(true);
        printDrinks(true);
    }
    protected void printDrinks(boolean printPrice) {
        System.out.println("🥤 음료");
        for(Product product:products){
            if(product instanceof Drink){
                printEachMenu(product,printPrice);
            }
        }
        System.out.println();
    }

    protected void printDduckbooki(boolean printPrice) {
        System.out.println("🍛 떡볶이");
        for(Product product:products){
            if(product instanceof Dduckbockki){
                printEachMenu(product,printPrice);
            }
        }
        System.out.println();
    }

    protected void printKimbab(boolean printPrice) {
        System.out.println("🍙 김밥");
        for(Product product:products){
            if(product instanceof Kimbab){
                printEachMenu(product,printPrice);
            }
        }
        System.out.println();
    }
    private static void printEachMenu(Product product,boolean printPrice) {
         System.out.printf("   (%d) %s  %5d원\n",product.getId(),product.getName(),product.getPrice());
    }
}

 

2.

@Override
public int  apliycalculation(int price) {
    return discountPolicy.calculateDiscountedPrice(price);
}

위의 코드와 아래의 코드의 차이는 이 클래스 즉 이 메서드 안에서

의 존재를 알 고 있느냐 모르고 있느냐 그 차이인 것이다. 위의 코드는 FixedAmountDiscountPolicy라는 직접적인 클래스의 정보를 코드가 모르고 있는 것이고, 밑에 코드는 안다는 것이다. 

만약 할인 정책이 바뀌었을 때 위에 코드는 수정할 필요가 없지만 아래 코드는 수정해야한다. 

@Override
public int  apliycalculation(int price) {
    return FiexedAmountDiscountPolicy.calculateDiscountedPrice(price);
}

 

 

3. 위의 코드로도 설명할 수 있지만

package com.codestates.seb.kiosk_program.discount.discountpolicy;


public class FiexedAmountDiscountPolicy implements DiscountPolicy {
    private int discountAmount;

    public FiexedAmountDiscountPolicy(int discountAmount) {
        this.discountAmount = discountAmount;
    }
    public int calculateDiscountedPrice(int price){
        return price - discountAmount;
    }
}
package com.codestates.seb.kiosk_program.discount;


import com.codestates.seb.kiosk_program.discount.discountcondtion.DiscountCondition;

public class Discount {
    private DiscountCondition[] discountConditions;

    public Discount(DiscountCondition[] discountConditions) {
        this.discountConditions = discountConditions;
    }

    public int discount(int price){
        int discountPrice = price;
        for(DiscountCondition discountCondition: discountConditions){
            discountCondition.check();
            if(discountCondition.isSatisfied())discountPrice=discountCondition.apliycalculation(discountPrice);
        }
        return discountPrice;
    }
}

이 둘 할인 정책 클래스는 속성도 비슷하고 메서드도 비슷하다 . 따로따로 작성할 경우에는 중복된 코드가 많을 뿐더러 2번을 만족시킬 수 없기 때문에 공통된 속성을 묶어서 인터페이스나 추상 클래스를 만들어 주는 것이다.

package com.codestates.seb.kiosk_program.discount.discountpolicy;

public interface DiscountPolicy {
    public int calculateDiscountedPrice(int price);

}

이렇게 되면 2번을 만족하게 되고, 코드의 중복도 막을 수 있다는 장점이있다.

이런 기본적인 원칙을 가지고 계속 객체 지향 코드를 짜본다면 실력또한 금방 늘 것이라고 기대하는 바이다.

반응형

'부트캠프 > 코트스테이츠 백엔드 코스' 카테고리의 다른 글

회고 15일차  (0) 2023.03.07
회고 14일  (0) 2023.03.06
회고 12일차  (0) 2023.03.01
회고 11일차  (0) 2023.02.27
회고 10일차  (0) 2023.02.24