Pattern/C++

[C++] interface와 결합(Coupling)

dpswlsldj 2021. 3. 20. 16:20
728x90

interface는 객체 지향 프로그래밍에 있어서 중요한 개념입니다.

 

객체 지향 프로그래밍에서 중요시하는 여러 아이템이 있지만 그 중 하나가 코드 수정을 최소화하는 것입니다.

 

이를 위해 강한 결합 (객체 간 직접 참조)을 최소화하고 약한 결합을 지향합니다.

 

객체가 추가되거나 삭제되어도 이를 이용하는 소스에 변화가 발생하지 않도록 하자는 것입니다.

 

아래의 예시 코드가 강한 결합의 예입니다.

 

 

원래 Bus만 운전하던 Driver가 있습니다. 그런데 Truck이 새로 생겼습니다.

 

이 Driver는 Truck을 운전하기 위해 본인의 클래스에 go(Truck) 에 대한 함수를 추가해야만 했습니다.

#include <iostream>

using namespace std;

class Bus
{
public:
	void accelerator() {
		cout << "Bus gogo" << endl;
	}
};

class Truck
{
public:
	void accelerator() {
		cout << "Truck gogo" << endl;
	}
};

class Driver
{
public:
	void go(Bus* bus) {
		bus->accelerator();
	}
	void go(Truck* truck) {
		truck->accelerator();
	}
};

int main() {
	Bus bus;
	Truck truck;
	Driver driver;

	driver.go(&bus);
	driver.go(&truck);
}

 

아래의 코드에서는 원래 Bus만 운전하던 Driver가 Car만 운전할 줄 안다면, Truck을 받더라도 Driver 클래스는 변화하지 않습니다. 다만 Truck이 새로 생겼을 뿐입니다.

 

위의 강한 결합 코드와 다른 점이 이런 부분입니다. 한가지 카테고리에 대한 상위 클래스(interface)만 알고있다면 그 아래 객체들의 상세 내용에 대해서는 몰라도 프로그램은 잘 돌아갑니다.

#include <iostream>

using namespace std;

class ICar
{
public:
	virtual void accelerator() = 0;
};

class Bus : public ICar
{
public:
	void accelerator() override {
		cout << "Bus gogo" << endl;
	}
};

class Truck : public ICar
{
public:
	void accelerator() override {
		cout << "Truck gogo" << endl;
	}
};

class Driver
{
public:
	void go(ICar* car) {
		car->accelerator();
	}
};

int main() {
	Bus bus;
	Truck truck;
	Driver driver;

	driver.go(&bus);
	driver.go(&truck);
}

실행결과

Bus gogo
Truck gogo

 

interface를 나타내는 클래스는 아래와 같이 구조체로 표현할 수도 있습니다.

struct ICar
{
	virtual void accelerator() = 0;
};

Java를 사용하다가 넘어온 일부 프로그래머들은 #define으로 interface를 정의해서 쓴다고도 합니다.

 

각 회사 사정에 맞게 coding convention을 정해야 합니다.

#define interface struct

interface ICar
{
	virtual void accelerator() = 0;
};