<aside> 💁‍♂️ 이번 장에서는 결합도에 대해 알아봅니다.

결합도란, **‘모듈 사이의 의존도를 나타내는 지표’**라고 할 수 있습니다. 여기서 ‘모듈’은 클래스를 나타낸다고 할 때, 이는 곧 **‘클래스 사이의 의존도를 나타내는 지표’**라고 볼 수 있습니다.

어떤 클래스가 다른 클래스에 많이 의존하고 있는 구조를 강한 결합(tightly coupling), 결합도가 낮은 구조는 **느슨한 결합(loosecoupling)**이라고 부릅니다.

강한 결합 코드는 이해하기도 힘들고, 변경하기도 굉장히 힘듭니다. 반면 느슨한 결합 구조로 개선하면 코드 변경이 쉬워집니다.

이번 장에서는 어떻게 느슨한 결합 구조를 만들 수 있는지 알아봅니다.

</aside>

강한 결합 문제를 해결하려면, 책무에 대한 접근 방법을 빼놓을 수 없습니다.

소프트웨어 설계에서 ‘책무’란, **‘어떤 관심사를 정상적으로 작동하게 제어해야 하는 책임’**으로 생각할 수 있습니다.

책무를 제대로 생각하지 않으면, 결합도가 높아지기 쉽습니다.

#8-1. 결합도와 책무

책무를 생각하지 않으면 발생하는 문제에 대해 알아보도록 합시다.

온라인 쇼핑몰에 일반 할인 서비스를 추가하는 예시를 들어보겠습니다.

[code 8-1] 상품 할인과 관련된 클래스

class DiscountManager {
	List<Product> discountProducts;
	int totalPrice;

	boolean add(Product product, ProductDiscount discount) {
		if(product.id < 0) {
			throw new IllegalArgumentException();
		}
		if (product.name.isEmpty()) {
			throw new IlleIllegalArgumentException();
		}
		if (product.price < 0) {
			throw new IllegalArgumentException();
		}
		if(product.id = discount.id) {
			throw new IllegalArgumentException();
		}

		int discountPrice = getDiscountPrice(product.price);
		
		int tmp;
		if (discount.canDiscount) {
			tmp = totalPrice + discountPrice;
		} else {
			tmp = totalPrice + product.price;
		}
		if (tmp <= 200000) {
			totalPrice = tmp;
			discountProducts.add(product);
			return true;
		} else {
			return false;
		}
	}

	static int getDiscountPrice(int price) {
		int discountPrice = price - 3000;
		if (discountPrice < 0) {
			discountPrice = 0;
		}
		
		return discountPrice;
	}
}

class Product {
	int id;
	String name;
	int price;
}

class ProductDiscount {
	int id;
	boolean canDiscount;
}