아키텍쳐 설계

  • 소프트웨어에서 아키텍처는 소프트웨어의 골격이 되는 기본 구조를 의미하며, 다음과 같은 특징을 가짐
    • 소프트웨어의 골격을 나타내는 추상화된 전체 구조 제공
    • 소프트웨어를 이루고 있는 여러 구성 요소를 다룸
    • 인터페이스를 통해 소프트웨어의 구성 요소가 어떻게 상호작용하는지 정의
    • 세부 내용보다는 중요내용만 다룸
    • 설계에 적용되는 원칙과 지침이 있음
  • 소프트웨어의 품질을 향상시키기 위해 올바른 소프트웨어 아키텍쳐의 설계가 필요함
  • 소프트웨어 아키텍쳐를 올바르게 설계하기 위해 다음 기능을 고려해야 함
    • 모든 이해관계자 사이의 의사소통 도구로 활용할 수 있어야 함
    • 구현에 대한 제약 사항을 정의해야 함
    • 모든 이해관계자의 품질 요구사항을 반영해 우선순위에 따라 시스템 품질 속성을 결정해야 함
    • 특정 문제 영역에 적합한 소프트웨어의 구성 요소를 표준화하고 패턴화해 재사용할 수 있도록 설계해야 함
  • 품질 속성으로는 시스템 품질 속성, 비즈니스 품질 속성, 아키텍쳐 품질 속성이 있음
    시스템 품질 속성으로는 가용성(시스템이 오류없이 서비스를 제공할 수 있는 능력), 변경 용이성, 성능, 보안성, 사용성, 테스트 용이성이 있음
    비즈니스 품질 속성으로는 시장 적시성, 비용과 이익, 예상 시스템 수명, 목표 시장, 발매 일정, 기존 시스템과의 통합 등이 있음
    아키텍쳐 품질 속성으로는 개념적 무결성(=일관성), 정확성과 완전성, 개발 용이성이 있음

아키텍쳐의 4+1 관점

  • 소프트웨어 아키텍쳐를 설명하는 관점
  • 시나리오 관점은 최종 사용자가 인식하는 기능으로써, 기능 하나하나가 유스케이스로 표현되기 떄문에 유스케이스 관점으로도 볼 수 있음
    시나리오 관점에서 작성된 유스케이스 다이어그램은 다른 4개 관점에서 사용하는 다이어그램의 근간이 됨
  • 논리적 관점은 시스템의 기능을 제공하기 위해 필요한 클래스, 컴포넌트 및 관계에 초점을 둠
  • 프로세스 관점은 논리적 관점과 같이 시스템 내부 구조에 초점을 맞추지만, 독제적인 제어 스레드에 초점을 두어 시스템의 프로세스, 스레드 사이의 관계를 표현함
  • 구현 관점은 코드, 데이터 파일, 실행 파일 등의 소프트웨어 서브시스템의 모듈사이의 관계를 나타냄
  • 배치 관점은 서브시스템이 물리적인 환경에서 어떻게 배치, 연결, 실행되는지를 나타냄

아키텍쳐 스타일

데이터 중심형 스타일

  • 데이터를 리포지토리에 공동으로 보관하고 공유 데이터를 서브시스템이 사용하는 방법
  • 데이터를 모순되지 않고 일관성 있게 관리할 수 있고, 새로운 서브시스템을 추가하기도 쉬움
  • 리포지토리가 병목현상을 일으킬 수 있고, 리포지토리 변경시 서브시스템에 영향을 줄 수 있음

클라이언트-서버 스타일


데이터와 처리기능을 클라이언트와 서버에 분할해 사용하는 방법

  • 서버는 클라이언트에 서비스를 제공하는 역할을 함
  • 클라이언트는 사용자와 대화하기 위해 서버가 제공하는 서비스를 호출하는 서브시스템
  • 터미널과 같이 모든 응용 처리 및 데이터 관리를 서버에서 수행하고 클라이언트는 presentation만 구현하는 경우를 씬 클라이언트 스타일로 부름
    유지보수에 유리하고 프로그램이 가벼워 지지만, 서버와 네트워크에 걸리는 부하가 큼
  • 리액트 라이브러리처럼 서버에서 데이터 관리만 관여하고 애플리케이션 로직과 presentation의 상당수가 클라이언트 쪽에서 구현되는 것을 팻 클라이언트 스타일이라 함
  • 서버와 네트워크의 부담을 줄일 수 있지만, 씬 클라이언트 스타일보다 관리하기 복잡하고 업데이트 시 모든 클라이언트에 배포를 해줘야 한다는 단점이 있음

계층 스타일

  • 하나의 계층을 하나의 서브시스템으로 생각하고 하위 계층을 서버 역할, 상위 계층을 클라이언트의 역할을 하도록 구성함
  • 데이터 계층에서는 데이터베이스에 접근해 데이터 처리와 관리를 하며, 백엔드 부분으로도 부름
  • 비즈니스 로직 계층은 기능 요구사항을 구현하는 곳으로 미들웨어라고도 부름
  • 프리젠테이션 계층은 클라이언트 계층으로서 프론트엔드라고도 부름
  • 계층 내부의 응집도는 높고 계층간 결합도가 낮아 재사용 및 유지보수가 용이함
  • 대부분의 운영체제와 통신 시스템이 계층 스타일 사용

MVC 스타일

  • 모듈을 나눠 Model, View, Controller의 세 부분으로 나누어 관리하는 방법
  • Model은 모든 데이터 상태와 로직을 처리하는 부분으로, 특정 입출력 방식에 영향을 받지 않고, 호출에 응답을 함
  • View는 사용자에게 데이터를 직접 보여주는 부분
  • Controller는 View를 통한 사용자 요청을 적절한 모델에 넘겨주고, 모델로 받은 응답을 다시 View를 통해 사용자에게 돌려주는 부분

데이터 흐름 스타일

  • 필터에 해당하는 하나의 서브시스템이 하나의 데이터를 입력으로 받아 처리하고 그 결과를 다음 시스템에 넘기는 과정을 반복하는 스타일
  • 데이터 스트림을 입력으로 받아 데이터 스트림 하나를 출력하는 부분을 필터, 필터의 출력을 다른 필터의 입력에 연결하는 것을 파이프라고 함

클래스 간의 관계

연관 관계

  • 클래스 간에 서로 메시지를 주고받으며 사용하는 관계
  • 한 클래스가 상대 클레스에서 제공하는 기능을 사용하며, 클래스는 상대 클래스를 인식하고 있고, 상대 클레스의 변수를 받아 사용하게 됨
    세부적으로는 아래와 같이 구분 가능
    • 양방향 연관 관계: 학생과 교수가 수업이라는 관계로 엮이듯이 두 객체와 관계만으로 구성된 연관 관계, 두 클래스는 서로 반대 클래스가 무엇인지를 알고 있음
    • 다중 연관 관계: 양방향 연관 관계와 비슷하나 각 그룹의 객체가 한명씩이 아닌 경우(2:1, 다대다 등등)의 연관 관계
    • 단방향 연관 관계: 두 클래스 그룹간의 연관이 있는 것은 같지만, 한쪽은 상대 클래스를 알고, 다른 한쪽은 상대 클래스를 모르는 관계
    • 연관 클래스: 연관관계를 구체적으로 나타내기 위해 점선을 사용해 클래스를 추가로 보여주는 것

일반화 관계

  • 여러 클래스 사이의 일반적인 공통점을 찾아내 공통된 클래스를 만드는 방법
  • 일반화 관계는 상속 구조이며 하위 클래스는 상위 클레스의 모든 것을 상속받아 사용함
  • 개별 클래스와 공통 클래스 사이에 is a kind of 관계가 성립되어야 함
    ex: 삼각형은 도형의 일종이다, 사각형은 도형의 일종이다에서 삼각형, 사각형과 도형의 관계

집합 관계

  • 상위 클래스가 하위 클래스로 구성되는 경우
  • 개별 클래스와 공통 클래스 사이에 is composed of 관계가 성립해야 함
    ex: 모니터, 본체, 키보드는 컴퓨터의 구성요소
  • 모든 객체가 별도의 생명주기를 가지고 있으며, 각각 독립적으로 동작 -> 약한 결합 관계

합성 관계

  • 집합 관계와 비슷하지만, 각각의 요소를 분리해 재사용할 수 없는 경우
  • 부분 객체는 전체 객체가 없어질 때 같이 없어지게 됨 -> 강한 결합 관계

의존 관계

  • 연관 관계와 비슷하지만 상대 클래스를 인식하기 위해 변수를 클래스 전역 시간동안 가지지 않는 경우
  • 메서드에 상대 클래스를 인자로 가지거나 메서드 내부에서 지역 변수로 클래스를 선언하는 경우 메서드 실행 동안만 해당 변수를 가지게 되며, 이 경우를 의존 관계로 부름
// 연관 관계
class multiplier {
  multiply (a: number, b: number) {
    return a * b;
  }
}

class squareCalculator {
  const innerMultiplier = new multiplier();
  square(a: number) {
    return innerMultiplier.multiplier(a, a);
  }
}

//의존 관계 - 인자로 클래스 호출
class squareCalculator {
  square (a: number, multiplier: multiplier) {
    return multiplier.multiply(a, a);
  }
}

//의존 관계: 메서드 내부에서 클래스 선언
class squareCalculator {
  square (a: number) {
    const innerMultiplier = new multiplier();
    return innerMultiplier.multiplier(a, a);
  }
}

실체화 관계

  • 인터페이스와 같이 추상 메서드를 하위 클래스에서 구체적으로 구현하는 관계
  • 객체마다 구현이 조금씩 달라지는 경우에 사용 가능한 관계임

클래스 설계 원칙

  • 단일 책임 원칙(Sing-Responsibility Principle): 클래스를 변경해야 하는 이유는 단 하나여야 한다. => 하나의 클래스는 하나의 책임만을 가져야 함
  • 개방 폐쇄 원칙(Open-Closed Principle): 변경에는 닫혀 있어야 하고, 확장에는 열려 있어야 한다 => 추가 사항이 클래스에 영향을 받지 않도록 하고, 새로운 클래스는 쉽게 추가할 수 있는 구조여야 함
  • 리스코프 교체 원칙(Liskov Subsitution Principle): 상위 클래스의 객체는 언제나 하위 클래스의 객체로 교체할 수 있어야 함 => 상속 구조를 만들 때 상위 클래스가 추상 클래스, 추상 메서드여야 하고 오버라이딩을 할 때는 피터 코드의 상속 규칙에 맞게 사용해야 함
    피터 코드의 상속 규칙: 하위 클래스는 상위 클래스의 책임을 무시하거나 재정의하지 않고 확장만 수행함
  • 인터페이스 분리 원칙(Interface Segreation Principle): 클라이언트는 자신이 사용하지 않는 메서드와 의존 관계를 맺으면 안 된다. => 사용하지 않은 인터페이스 때문에 영향을 받아서는 안됨
  • 의존 관계 역전 원칙(Dependency Inversion Principle): 클라이언트는 구체 클래스가 아닌 추상 클래스에 의존해야 한다 => 서로다른 여러 객체가 동일한 구체 클래스를 참조하게 해서는 안됨

출처:
쉽게 배우는 소프트웨어 공학 2판, 김치수, 한빛아카데미

profile
냐아아아아아아아아앙

0개의 댓글

Powered by GraphCDN, the GraphQL CDN