2022. 4. 25. 16:15ㆍ강의 내용 정리/소프트웨어 공학
Design and Implementation
탑다운 방식이면 디자인과 구현을 명확하게 구현하곤 한다. 이를테면 설계는 한국에서 하되 구현은 외국에서 진행하는 등의 역할을 구분해 나눌 수 있다. 이러한 경우에는 디자인 단계에서 많은 문서가 나올 수 있다. 그러나 데브옵스와 인터넷 설계 등을 봤을 때 설계와 구현은 밀결합되어있는 경우가 많다.
소프트웨어에 대한 상세 설계와 구현은 프로그래밍 언어를 통해 만드는 과정을 의미한다. 결과적으로는 executable한 시스템을 만들 수 있다.
상세 설계와 구현은 매우 밀결합한 경우가 많다. 구현을 하다가 문제가 발생하는 경우에는 상세설계에 피드백을 줄 수도 있다. 둘은 매우 많이 인터렉션해야한다. 둘을 함께 진행하는 경우에는 일반적으로는 agile 기법이다. agile은 디자인을 최소화할 가능성이 높다.
상세설계는 우리가 만들고자 하는 내부 요소들을 하나의 시스템으로 정의했을 때 그 시스템 내의 구성요소를 정의하고 이들 간의 상호관계를 정의한다. 순차적으로 정의하고 있지만 앞쪽에서 정의한 아키텍쳐 하에서의 디자인을 진행해야한다. 소프트웨어는 하나하나 만들어가는 것이다. 상세 설계는 구현을 위한 것이기에 항상 구현과 밀결합되어야한다.
* 만들 것인가 사올 것인가
- COTS(commercial-off-the-shelf systems): 개발자가 만드는 것보다 상용 소프트웨어를 사서 조금만 바꾸면 사용할 수 있는데 더 싼 경우에는 굳이 개발할 필요가 없다.
- 오픈소스를 가져오는 경우에는 위와 같이 비용적인 측면과 더불어 다른 내용도 고려해야한다.
1. Object-oriented design using the UML
1) Object-oriented design using the UML
agile과 devops 기법에서도 사용할 수 있다. 이러한 경우에는 모두 다 UML로 구현하는 것이 아닌 필요한 내용만 구현하여 사용한다. 우리 끼리 공감대를 형성하거나 모호한 부분을 명확하게 하기 위함이다. 그러나 top-down 방식의 경우에는 구체적인 구현을 이끌어내기 위해 UML을 만들기에 매우 구체적으로 작성해야한다.
객체지향 개발 방법론은 매우 방대하고 다양하며 복잡한 문서를 분석하는 것들이 존재한다. 이 중에 필요하다고 생각이 드는 것을 뽑아서 사용하면 된다. 이를 상세 설계 단계에서 사용할 수 있다. agile 또한 이 중에 필요한 것을 일부분만 발췌해서 사용할 수 있다. 하나의 디자인 방법을 맹신하지 말고 필요한 것을 뽑아 적용하는 것이 중요하다. 특히 대부분 agile에서도 사용할 수 있는 중요한 것들을 위주로 설명하고자한다.
소프트웨어 개발 기간이 길면 대다수는 소프트웨어 개발 기법이 존재한다. 대부분 아래 다섯가지는 반영되어있다.
(1) 우리의 시스템이 할 것과 하지 않을 것들에 대한 부분을 아키텍처 디자인과 비슷하게 언급한다.
(2) 우리가 해야할 것과 다른 쪽의 시스템 레벨의 아키텍쳐를 정의한다.
(3) 우리가 만들 시스템이 있으니 이 내부에 구성요소를 정의한다.
(4) 시스템 오브젝트 간에 상호관계 정의
(5) 인터페이스를 정의한다.
앞쪽에서 예시로 언급한 내용을 하고자 한다. 또한 아키텍쳐 정의할 때 system context와 interations에서 외부 환경을 정의하고 우리 시스템의 바운더리를 정하는 것이 중요하다라는 것을 얘기 했다. 바운더리 안 밖에서 일어나는 상호작용과 우리 시스템이 무엇을 할지에 대한 것이 적혀있기에 이러한 부분이 상세 설계를 위한 요구사항이 될 수 있다. 구조적인 모델로 정의하는 것이 상세설계의 과정이 될 수 있고, 결국은 이를 통해서 동적, 정적으로 안에서 발생하는 것을 상세하게 풀어내는 것이 중요하다. system context, 포지셔닝, 상호작용 등을 통해 확인할 수 있다.
weather station
- 선은 상호작용한다는 것을 의미한다. 개발 코드와 조직 상에 대한 얘기까지 내포하고 있다.
- 숫자는 UML에서 등장한 의미로 관계를 맺는 수를 의미한다. 시스템이나 위성은 하나지만 weater station은 여러개이다.
use cases
- actor가 존재하고 그 등장인물의 action을 알려준다.
- 상세 설계도 동일하게 동작한다.
- 객체지향 기법과 같은 도구는 필요한 만큼 사용할 수 있다.
description
- 여러 도구 기법을 사용할 수 있는데 이 중 테이블 도구 기법을 사용해 이를 표현한다.
- Use case를 트리거하는 부분은 stimulus이다.
- 요청을 받으면 자연스럽게 weather information system에서 보낸다.
2) architectural design
우리 시스템과 바깥 시스템 간의 상호작용을 이해했다. 주요한 작업은 우리 시스템 내의 작업을 짜는 것이 중요하다. 외부와의 상호작용을 토대로 내부에서 해야할 일들도 정의해야한다. 이에 따라 이를 어떤 식으로 정의할 것인가가 주요 요지이다.
Use case가 얼마만의 주기를 가지고 정리하냐, 파일처리를 하냐, 데이터베이스를 만드냐 이런 것들에 대해 정해야한다.
High-level architecture of the weather station
- 기능 관점에서 use case를 기반으로 만든 architecture이다.
- restart, configuration 등을 한다.
- 기기나 관리에 대한 모듈을 정리하기도 한다.
- 우리 시스템을 구성할 요소를 정의하고 이를 어떻게 잘할 것인가가 객체지향 관점에서 하는 것이 중요하다.
- 데이터 컬렉션이 디테일하게 만들어져야하면 시스템 컴포넌트(서브 시스템)을 디테일하게 표현해야한다면 다음과 같이 그릴 수 있다.
Architecture of data collection system
3) 오브젝트 클래스 정의
- 정해진 정답이 없기에 스스로 객체를 정의해보고 고민해보는 부분이 필요하며 경험이 매우 중요하다. 소프트웨어 개발 과정이 어떻다는 것을 간접적으로 고민하고 설계하는 기법을 공부하면 도움이 된다.
- 디자인에서 놓치는 부분이 발생할수밖에 없다. 클래스를 정의하는 것 또한 마찬가지로 한번에 끝나지 않는다.
- 객체지향 기법으로 세부설계하는 것이 필요하다.
(1) 객체 정의의 접근
- 하드웨어 중심인 것에서 tangible하게 보인다면 그를 기준으로 클래스를 만들면 틀리지 않는다.
- 주어나 목적어로 등장하는 것은 대부분 클래스화할 수 있다. 이러한 관점에서 문법적인 접근을 사용할 수 있다. 동사는 함수로 만들 수 있다.
- 시나리오 베이스 접근은 누가 누구에게 어떻게 접근하고 어떻게 행동하는 지 등의 관점으로 클래스를 만들 수 있다. 시퀀스 차트, use case, 시나리오 등을 그리는 것은 도움이 된다.
- 메소드, 인터렉션과 같은 행동적인 부분에 초점을 맞춰 누가 어떤 행동을 하는지, 누가 어떻게 행동을 취하게 하는지 등을 토대로 정할 수 있다.
- 좋은 소프트웨어를 많이 보는 게 좋다.
weather station object classes
상세 설계로서 weather station
4) Design class
- 앞에서 시스템 아키텍쳐 상에서 날씨 스테이션이 뭐해야하는지에 대한 내용을 언급함 해당 부분에서는 두 가지를 기준으로 클래스를 정의하고자 한다.
(1) 우리가 다루는 소프트웨어 안에서 하드웨어를 보고 이를 기준으로 클래스를 정한다. 예시 1) 센서에 상응하는 객체로 정의한다.
(2) use case를 활용해 상호작용을 파악해 이를 대화 전용 클래스를 정의한다. 즉, 외부 시스템과의 대화를 위한 목적으로 만듦
cf) 여기에 weather data를 추가로 만들어서 사용한다.
- 하드웨어 중심과 use case 중심으로 추출하면 5가지의 컴포넌트나 오브젝트 시스템을 만들 수 있다. 7개의 상호작용을 weather station에서 전담하고 있는 것을 확인할 수 있다. use case를 상세하게 풀어서 각각의 instrument가 설정되어있고, 멤버 메소드 및 파라미터도 정의된 것을 확인할 수 있다. 날씨 데이터는 weather station을 통해 요청에 대한 응답을 하는 것이니 collect와 summarize를 사용한다.
- 인터렉션과 데이터를 구분하는 것이 철학이다. 하드웨어를 기반으로 클래스를 만들고 각각의 센서에 유니크한 값이 들어간 것을 확인할 수 있다. 정답은 없지만 반복해서 경험하며 노하우를 간접적으로 공부하면 더 잘만들 수 있다.
- 클래스의 세 개가 동일한 메소드를 가지고 있고, 하드웨어 센서를 의미한다는 공통점을 갖고 있다.
- 따라 유전의 법칙(상속)을 사용해 공통적인 부분을 한번에 사용할 수 있다.
- 지금은 다소 정적인 형태이기에 동적인 부분들에 대해서도 해야한다. -> 이를 아키텍쳐 입장에서의 등장인물 확인 및 Sequence model, state machine model, use case 등을 통해 이를 확인할 수 있다.
서브시스템 모델
- 각각의 서브시스템을 정하고 서브 시스템 내에 객체가 존재한다. -> 에그리게이션이나 has relation이라고 할 수 있다.
시퀀스 모델
- 그림에서 등장인물들이 존재하고 이들은 오브젝트로 구현이 된다. 위가 old 시간, 아래가 new 시간이며 주고 받는 것들에 대해 관계도 그리는데 이는 적당히 디테일하게 그림을 그릴 수 있다.
- 사람이 위성을 통해 weather station model에 접근하는 것을 확인할 수 있다.
- sat comms에서 weather station은 시스템 내부에 대한 바운더리가 존재한다. 즉 사용자와 위성에 대한 내용은 그림으로 그려져있지만 우리가 구현할 필요가 없다. 서브시스템 간에 통신을 하는 커뮤니케이션이 존재한다.
- 우리 시스템이 외부 시스템과, 외부 시스템이 내부 시스템과 관게가 있으며 언제 누가 어떤 것을 교류하는지 확인할 수 있다.
- 정적인 관점에 대한 내용을 확보한 후 시퀀스 차트로 동적인 것을 확인할 수 있다.
state diagram
- 하나의 클래스 오브젝트의 상태를 표현한다. 우리의 오브젝트와 클래스가 시간이 지나면서 동적으로 내외부에 맞춰 어떻게 진행되어야하는지를 알려준 것이다.
- 최초의 상태는 셧다운이되고 여러 인풋과 아웃풋, 상태에 따라 동작하는 게 다르다는 것을 확인할 수 있다.
- 정보를 collection하는 것은 주기적으로 한다고 use case description에서 정의했기에 시간에 따라 모으는 것을 확인할 수 있다.
인터페이스
- 시스템간에 혹은 구성요소 간에 주고 받는 것을 인터페이스라고 한다.
- 여기에선 클래스 간의 주고 받는 것을 인터페이스라고 한다.
- 자바에서는 다양한 데이터를 주고받거나 발전해야한다던지 등등의 이유로 확장가능/유지보수를 위해 인터페이스를 주고받는 것만 별도의 클래스로 만드는 경우가 많다.
2. Design patterns
1) 디자인 패턴이란?
- 디자인 패턴은 기존에 특정 분야에 대해 짜온 소프트웨어에 대한 것들을 재사용하는 방법을 의미한다.
- 디자인은 의사결정에 수반될 수 있지만 개발에 매우 밀결합되어 얘기할 수 있다.
- 특정 분야의 소프트웨어를 짤 때는 어떤식으로 접근할지 권장되는 소프트웨어 디자인이 존재한다.
- 따라서 백지상태에서 디자인을 진행하는 것이 아닌 디자인 패턴을 가져올수도 있다.
- 유사한 분야, 같은 산업이지만 같은 코드를 작성하는 경우는 적기에 단순히 코드를 복붙하는 것을 넘어서 가져와서 이를 활용한다.
- 추상화되어있는 디자인을 재사용함으로서 디자인의 안정성 및 시행착오를 줄이기에 기간 단축 등의 장점이 존재할 수 있다.
- 상속이나 다형성, UML 등을 가지고 디자인 패턴을 설명할 수 있다.
2) 패턴
- 특정 분야에 대한 소프트웨어를 짤 때 자주 사용하는 소프트웨어와 관련된 패턴을 사용할 수 있다.
- 많은 패턴이 존재한다.
- 어떤 패턴이든 정형화된 형태로 제공된다.
(1) 패턴 구성요소
- Name
- Problem description
- Solution description: 추상적으로 구성요소의 행동과 관계에 대해 얘기함
- Consequences: 기대되는 장점과 단점
- 동일한 문제에 대해 두 개 이상의 패턴이 있을 수 있고, 장단점을 토대로 취사선택할 수 있다.
- 디자인 마저 재사용가능하다.
3) Observer pattern 예제
(1) Observer pattern이란?
제 3자 시각에서 쳐다보는 패턴
- Name: Observer
- Description: 보여지는 것과 데이터를 분리한다.
- Problem description: 데이터가 다양한 형태로 보여진다.
- Solution description: UML description을 보여준다.
- Consequence: 디스플레이의 성능을 최적화하는데 문제가 발생할 수 있다. (제너릭한 도표를 만들기에)
cf) 소프트웨어를 짤 때 데이터와 액션을 구분하는 경우가 많다.
(2) 각 패턴 이름별 세부적인 내용에 대한 작성
problem description 내용 데이터가 바뀌면 다른 것도 바뀌어야한다. 표현하는 디스플레이는 인터렉션이 된다. 자신의 문제를 확인할 때 사용할 수 있다.
- solution description에서는 상속에 대한 내용, 각 drived class에서 사용하는 내용들에 대해 적혀있다. 우리가 만드는 패턴에는 객체가 등장하고 객체의 관계가 설명된다. state가 있고, 이에 대해 다양한 디스플레이가 가능할 때 subject 클래스에 observer 객체를 가진다. -> has relationship(aggregation)
- 업데이트의 값이 바뀌면 자동으로 state 값을 바꿔서 보여준다.
- 솔루션 위쪽은 정적, 아래는 동적인 부분에 대한 내용을 적어놓은 것이다.
- Consequences는 이로인해 얻어지는 결과나 장단점에 대해 써져있다. -> 일반적인 솔루션을 제공했기에 특정한 분야에 맞게 개발자가 개발해야함
cf) is relationship(유전의 법칙)
- Observer마다 보는 것이 다른 것을 확인할 수 있다.
(3) UML로 그린 Observer pattern
- 서브젝트는 옵저버를 가진 has relationship이 있고 이는 자유롭게 뗄 수 있따.
- Observer는 업데이트가 있고, Subject와 Observer는 concrete하게 유전의 법칙을 사용해 상속한다.
- 서브젝트는 베이스 클래스로서 실제 데이터가 많이 없지만 conctrete는 성적표 내지는 회사 대차대조표와 같은 구체적인 데이터가 존재한다.
4) 디자인 패턴의 종류
- 디자인 패턴은 여럿 존재한다.
- 이 중 유명한 디자인 패턴을 가져와 설명하고자 한다.
- Observer pattern
- Iterator pattern: 반복문을 통해 컬렉션의 엘리먼트에 접근하는 방법
- Facade pattern: 사용자에게 보여지는 것은 변하지 않게 하고, 작은 것만 보여주고 구현은 안보이게 짜는 것
- Decorator pattern: 게임할 때 자주 사용하는 패턴으로 런타임 시 존재하는 객체에 특정 기능을 추가하고 빼는 패턴
3. Implementation issues
소프트웨어 개발 시에 구현단계에서 많이 겪는 이슈
1) 소프트웨어 개발 시에 고려해야하는 이슈
(1) Reuse
- 소프트웨어 상세 디자인, 구현 전에는 반드시 이전에 짠 구성요소가 없는지 고민해야한다.
- 범용
- 1960년대 1990년대만 하더라도 백지 상태에서 코드를 작성했다. 외부 소프트웨어에 대한 자료를 받는 것은 매우 어려웠다. 이에 따라 소프트웨어 재사용이 어려워졌다. 이후 인터넷의 보급, 회사 내에서 네트워크 연결 등을 통해 소프트웨어를 공유하고 아카이브에 저장하며 개발자들이 볼 수 있게 되었다. 이에 따라 재사용이 강조되기 시작했다.
- 재사용을 한다면 개발기간 단축, 안정성/신뢰성을 보장할 수 있다. 이에 따라 전방위적으로 사용된다.
Reuse level
아래 네가지에 대해 Reuse가 가능하다.
- The abstraction level
- The object level
- The component level
- The system level
- 소프트웨어는 재사용이 가능하다. -> 아키텍쳐와 디자인 / 라이브러리 함수 등 / 객체가 모여있는 구성요소 프레임워크 재사용 / configuration 수준만 바꾸는 재사용 가능
i) 재사용 비용
- 재사용을 할 때에도 사람이 필요하고 개발도 진행해야한다.
- 특정 기간에 맞춰 특정 요구사항에 맞춰 정해진 자원으로 개발해야하기에 이를 투자할만큼의 의미가 있는지 확인해야한다.
- 비용적인 측면도 고려해야한다.
- 더불어 대부분의 소프트웨어는 이메일 시스템처럼 사온 뒤 설치하는 방법으로 진행하는 것이 아니라 우리 시스템과 부합하는지 등을 보고 수정해야할수도 있다.
- 기존 시스템과 합칠 때 제대로 합칠 수 있는지, 작업을 해야하는지, 성능저하가 발생하는지 등을 꼼꼼히 따져야한다.
(2) Configuration management
- 소프트웨어가 많은 소스파일로 이루어졌을 때의 버전관리를 어떻게 할지
- 소프트웨어의 개발단계에서변화를 관리한다.
- 범용
- 소프트웨어 개발 시 버전에 대한 관리 -> 우리가 가져오는 소프트웨어가 최신버전인지
- 시스템 통합 -> 소프트웨어를 내보낼 때 항상 최신버전만 가져오지는 않는다. 예를 들어 서버인 경우에는 LTS 버전의 소프트웨어를 받는 것이 중요하다. 소프트웨어의 버전들이 서로 연결되어있기에 무조건 최신 버전이 아니라 이 버전을 맞추는 것이 중요하다.
- 업데이트를 할 때는 각각을 업데이트하고 제대로 돌아가는지 테스트하고 검증을 완료한 뒤 수동으로 릴리즈 한다. 결국 서버는 자동업데이트를 하지 않는다.
- 문제 추적 -> 소프트웨어를 만들 때 발생하는 버그를 관리한다.
- 위의 유기적인 관계가 configuration management이다.
ex) 깃허브
(3) Host-target development
- 특정한 운영체제나 하드웨어에서 사용되는 경우 개발환경과 다를 수 있기에 이를 고려해야한다.
- 임베디드 시스템, 휴대폰 어플리케이션에서 중요하다.
- 동일한 리눅스더라도 크고 작은 메모리 등에 의해 개발환경과 운영이 다를 수 있다.
- 운영과 개발과 관련된 툴, 라이브러리, 컴파일러, 데이터 베이스 등이 나눠져있다.
- 개발환경은 대부분 개발을 하기위한 시스템이 많이 있다.
- 디버깅이나 테스팅을 하기위한 많은 도구가 존재한다.
- IDE도 포함된다.
4. Open source development
오픈소스란 소스코드가 오픈되어있기에 누구나 수정, 재배포, 사용할 수 있도록 한다.
- Free Software Foundation에서 free는 freedom을 의미한다.
- 모든 소프트웨어는 리눅스에 대한 것이다.
- 서버는 모두 리눅스로 쓰이고 자바, 아파치, mysql 등 리눅스를 사용하고 있다.
1) 오픈 소스 두가지 관점
- reuse 관점에서 오픈소스 소프트웨어를 사용하는 것은 합리적으로 보인다.
- 개발 환경을 구축하는 것 또한 오픈 소스를 만들 때 주요한 이슈다.
2) 오픈 소스 비즈니스
- 리눅스 운영체제나 오픈 스택 등에 대해 새로운 기능을 추가하거나 이를 구현하여 내놓아 기술지원이라는 명목으로 돈을 받는다. 이는 소프트웨어가 아니라 그에 대한 지원을 판매한다.
- 오픈소스를 토대로 명성을 쌓으면 연락이 올 수 있다.
3) 오픈소스 라이센스
- 오픈소스는 항상 라이센스가 따라온다.
- 소프트웨어는 이를 만든 개발자에게 권한이 있다. 이를 어느 정도까지 열어주는가를 이해할 필요가 있다.
- 오픈소스를 처음 주장한 GNU가 정한 라이센스 규칙이 GPL
(1) GPL: 대중에게 공개되는 라이센스로 GPL을 활용해서 소프트웨어를 만들면 모두 공개해야한다.
(2) LGPL: 바이너리로 저장되어있고, 이를 손상시키지 않으며 링킹을 토대로 사용할 때 사용하는 입장에서 만든 프로그램은 공개할 필요가 없다.
(3) BSD: 고지의무만 존재하고 판매도 가능한 라이센스
4) 라이센스 관리
- 단순한 소프트웨어에서 시작해도 이후 성장하게되면 라이센스 관리부서도 새로 만들기도 한다.
- 어떤 오픈소스가 들어오는지 알아야하고 이 라이센스를 추적하고, 오픈소스가 유지보수가능한지, 정치적인 문제는 없는지 등을 확인해야한다.
- 사람들에게 오픈소스에 관한 교육도 해야하고, 꼼꼼하게 라이센스 룰을 지켜야한다.
- 오픈소스 문화에 기여해야한다.
요약)
- 소프트웨어를 상세 디자인하고 구현하는 것은 밀결합되어있다.
- 더불어 디자인 단계에서 사용할 수 있는 도구가 매우 많다.
- 시스템 내의 구성요소 추출, 정적/동적인 관계를 UML로 추출했다.
- 재사용이 득인지 실인지 확인해봐야한다.
- configuration management, 개발 환경과 운영 환경이 어떤지 확인해봐야한다.
- 오픈소스 개발은 freedom이기에 라이센스를 지켜야하고 이를 개방하는 좋은 문화에 기여해야한다.
'강의 내용 정리 > 소프트웨어 공학' 카테고리의 다른 글
소프트웨어 공학 (11), Software Evolution (0) | 2022.05.26 |
---|---|
소프트웨어 공학 (10), Software Testing (0) | 2022.05.18 |
소프트웨어 공학 (8), Architectural Design (0) | 2022.04.25 |
소프트웨어 공학 (7), System modeling (0) | 2022.04.25 |
소프트웨어 공학 (6) Requirement Engineering (0) | 2022.04.16 |