본문 바로가기
컴퓨터공학/기초

소프트웨어 공학

by 하이방가루 2022. 8. 18.
728x90
반응형

이 글은 Crash Course의 Computer Science를 보고 정리한 글입니다.

Microsoft Ofiice는 대략 4천만 줄의 코드를 가지고 있다. 그것은 혼자서 알아내고 쓰기에는 너무 크다. 이러한 거대한 규모의 프로그램을 만들기 위해서 프로그래머들은 일련의 도구와 실습을 사용한다. 종합하면, 이것들이 소프트웨어 공학(Software Engineering)의 한 분야를 형성한다. 이것은 엔지니어인 Margaret Hamilton이 만든 용어이다. 그녀는 NASA가 아폴로 미션을 수행하던 중 문제가 발생하지 않도록 도운 사람이었다. 그녀는 "이것은 신경치료와도 같아요. 당신은 끝까지 기다렸지만, 그것은 미리 할 수 있었던 일이 아니었습니다. 그것은 예방용 건강관리와 같지만 그것은 예방용 소프트웨어입니다."라고 말했다.

 

이전에 말했듯 큰 프로그램을 작은 함수들로 쪼개면 사람들은 동시에 일할 수 있다. 그들은 전체에 대해 걱정할 필요가 없다. 단지 그들이 작업하고 있는 함수에만 집중하면 된다. 그러나, 코드를 함수로 묶는 것 만으로는 충분하지 않았다. Microsoft Office는 아마 수십만 개의 함수를 가지고 있을 것이다. 그것은 4천만 줄의 코드를 다루는 것보단 낫지만, 여전히 한 사람이나 팀이 관리할 수 있는 것으로는 너무 많다.

 

해결책은 함수를 계층구조(Hierarchies)로 패키지화하여 관련된 코드를 객체(Object)로 모으는 것이다. 예를 들면, 자동차의 소프트웨어에는 크루즈 컨트롤과 관련된 여러 기능을 가지고 있다. 속도 설정, 속도 올리기, 속도 내리기, 크루즈 컨트롤을 정지하는 것과 같은 기능들을 가지고 있을 것이다. 모두 관련되어 있으므로 이들을 통합된 크루즈 컨트롤 객체로 포장할 수 있다. 그러나 이게 끝이 아니다. 크루즈 컨트롤은 엔젠 소프트웨어의 한 부분일 뿐이다. 점화 플러그 제어, 연료 펌프 및 라디에이터를 제어하는 함수 세트도 있을 것이다. 그래서 부모 엔진 객체를 만들어 자식 객체들을 포함시킬 수 있다. 또한, 자식 객체 외에도 엔진 그 자체의 함수를 가질 수 있다. 자체 함수의 예로는 엔진을 멈추거나 작동시킬 수 있는 함수가 있을 것이다. 또한 차가 몇 마일이나 주행했는지를 나타내는 자체 변수도 있다.

일반적으로, 객체는 이렇게 다른 객체와 함수 및 변수를 포함할 수 있다. 물론 엔진은 단지 자동차의 한 부분일 뿐이다. 변속기, 바퀴, 문, 창문 등도 자동차의 부분이다.

이제 프로그래머로서 만약 크루즈 컨트롤을 설정하고 싶다면, 객체를 조정하여 가장 바깥쪽 객체에서 더 깊숙이 중첩된 객체 계층까지 탐색한다. 결국 조정하고 싶은 기능에 도달해서 Car.Engine.CruiseControl.setCruiseSpeed(55)와 같이 속도를 설정할 수 있다. 이와 같이 기능 단위를 중첩된 객체로 묶는 것을 객체 지향 프로그래밍(Object Oriented Programming)이라고 한다. 이전에 트랜지스터 회로를 상위 수준의 논리게이트로 묶듯이 고차원 구성 요소에 하위 수준의 세부 정보를 캡슐화하여 복잡성을 숨기는 것이다. 그저 소프트웨어로 똑같은 일을 할 뿐이다.

 

자동차 소프트웨어와 같이 큰 프로그램을 기능적 단위로 분해하면 팀으로 작업하기에 좋다. 한 팀이 크루즈 제어 시스템에 책임이 있고 팀원 중 한 프로그래머는 몇 가지의 기능을 다룰 것이다. 크루즈 컨트롤에서 코드는 엔진 소프트웨어의 다른 부분에서 함수를 사용하여 차를 일정 속도로 유지해야 한다. 이 코드는 크루즈 컨트롤팀의 책임 부분이 아니다. 그것은 다른 팀의 코드일 것이다. 크루즈 컨트롤팀이 그 코드를 작성하지 않았기 때문에 각 코드의 기능이 무엇인지, 잘 정의된 API(Application Programming Interface; 응용 프로그램 인터페이스)에 대한 문서(Documentation)를 필요로 할 것이다. 

 

API는 프로그래머가 코드의 다양한 부분에서 공동 작업하는 방식이라고 할 수 있다. 예를 들어, 점화 제어 객체에서는 엔진의 RPM을 설정하는 기능과 점화 플러그 전압을 확인하고, 개별 스파크 플러그를 발사하는 기능이 있을 수 있다. 크루즈 컨트롤 팀은 모터의 RPM을 설정하는 함수를 호출해야 할 것이다. 그러나 크루즈 컨트롤 팀은 어떻게 점화 시스템이 작동하는지에 대해 많이 알 필요가 없다. 개별 점화 플러그를 작동하는 함수를 직접 호출할 것은 아니기 때문이다. 잘못하면 엔진이 폭발할 수도 있을 것이다.

 

API를 사용하면 적절한 함수와 데이터에 대한 적절한 접근 권한을 얻을 수 있다. 객체 지향 프로그래밍 언어는 함수의 공개(Public) 혹은 비공개(Private) 사용 여부를 지정할 수 있게 하여 이를 수행한다. 함수가 비공개로 표시된 경우, 해당 객체 내부의 함수만 호출할 수 있다는 것을 의미한다.

이렇게 복잡성을 숨기고 선택적으로 그것을 드러낼 수 있는 능력은 객체 지향 프로그래밍의 본질이다. 그리고 그것은 크고 복잡한 프로그램을 만드는 강력하고 대중적인 방법이다.

대부분의 게임은 객체 지향 프로그래밍 언어인 C++, C# 또는 Objective-C와 같은 것들을 사용하여 작성된다. 그리고 Python과 Java 또한 객체 지향 언어이다.

 

컴파일되기 전에 코드는 텍스트일 뿐이다. 이전에 얘기했듯이 코드는 메모장이나 워드프로세서에서 작성할 수 있다. 하지만 일반적으로, 요즘 소프트웨어 개발자들은 프로그램을 쓰기 위한 특수 목적의 응용 프로그램을 사용한다. 그것은 코드를 쓰고, 조직하고, 편집하고 테스트할 수 있는 많은 유용한 도구들을 통합하는 프로그램으로 통합개발환경(Integrated Development Environments; IDE)이라고 불린다. 모든 IDE는 작문을 위한 텍스트 편집기를 제공하며, 가독성을 향상하는 자동 컬러 코딩과 같이 유용한 기능을 포함한다. 코드의 맞춤법 검사와 같이, 입력하는 동안 구문 오류가 있는지 대부분 확인한다. 큰 프로그램에는 많은 개별 소스가 포함되어 있어 IDE를 사용하면 프로그래머가 모든 것을 구성하고 효율적으로 탐색할 수 있다. 또한 IDE에 내장된 기능은 코드를 컴파일하고 실행한다. 만약 프로그램이 중단되면, 여전히 진행 중인 작업이므로 IDE는 중단이 일어난 코드 줄로 되돌릴 수 있으며 버그를 추적하고 수정하는 데 도움이 되는 추가 정보를 제공하는 디버깅이라는 프로세스를 지원한다.

대부분의 프로그래머가 가들의 시간을 새로운 코드를 작성하는 데에 쓰지 않고 테스트와 디버깅을 하는데에 70~80%를 소비하는 데 쓰기 때문에 이것은 매우 중요하다.

IDE에 포한된 좋은 도구는 프로그래머가 오류를 방지하고 찾을 수 있도록 도움을 줄 때 매우 유용하다.

 

코딩 및 디버깅 외에도 다른 프로그래머의 업무에서 중요한 부분은 그들의 코드를 문서화(Documenting)하는 것이다. 이것은 Read Me라고 부르는 독립된 실행파일에서 수행할 수 있다. 다른 프로그래머에게 실행하기 전에 도움말 파일을 읽도록 지시한다.

주석을 사용하여 코드 자체에서 바로 쓸 수도 있다. 주석은 코드가 컴파일될 때 프로그램이 무시하도록 특별히 표기된 문장이다. 주석은 프로그래머가 소스 코드에서 무엇이 무엇인지 알아낼 수 있도록 하기 위해서만 존재한다.

좋은 문서는 프로그래머가 잠시 보지 못했던 코드를 재방문할 때도 도움이 되지만, 새로운 프로그래머에게도 문서는 중요하다.

누군가가 아무런 증거가 없고, 주석 처리되지 않은 코드를 컴퓨터에 투하시킨다면 그것만큼 최악이 경우는 없을 것이다. 이럴 경우 코드가 무엇인지 이해하기 위해 한 줄씩 코드를 해석해야 할 것이다.

 

설명서는 또한 코드 재사용(Code Reuse)을 촉진한다. 따라서 프로그래머는 끊임없이 똑같은 일을 계속해서 반복해서 쓰는 대신, 그들이 해야 할 일을 할 수 있는 다른 사람의 코드를 색출해낸다. 그리고 설명서 덕분에, 코드를 읽을 필요 없이 프로그램에서 작업할 수 있다.

 

IDE 외에도 큰 팀이 대형 코딩 프로젝트에서 공동 작업하는 것을 돕는 또 다른 중요한 소프트웨어를 소스 관리(Source Control), 버전 관리 또는 리비전 컨트롤이라고도 부른다. 대부분의 경우, Apple 또는 Microsoft와 같이 큰 소프트웨어 회사에서 프로젝트를 위한 코드는 중앙 집중화된 서버, 코드 저장소(Code Repository)라고 불리는 곳에 저장된다. 프로그래머가 코드 부분 작업을 원할 때 코드의 내용을 확인할 수 있다. 이것은 IDE 안에서 바로 수행할 수도 있다. 개인용 컴퓨터에서 원하는 모든 코드를 수정하고, 새로운 기능을 추가하고, 작동하는지 테스트할 수 있다.

프로그래머가 변경 사항을 확인하고, 설명되지 않는 부분이 없다고 확신하면 코드를 커미팅(Committing)이라고 하는 저장소로 다시 체크하여 다른 모든 사람들이 사용할 수 있게 한다. 한 조각의 코드가 확인되고, 업데이트되거나 수정될 것으로 예상되는 동안 프로그래머는 그것을 내버려 둔다. 이것은 이상한 갈등과 중복된 작업을 방지한다. 이 방법으로 수백 명의 프로그래머가 동시에 코드를 체크 인 및 체크 아웃을 하고, 반복적으로 거대한 시스템을 구축한다.

코드가 충돌하여 혼란을 일으키고 시간을 낭비할 수 있기 때문에, 서버에 저장된 코드의 마스터 버전은 항상 오류 없이 컴파일하고 최소한의 버그로 실행되어야 한다. 하지만 버그는 언제나 생기기 때문에 소스 관리 소프트웨어는 모든 변경 사항을 추적하고, 만약 버그가 발견되면 전체 코드 또는 하나의 코드 조각을 초기의 또는 안정적인 버전으로 되돌릴 수 있다(Rolled Back). 또한 각 변경 사항을 누가 작성했는지 추적하므로 동료들이 불쾌감을 줄 수도 있다. 그럴 때는, 문제가 있는 사람에게 도움이 되거나 격려할 수 있는 이메일을 보낼 수도 있다.

 

디버깅은 코드 작성과 함께 진행되며, 개인이나 소규모 팀이 가장 자주 하는 일이다. 디버깅의 큰 그림 버전은 품질 보증 테스트(Quality Assurance; QA)이다. 이곳은 팀이 엄격하게 소프트웨어를 테스트하는 곳이다. 실수를 불러일으킬 수도 있는 예기치 않은 상황을 만들어내어 소프트웨어를 작동시킬 수 있다. 기본적으로 이들은 버그를 이끌어낸다. 모든 주름을 제거하는 것은 엄청난 노력이지만, 소프트웨어가 출하되기 전에 상상할 수 있는 많은 상황에서 여러 사용자들을 대상으로 소프트웨어가 작동하는지 확인하는 데 중요하다.

베타 소프트웨어는 대부분 완성된 소프트웨어 버전이다. 하지만 100% 완벽하게 테스트한 것은 아니다. 회사는 종종 문제를 식별할 수 있도록 베타 버전을 공개한다. 그것은 기본적으로 무료 품질 보증을 받는 것과 같다. 베타 이전의 버전인 알파버전은 일반적으로 매우 거칠고 버그가 있으며, 내부적으로만 테스트된다.

728x90
반응형

'컴퓨터공학 > 기초' 카테고리의 다른 글

운영 체제 OS  (0) 2022.08.25
집적 회로와 무어의 법칙  (0) 2022.08.20
앨런 튜링 Alan Mathison Turing  (0) 2022.08.15
자료구조  (0) 2022.08.09
알고리즘 소개  (0) 2022.08.08

댓글