본문 바로가기

24DAY 백엔드

24DAY 백엔드 - 19DAY 개발과 설계원칙

728x90

1. GOF 디자인패턴

GOF에서는 23가지 디자인 패턴을 3가지 유형으로 분류합니다.

A. Creational Pattern

  • 객체를 생성하는데 관련된 패턴들
  • 객체가 생성되는 과정의 유연성을 높이고 코드의 유지를 쉽게 함

B. Structural Pattern

  • 프로그램 구조에 관련된 패턴들
  • 프로그램 내의 자료구조나 인터페이스 구조 등 프로그램의 구조를 설계하는데 활용할 수 있는 패턴들

C. Behavioral Pattern

  • 반복적으로 사용되는 객체들의 상호작용을 패턴화 해놓은 것들

A. 생성패턴

Abstract Factory (추상 팩토리)  

 -동일한 주제의 다른 팩토리를 묶어 준다.

Builder

 -생성(construction)과 표기(representation)를 분리해 복잡한 객체를 생성한다

Factory Method

 -생성할 객체의 클래스를 국한하지 않고 객체를 생성한다.

Prototype (원형)

 -기존 객체를 복제함으로써 객체를 생성한다.

Singleton (단일체)

 -한 클래스에 한 객체만 존재하도록 제한한다.

 

B. 구조패턴

Adapter (적응자)

 -인터페이스가 호환되지 않는 클래스들을 함께 이용할 수 있도록, 타 클래스의 인터페이스를 기존 인터페이스에 덧씌운다.

Bridge (가교)

 -추상화와 구현을 분리해 둘을 각각 따로 발전시킬 수 있다.

Composite (복합체)

 - 0개, 1개 혹은 그 이상의 객체를 묶어 하나의 객체로 이용할 수 있다.

Decorator (장식자)

 -기존 객체의 매서드에 새로운 행동을 추가하거나 오버라이드 할 수 있다.

Façade (퍼사드)

 -많은 분량의 코드에 접근할 수 있는 단순한 인터페이스를 제공한다.

Flyweight (플라이급)

 -다수의 유사한 객체를 생성·조작하는 비용을 절감할 수 있다.

Proxy (프록시)

 -접근 조절, 비용 절감, 복잡도 감소를 위해 접근이 힘든 객체에 대한 대역을 제공

 

C. 행위 패턴

Chain of Responsibility (책임연쇄)

 -책임들이 연결되어 있어 내가 책임을 못 질 것 같으면 다음 책임자에게 자동으로 넘어가는 구조

Command (명령)

 -위의 명령어를 각각 구현하는 것보다는 위 그림처럼 하나의 추상 클래스에 메서드를 하나 만들고 각 명령이 들어오면 그에 맞는 

  서브 클래스가 선택되어 실행하는 것

Interpreter (해석자)

 -문법 규칙을 클래스화한 구조를 갖는SQL 언어나 통신 프로토콜 같은 것을 개발할 때 사용

Iterator (반복자)

 -반복이 필요한 자료구조를 모두 동일한 인터페이스를 통해 접근할 수 있도록 메서드를 이용해 자료구조를 활용할 수 있도록 해준다.

Mediator (중재자)

 -클래스간의 복잡한 상호작용을 캡슐화하여 한 클래스에 위임해서 처리 하는 디자인 패턴

Memento (메멘토)

 -Ctrl + z 와 같은 undo 기능 개발할 때 유용한 디자인패턴. 클래스 설계 관점에서 객체의 정보를 저장

Observer (감시자)

 -어떤 클래스에 변화가 일어났을 때, 이를 감지하여 다른 클래스에 통보해주는 것

State (상태)

 -동일한 동작을 객체의 상태에 따라 다르게 처리해야 할 때 사용하는 디자인 패턴

Strategy (전략)

 -알고리즘 군을 정의하고 각각 하나의 클래스로 캡슐화한 다음, 필요할 때 서로 교환해서 사용할 수 있게 해준다.

Template Method

 -상위 클래스에서는 추상적으로 표현하고 그 구체적인 내용은 하위 클래스에서 결정되는 디자인 패턴

Visitor (방문자)

 -각 클래스의 데이터 구조로부터 처리 기능을 분리하여 별도의 visitor 클래스로 만들어놓고 해당 클래스의 메서드가 

  각 클래스를 돌아다니며 특정 작업을 수행하도록 하는 것

 

2. 도메인 설계주도(DDD)

DDD의 목적 소프트웨어의 복잡성을 최소화 하는 것 요구 사항을 쉽게 반영할 수 있습니다.

소통이 원활하게 이루어질 수 있습니다. 개발의 범위를 쉽게 파악하고 스케줄링 할 수 있습니다. 설계를 일관되게 할 수 있습니다.

 

DDD를 프로젝트에 반영하기 위해서는 기술보다 도메인이 더  높은 우선순위를 가져야하고, 어떤 문제를 하기 우해서는 하상 도메인을 먼저 고민하는 것을 필요로 합니다. 그리고 그 도메인들을 바탕으로 설계하고 프로젝트에 지속적으로/반복적으로 반영하여 개발합니다.

 

 

3, 테스트 주도 개발(TDD)

전통적으로 우리는 프로그램 개발이 완료된 후에 테스트를 진행합니다. 

TDD는 테스트코드를 먼저 작성하고 그 테스트코드를 통과하는 실제코드를 나중에 만듭니다. 건물을 지을 때 벽돌을 쌓는 방법을 떠올려보자. 벽돌을 쌓을 때는 벽돌을 얼마만큼 쌓을 건지 특정영역에 실로 표시를 해 놓고 벽돌을 쌓다가 실까지 벽돌이 채워지면 쌓는 것을 중요합니다.

TDD로 비유하면 공간에 실로 영역을 표시하는 것을 "테스트코드"에, 실제 벽돌을 쌓는 것은 "실제코드"에 비유할 수 있다. 벽돌을 쌓을 때 벽돌이 비뚤어지는지 정확히 쌓이는지 실에 의해서 판단이 가능한 것과 같은 이치로 테스트 코드는 실제 코드가 나아가야 할 방향을 알려주고 있는 것입니다.

만약 벽돌이 조금 비뚤어지게 쌓였다면 반듯하게 다시 잡아가게 되는데 이것은 리팩토링에 비유할 수 있겠습니다. (리팩토링은 소스코드의 기능은 유지한 채로 소스코드의 디자인을 개선해 나가는 방법입니다)

 

 

  1. 무엇을 테스트할 것인가 생각한다.
  2. 실패하는 테스트를 작성한다.
  3. 테스트를 통과하는 코드를 작성한다.
  4. 코드를 리팩토링한다. (테스트코드 또한 리팩토링한다)
  5. 구현해야 할 것이 있을 때까지 위의 작업을 반복한다.

TDD의 목표

Simple Code는 코드가 단순하다는 의미가 아니라 중복이 없고 누가 봐도 명확한 코드를 말합니다. 가끔 프로젝트를 하다보면 정말 띄어난 프로그래머들을 보게됩니다. " 오 ~ 이것을 이렇게 간단하고 이해하기 쉽게 표현하다니!" 라는 감탄사와 함께 말입니다. 직관련이 띄어난 프로그래머는 복잡하게 할 것을 아주 간단하게 만들어버리는 능력이 있습니다. 하지만 TDD를 이요하면 특별한 능력 없이도 자연스럽게 가가장 Simple한코드를 만들어 나가게 됩니다.

4. SOLID(객체 지향 설계)

1. SRP(단일책임의 원칙: Single Responsibility Principle)

작성된 크래스는 하나의 기능만 가지며 클래스가 제공하는 모든 서비스는 그 하나의 책임을 수행하는데 집중되어 있어야 한다는 원칙입니다.

 

2. OCP(개방 폐쇄의 원칙: Open Close Principle)

객체지향 소프트웨어 설계라는 책에서 정의한 내용으로 소프트웨어의 구성요소(컴포넌트, 클래스, 모듈, 함수)는 확장에는 열려 있고, 변경에는 닫혀있어야 한다는 원리입니다.

 

3. LSP(리스코브 치환읜 원칙)

5가지 원칙 중에서 좀처럼 쉽게 이해 되지 않는 윈칙의 하나로 LSP라는 이름에서는 도저히 원칙에 대한 내용을 도출할 수 없는 원칙입니다.

 

4. ISP(인터페이스 분리의 원칙)

한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다는 원리입니다.

 

5.DIP(의존성역전의 원칙)

구조적 디자인에서 발생하던 하위 레벨 모듈의 변경이 상위 레벨 모듈의 변경을 요구하는 위계관계를 끊는 의미의 역전입니다.

 

5. KISS

KISS는 "Keep it small and simple", "Keep it short and simple", 또는 Keep it simple, stupid" 를 나타내는데 소프트웨어 디자인을 간단하고 단순하게 하는 것 입니다. 즉 큰 프로젝트를 단순하게 디자인 하지 못하고 복잡하게만 구현을 한다는 것은 프로젝트를 제대로 이해하지 못했다는 증거입니다. 프로젝트가 진행되기 전에 최대한 기반 배경과 추진되는 목적자체를 이해하고 어떻게 구현을 단순화하고 알기쉽게설계할 수 있을지 회의를 해서 개선해야합니다. ERP를 예를 들으면, 기존의 업무를 분석하고 나서 그대로 구현하는 것이 아니라 조직내의 업무를 다 펼쳐 놓고 중복되는 일이나 잘 못 분배된 업무를 조정하는 것과 불필요한 일들을 제거하는 등의 업무내용을 개선을 먼저 진행을 하고 설계가 진행이 됩니다.

6. YAGNI

정말 필요할 때까지 그 기능을 만들지 마라

 

현재 필요하지 않지만 향후에 필요가능성을 대비해서 미리 함수나 코드를 작성하지말고 지금 필요한 기능만 추가해야합니다. 미리 필요없는 기능을 추가해두면 코드 자체가 길어지기 때문에 분석자체가 더 어려워지며 또한 버그가 발생 할 가능성이 커집니다. 예를 들어서, DB를 사용해서 조회 및 저장하는 프로그램이 있다고 가정해봅시다. DB 종류에는 MSSQL, MYSQL, ORACLE 등 다양해서 처음에는 MSSQL만 하다가 나중에 MYSQL이나 다른 DB 타입을 연동이 필요하다고 예상이 되서 DB를 조회하는 비지니스단을 추상화해서 쉽게 전환이 되게 작업을 할 수 있습니다. 물론 나중에 연동을 대배해서  미리 구현하는 것도 좋지만 그 만큼 시간이 소요되므로 프로젝트 기간이 늘어나므로 비용적인 부담도 발생이 됩니다. 이럴때 현재 연동할 DB만 연동하는것이 좋습니다. 나중에 다른 DB가 추가되면 그때 작업을 진행하는것이 좋습니다.

7. DRY

 

똑같은 일을 두번하지 않는다. 중복되는 함수나 코드는 하나의 공통의 콤포넌트에 넣고 사용한다. 큰 시스템을 여러 조각으로 나누고 서로 참조한다.

 

 같은 코드를 중복해서 작성하지 않는다. 시스템이 소규모일때는 복잡도가 크기 않기 때문에 프로그램을 이해하기가 수월한 반면 시스템이 커지고 개념도 많아지면 복잡도가 기하급수적으로 높아지게 된다. 이런 시스템에서는 복잡도를 최대한 줄여야 개발 및 나중에 유지보수비용이 절감이 된다. 

 



출처: https://hongjinhyeon.tistory.com/136 [생각대로 살지 않으면 사는대로 생각한다.]