티스토리 뷰

카테고리 없음

상속, 의존관계

무한경쟁시대 2021. 11. 14. 12:35

아래와 같이 쓰더라도 정상작동을 한다.

그런데, Car클래스의 생성자 부분(new ToyotaEngine();)을 바꾸면 그 안에 drive()메서드까지 바꿔줘야하는 등 유지 보수측면에서 시간을 많이 쓰게 된다.

따라서, 유지보수할 때 시간을 줄여줄 수 있는 방법을 생각해야한다. (객체 의존성 느슨, 결합도 낮게)

package com.example.car;

//객체간의 관계 두가지
//1) 상속관계(A is a B) A는 B다. A는 B를 상속받았다.
//2) 포함관계(A has a B) A는 B를 가진다.

class HyundayEngine{
	public void begin() {
		System.out.println("현대엔진이 동작: 부릉부릉~");
	}
}
class ToyotaEngine{
	public void start() {
		System.out.println("도요타 엔진이 동작: 부릉부릉~");
	}
	
}
class FordEngine{
	public void beginFord() {
		System.out.println("포드 엔진이 동작: 부릉부릉~");
	}
}

public class Car {
	private ToyotaEngine toyotaEngine = new ToyotaEngine();
	
	public void drive() {
		toyotaEngine.start();
	}
	public static void main(String[] args) {
		Car car = new Car();
		car.drive();
	}
}

 


그 다음 발전된 단계로 인터페이스를 써보기.

아래와 같이 쓰면 Car 클래스에서 메서드를 따로따로 바꿀 필요없다.

그러나, 인터페이스 변수(engine)에 객체 담아야하는데 이게 Car 클래스 안에서 이뤄지므로 마치 차를 만들 때 엔진이 내부에서 생성되는 느낌이 되는 것이다. 현실에서는 차를 만들고 엔진을 넣는방식으로 하는게 시간절약과 정확도를 높일 수 있기에 외부에서 생성되도록 코드를 만들 필요가 있다.

package com.example.car;

//객체간의 관계 두가지
//1) 상속관계(A is a B) A는 B다. A는 B를 상속받았다.
//2) 포함관계(A has a B) A는 B를 가진다.

class HyundayEngine implements Engine{
	@Override
	public void start() {
		System.out.println("현대엔진이 동작: 부릉부릉~");
	}
}
class ToyotaEngine implements Engine{
	@Override
	public void start() {
		System.out.println("도요타 엔진이 동작: 부릉부릉~");
	}
	
}
class FordEngine implements Engine{
	@Override
	public void start() {
		System.out.println("포드 엔진이 동작: 부릉부릉~");
	}
}

interface Engine{
	void start();
}

class Car{
	private Engine engine = new ToyotaEngine();//업캐스팅(부모타입에 의존한다)
	
	public void drive() {
		engine.start();
	}
}

public class Run {

	public static void main(String[] args) {
		Car car = new Car();
		car.drive();
	}
}

이렇게 하면 Car클래스 개발자는 자기가 사용하는 의존객체가 변경된다하더라도 전혀 영향을 안받는다.

package com.example.car;

//객체간의 관계 두가지
//1) 상속관계(A is a B) A는 B다. A는 B를 상속받았다.
//2) 포함관계(A has a B) A는 B를 가진다.

class HyundaiEngine implements Engine{
	@Override
	public void start() {
		System.out.println("현대엔진이 동작: 부릉부릉~");
	}
}
class ToyotaEngine implements Engine{
	@Override
	public void start() {
		System.out.println("도요타 엔진이 동작: 부릉부릉~");
	}
	
}
class FordEngine implements Engine{
	@Override
	public void start() {
		System.out.println("포드 엔진이 동작: 부릉부릉~");
	}
}

interface Engine{
	void start();
}

class Car{
	private Engine engine;//업캐스팅(부모타입에 의존한다)
	
	public Car(Engine engine) {
		super();
		this.engine = engine;
	}//생성자로 외부에서 엔진 가져오기
	
	public void setEngine(Engine engine) {
		this.engine = engine;
	}//setter로 외부에서 엔진 가져오기

	public void drive() {
		engine.start();
	}
}

public class Run {

	public static void main(String[] args) {
		Engine engine = new ToyotaEngine();
		
		Car car = new Car(engine); // 의존관계 설정(자동차가 엔진에 의존한다)
		car.drive();
		
		engine = new FordEngine();
		car.setEngine(engine);
		car.drive();
		
		car.setEngine(new HyundaiEngine());
		car.drive();
	}
}