디자인 패턴이란?
디자인 패턴의 3가지 분류
싱글톤
이 객체가 딱 한 번만 생성하게 하고 싶을 때 하는 디자인 패턴.
Ex) 게임을 총괄하는 매니저, 게임 보드라는 게 하나만 있으면 좋겠다 할 때,
항상 이미 만들어진 객체를 주고, 새롭게 만들지 않음.
이 클래스의 인스턴스가 하나만 만들어지도록 보장해야함.
-> 클래스의 생성자를 private으로 만든다. 객체가 아무곳에서나 생성되게 하지 않는다.
그래도 아예 막아버리면 안 되고, 생성은 해야한다. 글로벌 액세스 포인트를 만들어서 객체 생성을 제어한다.
Static 키워드를 이용한 멤버필드, 멤버펑션으로 생성자를 만든다.
생성자를 만들거나, 이미 있는 객체를 반환하거나 한다.
java는 복사를 명시적으로 해야하지만, C++은 단순히 선언만 해도 복사가 잘 된다. (9분)
클래스 함수에 delete를 해두면 이 함수는 절대 호출되지 않는다. (존재하지 않는다.)
빌더
건축가와 같은 뜻으로 객체를 건축한다. 간단한 객체를 만드는 건 쉽다. 어떤 객체를 만들 때 너무 복잡한 수행이 필요할 때 사용하는 디자인 패턴이다.
House 클래스 - 조절할 게 많다!
차고, 수영장, 동상, 정원 ... 인스턴스가 다양하고 만드는 것도 복잡하다.
생성자에서 이런 정보를 받아야 집 객체를 만들어줄 것이다. (정보 configuration이 100가지나 된다면? 생성자의 인자를 100개를 넘겨줘야 객체를 만들어줄 수 있을 것이다. parameter가 뭔지도 다 기억해야할 것이다. 헷갈리고 복잡하다.)
생성자의 인자가 뭔지 기억할 필요 없이 함수를 불러서 조립하고, 마지막에 getResult()로 마지막에 불러오기만 하면 되도록 짜자.
circular dependency ->서로를 include해야 작동이 가능한 상태, 컴파일 오류
Forward Declaration 전방 선언
C++에서 circular dependency를 피하는 방법.
프로토타입
객체가 있는데 복사해서 클론을 만들고 싶다. 객체를 상세하게 알고 싶은 것은 아닐 때
Encapsulation을 위배하지 않도록 객체한테 스스로 복사하라고 하는 것.(Clone()메소드를 짜주기.)
자기가 자기를 만들어서 반환하도록 한다.
Abstract factory
객체를 생성하는 공장이다.
빌더와는 좀 차이가 있다. 공장에서 나오는 물품들은 다양하다. 생산지는 동일하다!
여러 종류의 객체들을 여러 가지로 만들 수 있다. 테이블 객체를 3 가지 종류로 만들 수 있을 때 이 종류를 하나로 통일하고 싶을 때 사용한다.
특정 공장의 주소를 알려주고 해당 주소를 통해서 만든다면 원하는 걸 만들 것이다. 같은 종류의 객체로 만들고 싶을 때이다.
개별 물품을 하나씩 만들지 않고, factory를 통해서 자기 종류에 맞는 객체를 만들어서 반환을 해줄 것이다.
factory는 인터페이스로 abstract class이다.
-여기까지 소개한 것들은 객체 생성 디자인 패턴
한 번씩은 귓가에 스쳐가는 것이 좋다. 이런 게 있었다. 저런 게 있었다. 설계 시 참고하면서 사용하면 된다. 모든 디자인 패턴을 암기할 필요는 없다. 적용이 중요하다.
Adapter
Bridge
객체 간의 다리를 연결해서 만들기. 객체가 지원할 기능이 너무 많다! 이러면 기능들이 너무 많아서 유지 보수가 어렵다. 이 기능들을 다 알아둬야 유지보수 가능.
최대한 사물 단위로 개별적으로 분리할 수 있는 것들을 기준으로 구분하여 설계하면 된다.
Composite
합친다! 객체를 하나 구성할 때,
하나의 박스에 모든 것을 담는다면 찾기도 어렵다. 그렇다면 박스 안에 박스를 만들어서 소분류로 넣어두자. 재귀적인 구성! 구성을 훨씬 간단하게 할 수 있다.
execute()를 실행해서 composite을 호출해서 뭔가를 수행하고, composite이 또 그 안에 있다면 다시 그 composite을 호출하고 ... 재귀적으로 호출하자!
Facade 파사드
이해하기 좀 어렵지만, 알고나면 정말 별 거 없다.
나 혼자만 개발. 이게 아니라 다른 사람들과 협업하면서 library, API 등등 같이 사용한다. 나중에 동료의 것이 업데이트, 수정이 된다면 그와 관련된 걸 다시 찾아서 바꿔야할텐데 상호작용이 복잡해진다.
그 상호작용을 대리인이 하도록 하자. 나중에 동료의 것이 바뀐다면 다른 모듈, 다른 라이브러리가 바뀐다면 대리인만 수정해주면 내 코드 전체를 변경할 필요는 없어진다.
의존성을 무조건 낮추는 것이 중요하다. 의존성을 낮춘다는 건!
개발에 드는 비용, 결함 찾기, 결함 개선, 등등의 수정하는 것의 비용을 낮춰야 한다. 의존성이 높다면 효율성은 떨어지게 된다.
객체지향설계의 장점이 이러한 객체들 간 의존성을 없애는 것.
Proxy
facade는 의존성을 떨어뜨리기 위해서 그 의존성을 담당하는 대리인을 만드는 것이고, 이것도 전담자가 있는데!
어떠한 기능을 향상하고 싶다! (예시) 이것을 컨트롤하기 위해서 만든 것이다.
데이터베이스가 있다고 하자. 데이터값은 안 바뀐다. query를 동일하게 계속 줄 때(데이터베이스에 데이터를 요청하는 것), 데이터베이스까지 가서 답을 받는 것에서 시간이 오래 걸린다. 직접 데이터베이스로 가는 것에 시간 overhead가 발생하게 되기 때문이다. 그렇다면 프록시를 이용해서 더 빠르고 거리가 짧게 만들어서 접근을 용이하게 하자.
혹은 데이터베이스에 대해서 접근을 엄격하게 하고 싶다면, 프록시를 통해 인증절차를 확인받고 데이터베이스의 값을 저장한 프록시가 그 데이터를 주게 된다. 옵션을 주자!
facade와 proxy의 차이가 도대체 뭐야!
facade는 의존성을 떨어뜨리기 위한 목적.
proxy는 향상을 위한 목적.
'[Computer Science] -보호글 > [객체지향설계]' 카테고리의 다른 글
[객체지향설계] 11/14 이론 (0) | 2023.11.14 |
---|---|
[객체지향설계] 11/7 이론 (0) | 2023.11.07 |
[객체지향설계] 10/03 이론 (0) | 2023.10.23 |
[객체지향설계] 10/17 이론 (1) | 2023.10.17 |
[객체지향설계] 09/26 이론 (0) | 2023.09.26 |