Framework

결합도(Coupling)가 높은 프로그램

유호야 2020. 12. 13. 11:19
반응형

결합도란 하나의 클래스가 다른 클래스와 얼마나 많이 연결되어 있는지를 나타내는 표현이며, 결합도가 높은 프로그램은 유지보수가 어렵다. 이 결합도와 유지보수 관계를 이해하기 위한 간단한 실습을 진행해보자.

 

package spring.book.practice;

public class SamsungTV {
	
	public void powerOn() {
		System.out.println("SamsungTV --- 전원을 킨다.");
	}
	
	public void powerOff() {
		System.out.println("SamsungTV --- 전원을 끈다.");
	}
	
	public void volumeUp() {
		System.out.println("SamsungTV --- 음량을 올린다.");
	}
	
	public void volumeDown() {
		System.out.println("SamsungTV --- 음량을 내린다.");
	}
}

 

package spring.book.practice;

public class LgTV {
	
	public void turnOn() {
		System.out.println("LgTV  --- 전원을 킨다.");
	}
	
	public void turnOff() {
		System.out.println("LgTV  --- 전원을 끈다.");
	}
	
	public void soundUp() {
		System.out.println("LgTV --- 음량을 올린다.");
	}
	
	public void soundDown() {
		System.out.println("LgTV --- 음량을 내린다.");
	}
}

 

package spring.book.practice;

public class TVUser {

	public static void main(String[] args) {
		
		SamsungTV tv = new SamsungTV();
		tv.powerOn();
		tv.powerOff();
		tv.volumeUp();
		tv.volumeDown();

	}

}

결과

package spring.book.practice;

public class TVUser {

	public static void main(String[] args) {
		
		LgTV tv = new LgTV();
		tv.turnOn(); 
		tv.turnOff(); 
		tv.soundUp();
		tv.soundDown();

	}

}

결과

 

SaumsungTV > LgTV 로 교체하기 위해서는 대부분의 코드를 변경해야 하는 번거로움이 있다.

- 다형성 이용하기

결합도를 낮추기 위해서 다양한 방법을 사용할 수 있겠지만, 가장 쉽게 생각할 수 있는 것이 객체지향 언어의 핵심 개념인 다형성(Polymorphism)을 이용하는 것이다. 앞에서 작성한 프로그램을 다형성을 이용하여 수정해보자. 다형성을 이용하려면 상속과 메소드 재정의(Overriding), 그리고 형변환이 필요하며, 자바 같은 객체지향 언어는 이를 문법으로 지원한다.

TVUser와 TV 클래스의 관계

 

TV 클래스들의 최상위 부모로 사용할 TV 인터페이스를 추가하고, 모든 TV가 공통으로 가져야 할 메소들을 추상메소드로 선언한다.

package spring.book.practice;

public interface TV {
	public void powerOn();
	public void powerOff();
	public void volumeUp();
	public void volumeDown();
}

이제 SamsungTV와 LgTV 클래스를 수정하여 방금 추가한 TV 인터페이스를 구현하도록 한다.

package spring.book.practice;

public class TVUser {

	public static void main(String[] args) {
		
	TV tv = new SamsungTV();
	tv.powerOff();
	tv.powerOff();
	tv.volumeUp();
	tv.volumeDown();

	}

}

결과

package spring.book.practice;

public class TVUser {

	public static void main(String[] args) {
		
	TV tv = new LgTV();
	tv.powerOff();
	tv.powerOff();
	tv.volumeUp();
	tv.volumeDown();

	}
	
}

TVUser클래스는 TV인터페이스 타입의 변수로 SamsungTV 객체를 참조하고 있다. 이렇게 묵시적 형변환(Promotion)을 이용하여 객체를 참조하면 SamsungTV를 LgTV 객체로 변경할 때, 참조하는 객체만 변경하면 되므로 객체를 쉽게 교체할 수 있다. 이렇게 다형성을 이용하면 TVUser와 같은 클라이언트 프로그램이 여러 개 있더라도 최소한의 수정으로 TV를 교체할 수 있다. 따라서 유지보수는 좀 더 편해졌다고 볼 수 있다.

 

- 디자인 패턴 이용하기

결합도를 낮추기 위한 또 다른 방법으로 디자인 패턴을 이용하는 방법이 있다. 앞에서 살펴본 다형성을 이용하는 방법은 메소드를 호출할 때 인터페이스를 이용함으로써 좀 더 쉽게 TV를 교체할 수 있었다. 하지만 이 방법 역시 TV를 변경하고자 할 때, TV 클래스 객체를 생성하는 소스를 수정해야만 한다.

TV를 교체할 때, 클라이언트 소스를 수정하지 않고 TV를 교체할 수만 있다면 유지보수는 더욱 편리해질 것이다. 이를 위해서 Factory 패턴을 적용해야 하는데, Factory 패턴은 클라이언트에서 사용할 객체 생성을 캡슐화하여 TVUser와 TV사이를 느슨한 결합 상태로 만들어준다. 다음과 같이 Factory 패턴이 적용된 BeanFactory 클래스를 추가한다. 

package spring.book.practice;

public class BeanFactory {
	public Object getBean(String beanName) {
		if(beanName.equals("samsung")) {
			return new SamsungTV();
		} else if(beanName.equals("lg")) {
			return new LgTV();
		}
		return null;
	}
}

BeanFactory 클래스의 getBean() 메소드는 매개변수로 받은 beanName에 해당하는 객체를 생성하여 리턴한다. 이제 이 BeanFactory 클래스를 이용하여 사용할 TV 객체를 획득하도록 TVUser 클래스를 수정한다.

package spring.book.practice;

public class TVUser {

	public static void main(String[] args) {
		BeanFactory factory = new BeanFactory();
		TV tv = (TV)factory.getBean(args[0]);
		
		tv.powerOff();
		tv.powerOff();
		tv.volumeUp();
		tv.volumeDown();

	}
	
}

 

 

 

반응형