우보천리 개발

객체지향 공부하기 - 다향성 그리고 중복코드 제거해보기 본문

언어/Java

객체지향 공부하기 - 다향성 그리고 중복코드 제거해보기

밥은답 2023. 10. 1. 17:39
반응형

"자바의 정석 P.367를 바탕으로 공부"

 

책의 예제에서 Buyer 클래스와 Product 클래스를 만들어서 Buyer이 물건을 구매하는 코드를 짜보는 예제가 있다.

여기서 더 나아가서 객체지향적인 코드를 공부해보기 위해서 여러가지 시도를 해보았다.

 

우선 예제의 코드다

class Product {
	int price, bonusPoint;
    
    Product(int price) {
    	this.price = price;
        bonusPoint = (int)(bonusPoint / 10.0);
    }
    
    Product() {
    	price = 0;
        bonusPoint = 0;
    }
}
    
    
class Tv extends Product {
	TV() {
    	super(100);
    }
    
    public String toString() {
    	return "TV";
    }
}

 // 다른 물건은 생략
 
 class Buyer {
    int money, bonusPoint;
    ArrayList<Product> items = new ArrayList<>();

    Buyer() {
        this.money = 10000;
        this.bonusPoint = 0;
    }

    void buy(Product p) {
        if (this.money < p.price) {
            System.out.println("Can't buy");
            return;
        }
        this.money -= p.price;
        this.bonusPoint += p.bonusPoint;
        items.add(p);
        System.out.println("Purchased Item : " + p.toString());
    }
    
    void summary() {
        int sum = 0;
        String itemList = "";

        for (int i = 0; i < items.size(); i++) {
            sum += items.get(i).price;
            itemList += items.get(i).toString() + " ";
        }

        System.out.println("Total : " + sum);
        System.out.println("Purchased Items : " + itemList);
    }

    void refund(Product p) {
        if (items.remove(p)) {
            money += p.price;
            bonusPoint -= p.bonusPoint;
            System.out.println("Refunded : " + p.toString());
        }
        else {
            System.out.println("Cannot Refund");
        }
    }
}

 

편의상 다른 Products인 Computer, Audio의 코드는 생략했다.

 

처음에는 각 물건마다 구매(생성)시 고유번호를 부여해서 몇번째 아이템인지 확인하고 싶었다.

예를 들어 컴퓨터를 하나 사면 Computer1, 그리고 Computer2 ... 로 나아가게 하고 싶었다.

 

그래서 우선 각 제품별로 따로 변수를 만들어주면서 개수를 카운팅 하는 방법을 생각했다.

 

그렇게 된다면 각 아이템마다 코드를 이렇게 짰다.

class Tv extends Product {
	static int productNumber = 0;
    int number = 0;
	TV() {
    	super(100);
        productNumber++;
        number = productNumber;
    }
    
    public String toString() {
    	return "TV";
    }
}

 

그렇게 되니 새로운 Product를 추가할때마다 총 4줄의 코드를 더 작성했어야했다. 

그래서 더 나은 방법을 고민하여 공통 코드는 공통 조상인 Product에 넣는 방법을 생각해보았다.

또한 각 제품별로 toString() 메소드가 있었는데 이것 또한 뽑아내고 싶었다.

 

그래서 새로 작성한 Product 클래스는

class Product {
	int price, bonusPoint, itemNum;
    
    Product(int price, int itemNum) {
    	this.price = price;
        bonusPoint = (int)(bonusPoint / 10.0);
        this.itemNum = itemNum;
    }
    
    Product() {
    	price = 0;
        bonusPoint = 0;
    }
}

class Tv extends Product {
	static int tvCount = 1;
	Tv() {
    	super(100, tvCount);
        tvCount++;
    }
    
    // toString() ... 
}

 

Tv를 생성하면 Product 클래스의 생성자를 사용하게 만들면서 동시에 현재 Tv 객체의 개수를 전달하고, tvCount를 증가시켜 다음 객체를 생성할 때 다음 번호로 나오게 했다.

 

다음으로는 toString() 메소드를 Product에 정의했다.

class Product {
	int price, bonusPoint, itemNum;
    String productName;
    
    Product(int price, int itemNum, String productName) {
    	this.price = price;
        bonusPoint = (int)(bonusPoint / 10.0);
        this.itemNum = itemNum;
        this.productName = productName;
    }
    
    Product() {
    	price = 0;
        bonusPoint = 0;
    }
    
    public String toString() {
    	return productName + itemNum;
    }
}

 

Tv, Computer 등 새로운 품목을 생성할 때마다 제품의 이름도 넘겨주었다. 또한 toString()을 Product에 정의하면서 호출 될 때마다 동적으로 해당되는 품목의 이름과 개수를 출력하도록 작성하였다.

 

그렇게 Tv, Audio, Computer 등에서는 공통적인 코드는 최대한 뽑아내고 단순하게 만들어보았다.

 

Buyer 클래스에서는 buy 메소드를 오버로딩하여 하나의 제품을 사는 경우와 여러개를 한번에 살 수 있게 만들었다.

void buy(Product p) {
        if (this.money < p.price) {
            System.out.println("Can't buy");
            return;
        }
        this.money -= p.price;
        this.bonusPoint += p.bonusPoint;
        items.add(p);
        System.out.println("Purchased Item : " + p.toString());
    }

    void buy(Product...products) {
        int totalCost = 0;
        int totalBonusPoints = 0;

        for (Product p : products) {
            if (this.money < p.price) {
                System.out.println("Cant Buy " + p.toString());
                continue;
            }
            totalCost += p.price;
            totalBonusPoints += p.bonusPoint;
            items.add(p);
            System.out.println("Purchased Item : " + p.toString());
        }

        this.money -= totalCost;
        this.bonusPoint += totalBonusPoints;
    }
}

 

* 전체 코드 *

package chapter7;

import java.util.ArrayList;

class Product {
    int price, bonusPoint;
    int itemNum;
    String productName;

    Product(int price, int itemNum, String productName) {
        this.price = price;
        bonusPoint = (int) (price / 10.0);
        this.itemNum = itemNum;
        this.productName = productName;
    }

    Product() {
        this(0,0,"Undefined");
    }

    public String toString() {
        return productName + itemNum;
    }
}

class Tv extends Product {
    static int tvCounts = 1;
    Tv() {
        super(100, tvCounts, "Tv");
        tvCounts++;
    }
}

class Computer extends Product {
    static int computerCounts = 1;
    Computer() {
        super(300, computerCounts, "Computer");
        computerCounts++;
    }

/*    @Override
    public String toString() {
        return "Computer is Special!!";
    }*/
}

class Audio extends Product {
    static int audioCounts = 1;
    Audio() {
        super(50, audioCounts, "Audio");
        audioCounts++;
    }
}

class Buyer {
    int money, bonusPoint;
    ArrayList<Product> items = new ArrayList<>();

    Buyer() {
        this.money = 10000;
        this.bonusPoint = 0;
    }

    void buy(Product p) {
        if (this.money < p.price) {
            System.out.println("Can't buy");
            return;
        }
        this.money -= p.price;
        this.bonusPoint += p.bonusPoint;
        items.add(p);
        System.out.println("Purchased Item : " + p.toString());
    }

    void buy(Product...products) {
        int totalCost = 0;
        int totalBonusPoints = 0;

        for (Product p : products) {
            if (this.money < p.price) {
                System.out.println("Cant Buy " + p.toString());
                continue;
            }
            totalCost += p.price;
            totalBonusPoints += p.bonusPoint;
            items.add(p);
            System.out.println("Purchased Item : " + p.toString());
        }

        this.money -= totalCost;
        this.bonusPoint += totalBonusPoints;
    }

    void showItemCounts() {
        int total = Computer.computerCounts + Audio.audioCounts + Tv.tvCounts;
        System.out.println("Total Bought : " + total);
        System.out.println("Computer.computerCounts = " + Computer.computerCounts);
        System.out.println("Audio.audioCounts = " + Audio.audioCounts);
        System.out.println("Tv.tvCounts = " + Tv.tvCounts);
    }

    void summary() {
        int sum = 0;
        String itemList = "";

        for (int i = 0; i < items.size(); i++) {
            sum += items.get(i).price;
            itemList += items.get(i).toString() + " ";
        }

        System.out.println("Total : " + sum);
        System.out.println("Purchased Items : " + itemList);
    }

    void refund(Product p) {
        if (items.remove(p)) {
            money += p.price;
            bonusPoint -= p.bonusPoint;
            System.out.println("Refunded : " + p.toString());
        }
        else {
            System.out.println("Cannot Refund");
        }
    }
}

public class PolyArgumentTest {
    public static void main(String[] args) {
        Buyer b = new Buyer();

        Computer c1 = new Computer();
        Computer c2 = new Computer();

        Audio a1 = new Audio();

        Tv t1 = new Tv();
        Tv t2 = new Tv();
        Tv t3 = new Tv();

        b.buy(c1,c2,a1,t1,t2);
        b.buy(t3);

        b.refund(t2);

        System.out.println("Balance : " + b.money);
        System.out.println("BonusPoint : " + b.bonusPoint);
        b.summary();
        System.out.println();
        b.showItemCounts();
    }
}

 

// 결과

Purchased Item : Computer1
Purchased Item : Computer2
Purchased Item : Audio1
Purchased Item : Tv1
Purchased Item : Tv2
Purchased Item : Tv3
Refunded : Tv2
Balance : 9150
BonusPoint : 85
Total : 850
Purchased Items : Computer1 Computer2 Audio1 Tv1 Tv3 

Total Bought : 9
Computer.computerCounts = 3
Audio.audioCounts = 2
Tv.tvCounts = 4

Process finished with exit code 0
반응형

'언어 > Java' 카테고리의 다른 글

자바 객체 비교, Comparable 그리고 Comparator  (0) 2023.08.11
Comments