(Day 20) 인터페이스, 컴포지트 패턴
클라우드 기반 웹 데브옵스 프로젝트 개발자 교육 과정 (5기)
- 비트캠프 엄진영 강사님 (https://github.com/eomjinyoung/)
- 훈련기관 : 네이버클라우드주식회사
- 기간: 2023-11-14 ~ 2024-5-22
- 남은 일자 : 111 일 ( 20/129 )
본 내용은 제가 교육을 수강하며 기록한 내용으로, 정리되지 않은 부분이 많으므로 양해부탁드립니다.
20일(2023-12-11, 월)
취업 관련
여기서 배운 내용은 포트폴리오에서 언급해야 할 개념들이 많이 있다. 예시를 들면 아래와 같다.
SOLID 원칙을 준수하여 만들었다- SOLID 원칙을 준수하기 위해 GRASP 패턴을 적용하였다 -
- SOLID의 Low Cohesion 구현을 위해 GoF의 Composite 패턴을 적용하였다. - 이러한 객체지향 프로그래밍의 원칙들을 적용하기 위해서 인터페이스 문법이 필수적이다.
자기소개서를 지금부터 적는다고 생각하면 된다. 짧은 요약본 하나 만들고, 긴 자기소개서를 읽도록 유도해야 한다. 객체지향 프로그래밍을 위한 기법들을 사용하여 OO 서비스를 만들었다 등의 자기소개를 할 때, 이러한 내용이 있으면 보는 사람이 관심이 생기고, 전체 자기소개서나 포트폴리오를 볼 확률이 높아진다. (예전에는 경쟁이 심하지 않았으나 현재는 경쟁이 상당히 심해졌다. 자리가 줄어들어드는데 공급은 늘었다.)
질문이 들어오면, 아래와 같은 구조로 흘러갈 가능성이 높다.
- 적용했다는 OO 개념이 무엇인지 설명해줄 수 있나요?
- OO 개념을 어떻게 적용했는지 구체적으로 설명해줄 수 있나요?
- 어디에 적용했는지?
- 왜 적용했는지?
- 어떤 문제점을 해결했는지?
학습
인터페이스
인터페이스는 무엇인가?
인터페이스는 클래스를 위한 계약서 같은 것이다.
인터페이스는 마치 클래스 간의 상호작용을 규제하고 정의하는 일종의 ‘계약서’와 같다. 이 계약서에는 특정한 메서드나 속성이 반드시 포함되어야 하며, 이를 구현하는 클래스는 마치 이 계약서를 준수하여 기능을 제공해야 한다. 즉, 인터페이스는 클래스들 간의 약속된 규칙을 정의하고, 이를 통해 각 클래스가 어떤 동작을 수행해야 하는지 명확하게 정의한다. 클래스는 이 ‘계약서’를 따르면서 자신만의 독특한 구현을 추가할 수 있어, 마치 각자의 특색을 갖는 계약서 준수자들이 상호작용하는 것과 같다.
자바에서의 인터페이스 정의의 예시를 들어보면,
인터페이스 정의:
1
2
3
interface MyInterface {
void myMethod(); // 메서드 시그니처만 정의, 본문은 없음
}
클래스에서 인터페이스 구현:
1
2
3
4
5
6
7
class MyClass implements MyInterface {
@Override
public void myMethod() {
// 구체적인 기능 구현
System.out.println("MyClass의 구현된 메서드");
}
}
위 코드에서 MyInterface
는 메서드의 시그니처만 정의하고 있다. (바디가 없다) 이 인터페이스를 구현하는 클래스인 MyClass
에서는 myMethod
의 바디까지 계약대로(반드시) 구현해야 한다. 이렇게 인터페이스가 마치 클래스 간의 계약서같은 역할을 하게 된다.
SOLID: High-Coupling 의 문제점
- 기존 클래스의 변경에 직접적인 영향을 받는다. 그래서 기존 클래스가 변경되면 강결합된 클래스도 수정이 필요하다.
- 새 기능을 추가할 때 강결합이 되어 있으면 직접적인 영향을 받는다. 추가되는 기능에 연결되어 있는 코드들을 전부 변경해야 한다.
어떻게 해결해야 할까?
Low Coupling (GRASP) Open/Closed Principle (SOLID)
의존 객체 지정의 두 가지 방법
- 생성자를 통해서 의존객체 생성하기 (Association - 연관) 의존하는 클래스에서 의존받는 인스턴스 생성을 선언해 둠. 의존하는 클래스를 생성할 때 파라미터로 의존객체를 주기. 의존객체를 지속적으로 사용할 때 사용하는 방법이다. UML에서는 실선으로 그린다.
2.의존관계 (Dependency) 특정 메서드를 실행할 때 일시적으로 사용하는 경우. UML에서는 점선으로 표현한다. 디펜던시 객체를 디펜던시한다. 라는 문장은 어색해보일지라도 실제로 사요오디는 문장이다. 의존객체를 어떤식으로 사용하는가? 생성자로 받지 않고 메서드의 인자로 받는다! 즉 메서드가 실행될 때 일시적으로 받아서 쓰는 것이다.
Composite Pattern
myapp 프로젝트를 보면 계층적인 구조를 따른다. 이걸 어떻게 해야 편하게 코딩을 할 수 있을까 고민을 겁나게 해서 나온 노하우가 Composite 패턴이다. 메뉴구조, 회사 조직도 같은 것들은 게층적이다. 근데 매ㅓㄴ 매번 매번 클래스를 추가하고, 추가할 때마다 결합되어 있는(메소드를 호출하는) 부분을 다 수정하고 이러려니 미쳐버리는 것이다.
컴포지트 패턴을 사용하면 계층 구조를 구현할 때, 새로운 노드나 리프를 만들 때마다 클래스를 만들 필요가 없다.
XML을 이용한 메뉴 코드 작성(메뉴 컨트롤러)
안드로이드나 C# WPF 에서는 메뉴를 위한 XML 파일을 작성하면 해당 XML파일을 기반으로 코드가 생성된다. 이는 크게 컴포지트 패턴을 따른다. 기초를 단단히 배우면 다 것에도 적용할 수 있고, 사람들이 왜 이렇게 코드를 쓰고 있는지 이해할 수 있게 된다.
메뉴와 같은 계층 구조를 구현하는 것에는 컴포지트 패턴을 쓰는 것이 가장 나은 방법이라고 검증이 된 것이다.
인스턴스를 사용하는 객체지향 프로그래밍 언어는 모두 이러한 디자인패턴을 공통으로 적용할 수 있다. 그래서 세부 문법이나 기술에 집중할 것이 아니라 이러한 근본 원리에 집중해야 한다.
용어
클라이언트
많은 곳에서 사용되는데, OOP 에서 클라이언트는 다른 클래스를 사용하는 클래스를 말한다.