'추상화'에 해당되는 글 1건

  1. 2011.05.31 추상 데이터 형(ADT) : 좋은 추상화
2011.05.31 10:28
열강만 봐도 대충 추상화가 먼지 왜 쓰는지 알고있는 개념들이다.
하지만 코딩할때 자주 놓치는 부분이기때문에 정리해서 남김.
- 출처 : code complete


ADT는 데이터와 데이터를 다루는 연산의 집합이다.

ADT가 필요한 예)
글꼴 크기, 폰트 특성( 굴게, 기울임 ) 제어

------------------------------------------------
currentFont currentFont.size = 16; // 일반적인 대입.
  // 라이브러리 루틴 집합 제공.
 currentFont.size = PointsToPixels( 12 ); 
 // 다음과 같은 더 구체적인 이름을 제공할 수도 있다.
 currentFont.sizeInPixels = PointsToPixels( 12 );
// 굵게 설정.
currentFont.attribute = currentFont.attribute or 0x02;
// 좀더 직관적으로 짠다면
currentFont.attribute = currentFont.attribute or BOLD;
// 또는
currentFont.bold = true;
--
------------------------------------------------
 
 
위 코드(ADT를 사용하지 않은 코드)는 정상적인 코드같다.
하지만 문제점이 남아있는데 과연 무엇일까?
1. 유사한 코드들이 프로그램에 퍼지게 된다.
   
    한 클래스 내에 currentFont.sizeInPixels와 currentFont.sizeInPoints 두 멤버를
       모두 가질 수는 없다. 이유는 크기를 변경할때 둘 중 어느것을 사용해야 하는지 
       헷갈리기 때문이다.

2. 폰트에대한 특성들을 클라이언트 쪽에서 직접 제어해야 한다.
       만약 프로그램 전반에 폰트 크기 혹은 굵기 성정 코드들이 퍼저 있다면,
       프로그래머가 직접 그 부분들을 모두 찾아 수정해야한다.
       이렇게 되면 currentFont가 사용될 수 있는 방법을 제한하게 된다.


해결 방안 및 ADT 사용시의 혜택.
1. 세부적인 구현 사항을 감출 수 있다.
       정보은닉.
2. 변경이 전체 프로그램에 영향을 미치지 않는다.
       정보은닉은 데이터의 유형이 변경되어도 전체 프로그램에는 영향을 미치지 않고
       어느 한 곳에서 변경할 수 있음을 의미한다. 이는 메모리가 아닌 외부 저장소에  
       데이터를 저장하거나 폰트 처리 루틴들을 다른 언어로 재작성 하려고 할 때 
       프로 그램의 나머지 부분을 보호해 준다.

3. 인터페이스가 보다 많은 정보를 제공하도록 만들 수 있다.
       위의 첫 줄의 코드의 16이라는 수치는 폰트의 크기는 12 이지만,
       실제 픽셀의 높이는  16이라는 의미이다.
       하지만 여기에서는 16 또는 12라는 수치가 픽셀이나 포인트 단위의 크기가
       될 수 있기 때문에 모호한 값이 되버린다. 
       ADT를 사용하게 되면 유사한 모든 연산들을 하나의 ADT에 모아 포인트나 픽셀 
       형태로 전체 인터페이스를 정의하거나 둘을 분명하게 구별하여 
       혼란을 피할수 있다.

4. 성능을 향상시키기 쉽다.
5. 외관상으로 프로그램이 정확하다는 것을 더 잘 알 수 있다.
       currentFont.attribute나 0x02와 같은 문장을 currentFont.SetBoldOn()과 같은
       루틴을 제공함으로써 사소한 실수를 줄일수 있다. 
       ( or연산대신 and연산을 한다거나, 0x02 대신 0x20을 사용.)
       

6. 프로그램이 더 직관적이게 된다.
       0x02를 BOLD나 다른값으로 바꾸어 이 명령문을 향상 시킬 수는 있지만,
       SetBoldOn()과 같은 루틴 호출의 가독성에는 비할 바가 못된다.

7. 프로그램에 모든 데이터를 넘길 필요가 없다.
      위의 코드들은 currentFont를 직접적으로 변경하거나  폰트를 다루는 루틴에 
      이 값을 전달해야 한다. 하지만 ADT(추상 데이터 형)를 사용한다면 currentFont를
      모든 프로그램에 전달할 필요가 없으며, 전역변수로 변환할 필요도 없다.
      ADT는 currentFont의 데이터를 포함하는 구조체를 갖고 있으며, 데이터는 ADT의 
      일부인 루틴에 의해서만 직접적으로 접근된다. ADT에 속하지 않은 루틴들은 
      이 데이터를 신경 쓸 필요가 없는 것이다.

8. 저 수준 구현 구조체 대신 실세계의 개체들을 다룰 수 있다.
      
이 항목의 말이 어려운데.... 단지 폰트를 다루는 연산들을 배열 접근이나 
      구조체 정의, True와 False 같은 형태가 아닌 폰트의 관점에서 처리할 
      수 있다는 것이다.



ADT 사용 지침.
1. 전형적인 저수준 데이터 형을 저수준 데이터 형이 아닌 ADT로 만들거나 사용하라.
      8. 번과 같은 말이다. 스택, 큐, 리스트 등이 있다. 만약 스택이 직원들을 
      표현 한다면 스택이 아닉 고객으로 취급하라. StackArray라는 것을 
      EmployeeArray등의 이름으로 사용하라는 것같다. 

2. 파일과 같은 일반적인 객체들을 ADT로 취급하라.
      이 부분도 어렵다... 예로 윈도우같은 경우 디스크에 쓰는동안 운영체제는 
      특정한 물리적 주소에 읽기/쓰기 헤드를 위치시키고, 새로운 디스크 섹터 할당과
      외계어같은 오류 코드를 해석한다. 즉, 윈도우는 최상위 추상화 수준과 
      해당 수준에 대한 ADT를 제공하는 것인데, 우리는 윈도우를 사용할때 위와 같은
      복잡한  세부 사항들을 일일히 거치지 않고 알필요도 없고,
      단순하게 '파일'로서 다룰수 있다. 여기서 파일이란 C드라이브등에 존재하는 
      파일, 또는 exe파일 같은 경우 같다. 
      이 책의 말은 우리도 이처럼 '파일'로서 인터페이스를 다룰 수 있게 코딩을 
      하라는 것 같다.

3. 간단한 항목이라도 ADT로 취급하라.
      전구를 클래스로 표현한다. 기능은 단순하게 두가지 켜고 끄기 기능밖에 없다.
      우리들은 이것을 또 다른 루틴(멤버함수)으로 나누는 것이 낭비라고 여길지도 
      모른다. 하지만 이처럼 간단한 연산일지라도 ADT로 취급 함으로써 전구의 켜고 
      끄는 기능들을 코드가 스스로 설명할 수 있도록 도와준다. 또한 변경도 쉬운데
      TurnLightOn() / TurnLightOff() 간에 변화되는 순서를 제한할 수도 있다.

4. ADT가 저장되어 있는 매체에 독립적으로 ADT를 참조하라.
      위에서부터 자주 언급되는 말이다. 루틴의 이름을 잘 지으라는 뜻인데,
      예를 들어 보험료 테이블을 "보험료 파일"로 참조한다면, 
      RateFile.Read() 정도의 코드가 나올 것이다. 
      하지만 위처럼 파일로 참조하는것이 아닌 메모리를 참조하여 읽거나 저장하는
      코드로 변경한다면, 테이블을 파일로 참조하게된
      RateFile.Read()/RateFile.Save()등의 코드들은 틀리게 되고, 파일을 참조
      하는것인지, 메모리를 참조 하는것인지 모호하게 된다.
      즉, 여기서 말하는 독립적으로 참조하라는 말은 rateTable.Read() 혹은 
      rates.Read()등의 클래스 및 접근 루틴 이름을 제공하라는 뜻으로 풀이된다.

좋은 추상화.
 : 좋은 추상 인터페이스를 작성하는 것 자체가 클래스 인터페이스를 생성하는 데 있어서 여러가지 면에서 도움이 된다
신고
Posted by 우엉 여왕님!! ghostkyow

티스토리 툴바