추상화 수준을 결정하는 방법


35

저는 오늘 "청결한 코드" 라는 책을 읽고 있었는데 저자가 함수 당 추상화 수준에 대해 이야기하고있는 단락을 발견했습니다. 그는 일부 코드를 저 / 중급 / 고수준 추상화로 분류했습니다.

내 질문은 추상화 수준을 결정하는 기준은 무엇입니까?

나는이 책에서 그 단락을 인용한다.

함수가 "한 가지"작업을 수행하도록하려면 함수 내 명령문이 모두 동일한 추상화 레벨에 있는지 확인해야합니다. Listing 3-1이이 규칙을 어떻게 위반하는지 쉽게 알 수있다. getHtml ()과 같이 추상화 수준이 매우 높은 개념이 있습니다. 중간 수준의 추상화에있는 다른 것 (예 : String pagePathName = PathParser.render (pagePath); .append ( "\ n")와 같이 여전히 낮은 수준의 다른 것.


답변:


27

저자는 추상화 (계층 적 들여 쓰기 광산)에 대해 설명하는 부분의 "위에서 아래로 코드 읽기"하위 섹션에서 설명합니다.

[...] 우리는 프로그램이 TO 단락 세트 인 것처럼 프로그램을 읽을 수 있기를 원합니다 . 각 단락은 현재 추상화 레벨을 설명하고 다음 TO 레벨에서 다음 TO 단락을 참조 합니다.

  • 설정 및 분류를 포함하기 위해 설정을 포함시킨 다음 테스트 페이지 내용을 포함시킨 다음 분류를 포함합니다.
    • 설정을 포함하기 위해 스위트 인 경우 스위트 설정을 포함시킨 다음 일반 설정을 포함시킵니다.
      • 제품군 설정을 포함하기 위해 "SuiteSetUp"페이지의 상위 계층 구조를 검색하고 해당 페이지의 경로와 함께 include 문을 추가합니다.
        • 부모를 검색하려면 ...

이것과 함께 갈 코드는 다음과 같습니다.

public void CreateTestPage()
{
    IncludeSetups();
    IncludeTestPageContent();
    IncludeTeardowns();
}

public void IncludeSetups()
{
    if(this.IsSuite())
    {
        IncludeSuiteSetup();
    }

    IncludeRegularSetup();
}

public void IncludeSuiteSetup()
{
    var parentPage = FindParentSuitePage();

    // add include statement with the path of the parentPage
}

등등. 함수 계층 구조를 자세히 살펴볼 때마다 추상화 수준을 변경해야합니다. 위의 예에서 IncludeSetups, IncludeTestPageContent그리고 IncludeTeardowns동일한 추상화 레벨에서 모두.

이 책에서 주어진 예에서, 저자는 큰 기능이 매우 구체적이고 한 가지만하는 작은 기능으로 나뉘어 야한다고 제안합니다. 올바르게 수행하면 리팩토링 된 함수는 여기 예제와 유사합니다. 리팩토링 된 버전은이 책의 목록 3-7에 나와 있습니다.


10

이 질문을 이해하려면 추상화가 무엇인지 이해해야합니다. (나는 공식적인 정의를 찾기에는 너무 게으르다. 그래서 나는 쇠약해질 것이라 확신한다. 그러나 여기에서 간다.) 추상화는 복잡한 주제 나 실체를 가지고 대부분의 세부 사항을 숨길 때이다 그 객체의 본질을 여전히 정의하는 기능을 노출시키면서

나는 그 책이 당신에게 준 예가 집이라고 믿습니다. 집을 자세히 살펴보면 보드, 못, 창문, 문으로 구성되어 있음을 알 수 있습니다. 그러나 사진 옆에 집을 그리는 만화는 여전히 집입니다. 많은 세부 사항.

소프트웨어도 마찬가지입니다. 책에서 알 수 있듯이 프로그래밍 할 때마다 소프트웨어를 레이어로 생각해야합니다. 주어진 프로그램은 쉽게 100 개 이상의 레이어를 가질 수 있습니다. 맨 아래에는 CPU에서 실행되는 어셈블리 명령어가있을 수 있습니다.이 명령어는 더 높은 수준에서 디스크 I / O 루틴을 형성하기 위해 결합 될 수 있으며, 더 높은 수준에서는 디스크 I / O로 작업 할 필요가 없습니다. Windows 기능을 사용하여 파일 열기 / 읽기 / 쓰기 / 탐색 / 닫기를 간단히 할 수 있기 때문에 O. 이들은 자신의 응용 프로그램 코드에 도달하기 전에도 모두 추상화됩니다.

코드 내에서 추상화 계층이 계속됩니다. 하위 수준의 문자열 / 네트워크 / 데이터 조작 루틴이있을 수 있습니다. 더 높은 수준에서 이러한 루틴을 사용자 관리, UI 계층, 데이터베이스 액세스를 정의하는 서브 시스템으로 결합 할 수 있습니다. 또 다른 계층은이 서브 시스템을 더 큰 엔터프라이즈 시스템의 일부로 통합하는 서버 구성 요소로 결합 할 수 있습니다.

이들 추상화 계층 각각의 핵심은 각각이 이전 계층 (들)에 의해 노출 된 세부 사항을 숨기고 다음 계층에 의해 소비 될 매우 깨끗한 인터페이스를 제시한다는 것이다. 파일을 열기 위해 개별 섹터를 작성하는 방법이나 처리 할 하드웨어 인터럽트를 몰라도됩니다. 그러나 추상화 계층 체인으로 이동하기 시작하면 Write () 함수 호출에서 하드 드라이브 컨트롤러로 전송되는 정확한 명령까지 추적 할 수 있습니다.

저자가 말한 것은 클래스 나 함수를 정의 할 때 어떤 레이어인지 생각하십시오. 서브 시스템 및 사용자 오브젝트를 관리하는 클래스가있는 경우, 동일한 클래스가 저수준 문자열 조작을 수행하거나 소켓 호출을위한 변수를 포함하지 않아야합니다. 그것은 추상화 계층을 넘어서고 하나의 클래스 / 함수가 하나의 일만하는 것입니다 (SRP-단일 책임 원칙).


2

내 질문은 추상화 수준을 결정하는 기준은 무엇입니까?

추상화 수준은 분명해야합니다. 프로그래밍 언어의 일부가 아닌 문제 영역의 일부인 경우 추상적입니다. "매우 추상적"== "실제하지 않음"== "문제 도메인"보다 명확하지 않습니다. 그리고 "추상적이지 않습니다 == 구체적 == 언어의 일부". 추상화 수준을 결정하는 것은 쉽지 않습니다. 전혀 미묘해서는 안됩니다.

.append("\n")추상이 아닙니다. 문자열에 문자를 넣습니다. 구체적입니다. 초록이 아닙니다.

String pagePathName = PathParser.render(pagePath);문자열을 다룹니다. 구체적인 것. 구체적인 프로그래밍 언어 기능에 부분적으로. 추상적 인 "경로"와 "파서"개념으로 부분적으로 작업.

getHtml(); 추상. "마크 업"및 사소하고 구체적인 언어 기능이 아닌 것들을 다룹니다.

초록 == 언어 기능이 아닙니다.

콘크리트 == 언어 기능.


1
프로그래머가 생성 한 추상화, 즉 프로그래머가 생성 한 추상화를 기술하는 품질로 추상화를 정의하면, 나는 당신의 단어 정의에 동의하는 경향이 있습니다. 그러나 모든 프로그래밍 언어는보다 구체적인 것에 대한 추상화입니다. 프로그래밍 언어의 선택에 따라 어느 정도의 추상화가 시작되는지가 결정됩니다.
Robert Harvey

1

추상화 수준은 간단하다고 생각합니다. 코드 라인이 메소드의 단일 책임을 직접 구현하지 않으면 또 다른 추상화 수준입니다. 예를 들어, 내 메소드 이름이 SaveChangedCustomers ()이고 모든 고객 목록을 매개 변수로 사용하는 경우 단일 책임은 변경된 고객을 목록에 저장하는 것입니다.

foreach(var customer in allCustomers)
{
    if (CustomerIsChanged(customer)
        customer.Save();
}

종종 CustomerIsChanged () 메서드를 호출하는 대신 고객이 foreach 루프에 포함 된 것으로 변경되었는지 확인하는 논리를 찾을 수 있습니다. 고객 기록이 변경되었는지 확인하는 것은이 방법의 책임이 아닙니다! 다른 추상화 수준입니다. 그러나 그 결정을 내리는 논리가 단지 한 줄의 코드라면? 상관 없습니다 !!! 추상화 수준이 다르므로이 방법 외부에 있어야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.