# SOLID & Design Pattern Sample ## SOLID - SOLID 원칙들은 소프트웨어 작업에서 프로그래머가 소스 코드가 읽기 쉽고 확장하기 쉽게 될 때까지 소프트웨어 소스 코드를 리팩터링하여 코드 냄새를 제거하기 위해 적용할 수 있는 지침이다. - 각 항목별 before & after 를 비교하면서 어떤 차이가 있는지 생각해본다. - before & after 에 새로운, 또는 동일한 규칙(비즈니스 로직, 유효성 검사 등)을 적용해야 한다고 가정하고 변경을 시도해본다. ### SRP(Single Responsibility Principle) - 단일 책임 원칙 - 한 클래스는 하나의 책임만 가져야 한다. 즉, 한 클래스가 변경되는 이유는 한 가지여야 한다. #### 구현 요구사항 - 예금주의 이름으로 계좌를 생성할 수 있다. - 계좌에 입금할 수 있다. - 계좌에서 출금할 수 있다. ### OCP(Open/Closed Principle) - 개방-폐쇄 원칙 - 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다. #### 구현 요구사항 - 최초의 결제방식은 현금, 카드 두 가지가 있다. - 쿠폰 결제방식을 추가한다고 가정한다. - 쿠폰으로 결제할 경우 잔고가 차감되지 않는다. ### LSP(Liskov Substitution Principle) - 리스코프 치환 원칙 - 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다. #### 구현 요구사항 - 좌표를 입력하면 해당 좌표로 이동수단의 위치가 변한다. ### ISP(Interface Segregation Principle) - 인터페이스 분리 원칙 - 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다. #### 구현 요구사항 - 영화 상영관 좌석 현황을 조회할 수 있다. - 영화표 예매를 진행할 수 있다. ### DIP(Dependency Inversion Principle) - 의존 역전 원칙 - 프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안된다.” 의존성 주입은 이 원칙을 따르는 방법 중 하나다. #### 구현 요구사항 - 저장소에서 파일 데이터를 불러올 수 있다. - 하나의 저장소만 사용하며 저장소의 타입은 언제든지 변경될 수 있다. - 각각의 저장소는 각자만의 파일 데이터 조회 요청 인터페이스를 제공한다. - 아마존에서는 파일 이름을 요구한다. - 구글에서는 파일 번호를 요구한다. ## Design Pattern ### 전략(Strategy) 패턴 #### 구현 요구사항 - 연령대별로 물건의 할인된 금액 계산기를 구현한다. - 아이일 경우 할인율은 15%이다. - 어른일 경우 할인율은 30%이다. ### 템플릿 메서드(Template Method) 패턴 #### 구현 요구사항 - 스포츠 강사를 구현한다. - 모든 강사는 강의가 시작할 때 스트레칭을 한다. - 모든 강사는 강의가 끝날 때 인사한다. - 수영 강사는 강의 중간에 수영 동작을 보여준다. - 축구 강사는 강의 중간에 축구 동작을 보여준다. ### 상태(State) 패턴 #### 구현 요구사항 - 상태별로 다르게 움직이는 게임 캐릭터를 구현한다. - 기본적으로 게임 캐릭터는 정지상태이다. - 정지 상태에서 버튼을 누르면 이동한다. - 이동하는 상태에서 버튼을 누르면 점프한다. - 점프하는 상태에서 버튼을 누르면 착지한 뒤 정지한다. - 게임 캐릭터는 버튼을 누르면 동작하는 상태로 스스로의 상태를 변경한다. ### 데코레이터(Decorator) 패턴 #### 구현 요구사항 - 용사는 검을 가진다. - 용사는 검을 바꿀 수 있다. - 검에는 속성이 부여될 수 있으며, 속성에 따라 공격이 변한다. - 용사가 공격하면 소지한 무기의 공격이 발동된다. ### 프록시(Proxy) 패턴 #### 구현 요구사항 - 지갑의 주인은 지갑에 대해 입금 또는 출금을 진행할 수 있다. - 지갑의 동작은 입금 및 출금만 가능하도록 제한된다. - 지갑에 대해 입금 또는 출금이 이루어질 때 메시지를 출력한다. ### 어댑터(Adapter) 패턴 #### 구현 요구사항 - 발전소는 정해진 요청 규격에 따라 전기를 생산한다. - 가정은 정해진 규격에 따라 전기를 얻는다. - 발전소와 가정에서 사용하는 전기는 각각 다르다. - 발전소에서 생산한 전기를 가정용으로 변환하는 계산식은 아래와 같다. - 생산된 전류량 * (발전소 전압 / 가정용 전압) - 발전소에서 생산한 전기의 전압은 11000V 이다. - 가정에서 사용하는 전기의 전압은 220V 이다. ### 옵저버(Observer) 패턴 #### 구현 요구사항 - 주문의 상태가 변경되면 배송팀과 운영팀에 알리고, 각각의 팀은 그에 따른 조치를 취한다. - 배송팀은 배송을 시작한다. - 운영팀은 고객에게 메시지를 전송한다. - 배송팀과 운영팀 외에 다른 팀에도 필요하다면 또 다른 팀에 메시지를 전송해야 할 수도 있다. ### 미디에이터(Mediator) 패턴 #### 구현 요구사항 - 가전제품의 전원을 제어한다. - 가전제품의 전원은 하나만 켤 수 있고, 하나를 켜면 나머지는 모두 꺼진다. - 가전제품을 켤 경우, 해당 가전제품의 이름을 메시지로 전송한다. ### 파사드(Facade) 패턴 #### 구현 요구사항 - 회원의 모든 정보를 조회한다. - 회원의 모든 정보에는 회원의 기본 정보와 친구들에 대한 정보가 있다. - 회원의 기본 정보에는 이름, 나이가 있다. - 회원의 친구 정보에는 친구의 이름, 나이가 있다. ### 추상 팩토리(Abstract Factory) 패턴 #### 구현 요구사항 - 과일 이름을 입력하면 해당 과일 또는 과일주스를 만들어주는 마법이 있다. - 과일의 종류는 사과, 바나나, 오렌지로 총 세 가지다. - 과일주스의 종류도 마찬가지로 사과주스, 바나나주스, 오렌즈주스로 총 세 가지다. ### 컴포지트(Composite) 패턴 #### 구현 요구사항 - 프랜차이즈 기업의 정산은 가맹점으로 가입된 모든 가게들의 정산을 포함한다. - 프랜차이즈 기업은 다른 프랜차이즈 기업을 포함할 수 있다. - 프랜차이즈 기업은 이름을 갖는다. - 프랜차이즈 가맹점은 이름을 갖는다. ### 널 객체(Null Object) 패턴 #### 구현 요구사항 - 식당에서는 직원을 이름으로 관리하며 동명이인은 없다고 가정한다. - 이름으로 직원을 찾을 수 있고, 해당 직원에게 근무일자를 할당할 수 있다. - 직원은 근무일자를 고지 받으면 해당 날짜를 기억한다. ## 참고자료 - [SOLID (객체 지향 설계)](https://ko.wikipedia.org/wiki/SOLID_(%EA%B0%9D%EC%B2%B4_%EC%A7%80%ED%96%A5_%EC%84%A4%EA%B3%84))