3.1 의존성 문제
Depend upon abstractions, not concretions
1️⃣ 학습 목표
: 학습 목표는 "1)의존성 이해"와, "2)의존성 문제 파악"입니다. 이를 위한 단계별 학습 순서를 확인합니다.
✔️ 1. 학습 목표
- Step 1.
- Dependency, 의존성이라는 용어와 개념 이해
- 의존(의지, 종속, 객체 생성 책임)에 대한 개념 이미지를 머리속에 그리기
- 간단한 상속 관계를 기반으로 "의존" 이라는 개념을 이해하기
- Step 2.
- 객체 지향 프로그래밍(OOP)의 의존된 구조에서
"의존성" 개념을 코드로 이해하기
- 객체 지향 프로그래밍(OOP)의 의존된 구조에서
- Step 3.
- 의존된 구조의 문제 파악하기
✔️ 2. 의존 관계와 집합 이미지

✔️ 3. 의존 관계와 의존 역전 관계

2️⃣ 의존성 이해
✔️ 1. 용어
- Dependency: 의존, 의지, 종속
- 依 의지할 의, 存 있을 존
- 다른 것에 의지(依支)하여 존재(存在)함.
✔️ 2. 상속 관계에서 의존 관계 의미 이해하기


- 상속받은 자식 객체는, 부모 객체의 속성을 가지고 있습니다.
부모 객체의 속성 없이 존재할 수 없습니다. - 이를 하위 객체인 Programmer, Dancer, Dog, Iguana 등의 객체가 "상위 객체에 의존한다"고 표현합니다.
- 화살표의 방향은 의존하고 있는 방향입니다.
✔️ 3. 예제 - 간단한 상속관계
📁 3.1 부모 클래스 - Person
// Person 클래스: 부모 클래스 (상위 클래스)
// 공통 속성(Name)과 메서드(Hello)를 정의
public class Person
{
public string Name { get; set; }
public void Hello()
{
Console.WriteLine($"안녕하세요, 저는 {Name}입니다.");
}
}
Person 클래스는, Name이라는 데이터를 다루는 필드와, Hello( )라는 로직을 맴버로 갖습니다.
📁 3.2 자식 클래스 - Programmer, Dancer, singer
// Programmer 클래스: Person 상속 (하위 클래스)
// → Name 속성과 Introduce 메서드를 상위 클래스(Person)로부터 상속받아 의존
public class Programmer : Person
{
public void Code()
{
Console.WriteLine($"{Name}가 코딩을 합니다.");
}
}
Programmer 클래스는, Code( )라는 로직만을 맴버로 갖습니다.
하지만 Person 클래스를 상속받았기 때문에, Name 필드와, Hello( ) 로직도 맴버로 갖습니다.
public class Dancer : Person
{
public void Dance()
{
Console.WriteLine($"{Name}가 춤을 춥니다.");
}
}
public class Singer : Person
{
public void Sing()
{
Console.WriteLine($"{Name}가 노래를 부릅니다.");
}
}
✔️ 4. 예제 - 간단한 상속 관계에서 알아보는 의존 개념
// 메인 실행 클래스
class Program
{
static void Main()
{
Programmer programmer = new Programmer { Name = "홍길동" };
Dancer dancer = new Dancer { Name = "김영희" };
Singer singer = new Singer { Name = "박철수" };
// 상위 클래스의 Introduce 메서드를 호출
programmer.Introduce();
programmer.Code();
dancer.Introduce();
dancer.Dance();
singer.Introduce();
singer.Sing();
}
}
// 출력 예시
안녕하세요, 저는 홍길동입니다.
홍길동가 코딩을 합니다.
안녕하세요, 저는 김영희입니다.
김영희가 춤을 춥니다.
안녕하세요, 저는 박철수입니다.
박철수가 노래를 부릅니다.
(상위 클래스) Person 은 Name 속성과 Introduce 메서드를 (하위 클래스) Programmer, Dancer, Singer 에 제공합니다.
>> 하위 클래스는 상위 클래스의 기능을 "상속"받아 "확장"되었으므로, 상위 객체의 속성없지 존재 할 수 없음 → 종속(dependency) 관계
>> 상위 클래스 변경 시 하위 클래스에 영향 → 상속 관계의 의존성을 보여주는 기본 구조
>> 객체지향에서 "is-a" 관계를 표현 → Programmer is a Person, Dancer is a Person
3️⃣ 의존 관계
✔️ 1. 의존 관계 (Python 참고 영상 링크)

- Cat, Dog 객체
class Cat:
def speak(self):
print("Meow")
class Dog:
def speak(self):
print("bark")
- Zoo 객체
class Zoo:
def __init__(self):
self.cat = Cat()
self.dog = Dog()
- Zoo 클래스가 Cat 클래스 생성 책임을 가짐
- Cat 클래스 코드 변경 시 Zoo도 영향을 받음
- 다른 동물 추가 시 Zoo 내부 코드 수정 필요
- 강한 결합 (Tight Coupling)
- 실행
zoo = Zoo()
zoo.cat.speak()
zoo.dog.speak()
- Zoo 객체는, Cat, Dog 객체에 의존된 관계다.
- Zoo 객체는, Cat, Dog 객체 없이 존재할 수 없으며,
- Zoo 객체는, Cat, Dog 객체가 수정되거나 Sheep 객체가 확장 될 때, 같이 수정할 필요가 있다.
✔️ 2. 예시 - 의존된 관계에 기능 확장하는 경우

✔️ 3. 예시 - 의존된 관계에 기능 확장하는 경우, 소스코드
class Cat:
def speak(self):
print("Meow")
class Dog:
def speak(self):
print("bark")
# 추가된다고 가정합니다.
class Sheep:
def speak(self):
print("Baaa")
class Cow:
def speak(self):
print("Moo")
# 가장 먼저,
# 의존된 관계에서는 Zoo 객체가 직접 수정되어야 한다.
class Zoo:
def __init__(self):
self.cat = Cat()
self.dog = Dog()
self.sheep = Sheep()
self.cow = Cow()
zoo = Zoo()
zoo.cat.speak()
zoo.dog.speak()
zoo.sheep.speak()
zoo.cow.speak()
- 프로그래밍 관점에서, 객체가 의존된 관계에서 어떤 문제가 발생하는지 확인해 봅시다.
4️⃣ 의존 관계 - 문제 파악하기
: 프로그래밍은, 개발자 입장에서 프로그램을 구현하는 관점에서 생각해보아야 한다.
✔️ 1. 가정
위 종속된 객체 구조 예시에서, 개발자 2명이 각각 구현했다고 가정합니다.
개발자A는 Sheep 객체를, 개발자B는 Cow 객체를 각각 구현한다면, 어떤 문제가 발생하는지 확인해봅시다.
✔️ 2. 개발자A, " Sheep 객체" 구현 후, 기존 코드 적용 작업

✔️ 3. 개발자B, "Cow 객체" 구현 후, 기존 코드 적용 작업

✔️ 4. 개발자A, 개발자B 작업 결과 서로 다른 코드로 구현되어 통합 작업 필요

✔️ 5. 팀원 3명으로 의존 관계의 소스코드 구조 구현후 통합해보시면, 실감하실 수 있습니다.
- 전사, 마법사, 궁수 클래스를 각각 구현하고, 통합 테스트를 진행해보세요
✔️ 6. 여러명의 팀단위 구현이 아니더라도, 내 코드가 위 구조와 같다면, 동일 업무 로드가 발생합니다.
✔️ 7. 문제를 파악했으니, 문제를 해결하기 위한 기술을 배울 차례입니다.
5️⃣ 의존 관계 - 문제 파악하기 (C# 소스코드 버전)
: 의존이란, 객체 생성 책임 구현 구조 문제다.
Cat, Dog 객체
class Cat
{
public void Speak()
{
Console.WriteLine("Meow");
}
}
class Dog
{
public void Speak()
{
Console.WriteLine("Bark");
}
}
(확장) Sheep 객체
class Sheep
{
public void Speak()
{
Console.WriteLine("Baaa");
}
}
Zoo 객체
// Zoo 클래스가 구체 클래스에 직접 의존함
class Zoo
{
private List<object> animals = new List<object>();
public void AddCat()
{
animals.Add(new Cat());
}
public void AddDog()
{
animals.Add(new Dog());
}
public void AddSheep()
{
animals.Add(new Sheep());
}
public void Run()
{
foreach (var animal in animals)
{
if (animal is Cat cat)
cat.Speak();
else if (animal is Dog dog)
dog.Speak();
else if (animal is Sheep sheep)
sheep.Speak();
}
}
}
실행
class Program
{
static void Main()
{
Zoo zoo = new Zoo();
zoo.AddCat();
zoo.AddDog();
zoo.AddSheep();
zoo.Run();
}
}