소프트웨어 공부/프로그래밍

[프로그래밍] 루틴의 특성

야곰야곰+책벌레 2021. 8. 25. 10:58
728x90
반응형
루틴이란 하나의 단일 목적에 도달하기 위한 개별적인 함수나 프로시저를 말한다.

 

루틴 작성의 이유


복잡성의 감소

  루틴 작성의 가장 중요한 이유는 프로그램의 복잡성을 줄이는 데 있다. 정보를 숨기는 루틴을 만들면 그것에 관해 생각할 필요도 없다. 자세한 세부 사항은 잊고 내부적 작업을 알지 못해도 루틴을 사용할 수 있다. 루틴의 추상화 기능 없이 복잡한 프로그램을 머리만으로 관리하는 것은 불가능하다.

코드의 중복을 피함

  의심할 것도 없이 가장 널리 알려진 이유는 코드 중복을 피하는 것이다. 2개의 루틴 안에 유사한 코드를 만들면 그것들이 분리되어 있어 에러를 내포할 가능성이 크다. 양쪽 루틴에서 중복되는 코드가 있다면 공동 코드화 시킨다. 그러고 나서 양쪽의 코드 부분에 새 루틴을 사용한다. 공간 절약은 물론 하나의 코드만 관리하면 되므로 신뢰성이 높아진다.

변경 시의 영향 제한

  변경으로 영향을 받을 영역들을 분리시킨다. 그래야 변경의 영향이 하나의 루틴 혹은 몇 개의 루틴 영역으로 제한할 수 있다. 이런 설계 방식은 대부분 변경을 매우 쉽게 해 준다.

순서의 은폐

  진행 과정에서 발생되는 일들의 순서를 은폐하는 것은 좋은 생각이다. 예를 들면, 프로그램이 사용자로부터 데이터를 얻고 파일로부터 보조 데이터를 얻는다면 사용자 데이터를 가진 루틴이나 파일 데이터를 가진 루틴 어느 것도 먼저 수행되는 다른 루틴에 의존해서는 안된다.

수행의 개선

  여러 곳보다는 한 곳에서 코드를 최적화시키는 것이 좋다. 한 장소에 코드를 가지는 것은 좀 더 효율적인 알고리즘으로 혹은 어셈블러와 같은 좀 더 신속하고 어려운 언어를 가지고 코드 작성을 새로 하는데 실용적이다.

 

제어의 중심점 포인트 만들기

  중앙 집중식 제어는 정보를 은폐하는 것과 유사하다.

데이터 구조의 은폐

  데이터 구조의 세부 구현을 숨김으로써 대부분의 프로그램이 컴퓨터 과학 구조를 조종하는 복잡한 세부 사항에 관해 걱정할 필요가 없고 문제를 다룰 때 방법에 대해서만 생각하면 된다. 세부 구현을 숨기는 루틴은 프로그램의 복잡성을 줄이고 데이터 구조를 중앙에 집중시켜 데이터 구조에서 생기는 오류 발생을 줄일 수 있다. 또한 프로그램 전반을 수정하지 않고도 구조를 변경하기 쉽다.

글로벌 데이터의 은폐

  액세스 루틴이 글로벌 데이터를 사용하게 되면 프로그램을 변경하지 않고 데이터 구조를 변경할 수 있고 데이터 액세스를 모니터 할 수 있게 된다.

포인터 연산의 은폐

  포인터 연산은 판독하기 어렵고 에러를 내기 쉬운 경향이 있다. 루틴에서 그것들을 분리시킴으로써 포인터를 다루는 것보다는 연산에 주의를 집중할 수 있다.

코드의 재사용 증진

  모듈화 된 루틴의 코드는 루틴 안에 그냥 사용된 같은 코드보다는 다른 프로그램 안에 재사용하는 것이 더 쉽다.

프로그램 시리즈를 위한 계획

  프로그램을 변경할 계획이 있다면 그 자체를 루틴으로 작성함으로써 변경하고자 하는 부분을 분리시키는 것이 좋다.

판독 가능한 코드 작성

  잘 명명된 루틴 안에 코드를 작성하는 것은 그 기능을 설명하는 최상의 방법 중 하나다.

이식성의 개선

  루틴을 사용하면 이식 불가능한 기능과 미래의 이식 가능한 일을 분명히 할 수 있다. 이식이 불가능한 기능에는 표준이 아닌 언어 기능, 하드웨어 종속, 운영 체계의 종속성이 해당된다.

복잡한 연산 분리

  복잡한 운용, 복잡한 알고리즘, 커뮤니케이션 프로토콜, 까다로운 boolean 테스트, 복잡한 데이터의 운용 등등에서는 에러가 발생하기 쉽다. 만일 오류가 발생되면 그것이 루틴 안에 포함된 사실을 발견하기가 어렵지 않을 것이다. 이 에러는 다른 코드에 영향을 주지 않으므로 오직 한 루틴에서만 수정하면 된다.

언어의 비표준 기능 분리

 

좋은 루틴명


  루틴의 좋은 이름은 그 루틴이 하는 모든 것을 명백히 나타내야 한다.

 

  • 프로시저의 이름으로 목적어가 수반되는 강한 의미의 동사를 사용.
    PrintReport(), CalcMonthlyRevenues(), CheckOrderInfo(), RepaginateDocument()
    Report.Print(), OrderInfo.Check(), MonthlyRevenues.Calc()
  • 함수 이름으로는 복귀 값에 대한 설명을 사용
    cos(), NextCustomerId(), PrinterReady(), CurrentPenColor()
  • 의미가 어렵거나 분명하지 않은 동사들을 피함
    HandleOutput() → FormatAndPrintOutput() : 루틴이 무엇을 하는지 정확히 파악할 수 있어야 함.
  • 루틴이 하는 모든 일을 설명
  • 루틴명은 필요에 따라 가능하면 길게
  • 일반 명령을 위한 규약이 제정

 

소결합(Loose Coupling)


  결합의 정도는 두 개의 루틴 간의 연결되어 있는 강도를 설명한다. 루틴 간의 좋은 결합은 하나의 루틴이 다른 루틴에 의해 쉽게 불려질 수 있도록 느슨해야 한다. 거의 다른 루틴에 의존하지 않는 루틴들을 작성하도록 시도해야 한다.

 

결합의 기준

  다음은 루틴 간의 결합을 평가하는 기준이다.

  • 크기 : 크기는 루틴 간의 연결 수를 말한다. 결합에 있어서 작은 것이 좋다. 왜냐면 적은 인터페이스를 통해 루틴이 다른 루틴들을 연결시키는 작업을 줄일 수 있기 때문이다.
  • 친밀성 : 친밀성은 두 개의 루틴 간의 연결의 직접성을 말한다. 가장 친밀한 연결은 매개변수를 통한 연결이며 가장 친밀도가 떨어지는 연결은 데이터베이스의 레코드나 파일을 가지고 작업하는 루틴이다.
  • 가시성 : 가시성은 두 개의 루틴 간의 연결의 눈에 띄는 정도를 가리킨다. 매개 변수 리스트 안으로 데이터를 보내는 것은 확실하게 연결시키기 위함이다. 다른 루틴도 사용하는 글로벌 데이터를 수정하는 것은 루틴 사이의 연결이 잘못될 수도 있으므로 좋지 않다.
  • 융통성 : 융통성은 루틴 간의 연결을 얼마나 쉽게 변경할 수 있는가를 알려준다.

  더 쉽게 루틴을 불러낼수록 더 느슨하게 결합되어 있으며 이것은 융통성이 있고 유지 보수에 좋다.

 

결합의 단계

  • 단순한 데이터 결합 : 만일 두 개의 루틴 사이에 전달된 모든 데이터들이 구조를 갖지 않고 매개 변수 리스트를 통해 전달되었다면 두 개의 루틴은 단순한 데이터로 결합되었다고 할 수 있으며 이를 "정규 결합"이라 부르곤 하는데 가장 좋은 방법이라 할 수 있다.
  • 데이터 구조 결합 : 만일 두 루틴 사이에 전달된 데이터가 구조적이고 매개 변수 리스트를 통해 전달되었다면 두 개의 루틴은 데이터 구조로 결합되었다고 한다. 이는 때때로 "스탬프 결합"이라고 불린다.
  • 제어 결합 : 만일 하나의 루틴이 두 번째 루틴이 해야 할 일을 지시하는 방법으로 다른 루틴 데이터를 전달한다면 두 개의 루틴은 제어 결합되어 있다고 할 수 있다.
  • 글로벌 데이터 결합 : 두 개의 루틴이 동일한 글로벌 데이터를 사용하게 한다면 이 두 루틴은 글로벌 데이터 결합되어 있다고 말할 수 있다. 이는 또한 "일반적 결합" 혹은 "글로벌 결합"이라고 불린다. 단지 데이터를 읽는 용도만 사용한다면 문제가 없을 것이나 루틴 간 연결이 친밀하지 않기 때문에 바람직하지 않다. 또한 "정보 유실"을 발생시킬 수 있다.
  • 병리적 결합 : 하나의 루틴이 또 다른 루틴 안의 코드를 사용하거나 다른 루틴 안에 사용된 지역 데이터를 변경한다면 이 두 개의 루틴은 병리적으로 결합되었다 한다. 이는 또한 "내용 결합"이라 부른다. 이런 종류의 결합은 크기, 친밀도, 가시성, 융통성의 모든 영역에 적합하지 않기 때문에 수용 불가능하다.
728x90
반응형