추상화에 따라 중요한 단점이 있습니까?


9

SAP (Stable Abstractions Principle)에서이 위키를 읽고있었습니다 .

SAP는 패키지가 안정적 일수록 더 추상적이어야한다고 말합니다. 이것은 패키지가 덜 안정적이고 (변경 될 가능성이 높으면) 더 구체적이어야 함을 의미합니다. 내가 실제로 이해하지 못하는 것은 이것이 사실이어야하는 이유입니다. 확실하게 안정성에 관계없이 모든 경우에 추상화에 의존하고 구체적인 구현을 숨겨야합니까?


제공하는 추상화를 사용 하지 않고 익숙한 것보다 한 단계 낮은 수준에서 모든 것을 자세하게 수행하여 편안한 구성 요소를 사용해보십시오 . 그것은 추상화의 장단점에 대해 꽤 좋은 인상을 줄 것입니다.
Kilian Foth

2
링크 된 기사 및 / 또는 기사의 기반이되는 을 읽었습니까 ?
Jörg W Mittag

1
+1 좋은 질문입니다. 특히 안정성과 추상화의 관계가 즉시 직관적이라고 생각하지 않기 때문입니다. 이 기사의 11 페이지 는 추상 사례의 예가 의미가 있지만 누군가가 구체적인 사례의 명확한 예를 작성할 수 있습니다. 보류 해제 요청.
Mike

이러한 추상화에 대해 어떤 문제 영역을 다루고 있습니까? C2에서 언급 한 바와 같이 : "고객, 직원, 송장, BOM, 제품 등의 실제 도메인 모델링에서 안정적인 추상화를 찾기가 어려울 수 있습니다. 전산 영역- 스택, 큐, 함수, 트리, 프로세스, 스레드, 그래픽 위젯, 보고서, 양식 등이 훨씬 안정적입니다. " "일부 도메인에서는 안정적인 추상화가 이루어지기 어렵습니다." SAP로 해결하려는 문제를 알지 못하면 좋은 대답을하기가 어렵습니다.

@ JörgWMittag와 Mike-그래 나는 기사를 읽었다. "사용할 수없는 패키지가 구체적이어야하는 이유"에 대한 설명이 부족하다고 생각합니다. 이 기사의 13 페이지에서 그는 그래프를 보여 주지만 그래프에서 (1,1)을 피해야하는 이유를 너무 자세하게 설명하지는 않습니까? 기본적으로 불안정하다는 생각은 덜 구심적인 의존성을 의미하며 추상화를 사용할 필요가 없기 때문에? 그렇다면 요구 사항이 변경되어 안정성이 변경되는 경우를 대비하여 추상화를 사용하는 것이 좋지 않습니다.
SteveCallender

답변:


7

패키지를 API로 생각하고, 논문에서 예제를 가져 오고 , 추상 API 와 Reader함께 string Reader.Read()또는 API로 정의를 취 하십시오.Writervoid Writer.Write(string)

그런 다음 Copy메소드 Copier.Copy(Reader, Writer)와 구현 Writer.Write(Reader.Read())및 일부 위생 검사 를 사용하여 클래스를 작성할 수 있습니다 .

지금, 당신은 구체적인 구현을, 예를 들어 FileReader, FileWriter, KeyboardReaderDownloadThingsFromTheInternetReader.

구현을 변경하려면 어떻게해야 FileReader합니까? 문제 없습니다. 클래스를 변경하고 다시 컴파일하십시오.

추상화 정의를 변경하려면 어떻게해야 Reader합니까? 아차, 당신은 그것을 바꿀 수는 없지만, 당신은 또한 변경해야합니다 Copier, FileReader, KeyboardReaderDownloadThingsFromTheInternetReader.

이것이 안정적인 추상화 원리의 근거입니다. 추상화보다 추상화를 덜 안정적으로 만드십시오.


1
나는 당신이 말하는 모든 것에 동의하지만 저자의 안정성과 당신의 정의는 다르다고 생각합니다. 저자는 "안정성은 모듈이 변경 될 가능성을 측정하는 것이 아니라 모듈을 변경하기가 어렵다는 측정"이라고 말합니다. 그래서 내 질문은 더 추상적 인 것이 아니라보다 구체적으로 쉽게 변경되는 패키지에 유리한 이유는 무엇입니까?
SteveCallender

1
@SteveCallender 그것은 미묘한 차이입니다. "안정성"에 대한 저자의 정의는 대부분의 사람들이 "안정성 필요"라고 부르는 것입니다.
Residuum

6

의 때문에 YAGNI .

현재 하나의 하나의 구현이있는 경우 일을 , 왜 여분의 쓸모 층으로 귀찮게? 불필요한 복잡성을 초래할뿐입니다. 더 나쁜 것은 때로는 두 번째 구현이 오는 날에 추상화 사고 를 제공하는 것입니다. 일의 낭비!

또한 스스로에게 묻는 실제 질문은 "추상화에 의존해야합니까?"가 아니라고 생각합니다. 오히려 "모듈화가 필요합니까?". 모듈성이 항상 필요한 것은 아닙니다 (아래 참조).

내가 일하고있는 회사에서 내가 개발 한 일부 소프트웨어는 통신해야하는 일부 하드웨어 장치와 밀접한 관련이 있습니다. 이 장치는 매우 구체적인 목표를 달성하기 위해 개발되었으며 모듈 이외의 모든 것입니다. :-) 첫 생산 장치는 공장 벗어나 어딘가에 설치되면 펌웨어 및 하드웨어 할 수 결코 변화 모두, 지금 .

따라서 소프트웨어의 일부는 절대 진화하지 않을 것입니다. 이 부분들은 하나의 구현 만 존재하고 결코 변하지 않을 것이기 때문에 추상화에 의존 할 필요가 없습니다. 이 코드 부분에 대한 추상화를 선언하면 모든 사람을 혼란스럽게하고 더 많은 시간을 소비합니다 (가치가없는).


1
나는 YAGNI에 동의하는 경향이 있지만, 당신의 모범이 궁금합니다. 다른 장치에서 코드를 반복 하지 않습니까? 같은 회사의 장치에 공통 코드가 없다고 생각하기가 어렵습니다. 또한 펌웨어에서 버그를 수정하지 않을 때 클라이언트는 어떻게 좋아합니까? 당신은 버그입니다 결코있을 건가요 지금 ? 4 개의 다른 구현에서 버그가있는 동일한 코드가있는 경우 공통 모듈에 있지 않은 경우 버그를 4 번 수정해야합니다.
Fuhrmanator

1
@Fuhrmanator 공통 코드는 추상화와 다릅니다. 공통 코드는 헬퍼 메소드 또는 라이브러리를 의미 할 수 있으며 추상화가 필요하지 않습니다.
Eilon

@Fuhrmanator 물론 우리는 라이브러리에 공통 코드를 가지고 있지만 Eilon이 말했듯이 모든 것이 추상화에 의존하지는 않습니다 (그러나 일부는 그렇지 않습니다). 나는 버그가 없다고 말한 적이 없으며 패치 할 수 없다고 말했다 (OP의 질문 범위를 벗어난 이유로).
발견

@Eilon 내 의견은 모듈화가 항상 필요한 것은 아닙니다 (추상화 는 아님 ).
Fuhrmanator

@Spotted 패치 할 수없는 문제가 없습니다. 이것은 꽤 구체적인 예일 뿐이며 대부분의 소프트웨어에서는 일반적이지 않습니다.
Fuhrmanator

6

로버트 마틴이 선택한 ' 안정적 '이라는 단어에 혼란 스러울 것 같습니다 . 혼란이 시작되는 곳은 다음과 같습니다.

이것은 패키지가 덜 안정적이고 (변경 될 가능성이 높으면) 더 구체적이어야 함을 의미합니다.

원본 기사 를 읽으면 (강조 표시)가 표시됩니다.

단어 안정성의 고전적인 정의는 다음과 같습니다 . "쉽게 움직이지 않습니다." 이것이 우리가이 기사에서 사용할 정의입니다. 즉, 안정성은 모듈이 변경 될 가능성의 척도가 아닙니다. 오히려 모듈을 변경하는 데 어려움 이 있음을 측정 한 것입니다 .

분명히 변경하기 어려운 모듈은 덜 휘발성이 될 것입니다. 모듈을 변경하기가 더 어려우며, 즉 더 안정적 일수록 휘발성이 떨어집니다.

나는 (당신과 같은) 안정 의 "우연성"측면, 즉 변화하지 않을 가능성을 생각하는 경향이 있기 때문에 저자의 안정 이라는 단어의 선택에 항상 어려움을 겪고 있습니다 . 어려움 은 해당 모듈을 변경하면 다른 많은 모듈이 손상되어 코드를 수정하는 데 많은 노력이 필요하다는 것을 암시합니다.

마틴은 또한 독립 적이고 책임감 있는 단어를 사용하여 훨씬 더 많은 의미를 전달합니다. 그는 연수회에서 자라나는 자녀의 부모와 자녀가 그들에게 의존하기 때문에 어떻게 책임을 져야하는지에 대한 은유를 사용했습니다. 이혼, 실업, 수감 등은 부모의 변화가 아이들에게 미칠 부정적인 영향의 실제 사례입니다. 따라서 부모는 자녀의 이익을 위해 "안정적"이어야합니다. 그건 그렇고, 이러한 어린이 / 부모의 은유가 반드시 OOP의 상속과 관련이있는 것은 아닙니다!

따라서 "책임"의 정신에 따라 변경하기 어려운 (또는 변경해서는 안 됨 ) 대체 의미를 찾았 습니다 .

  • 의무-다른 클래스는이 클래스에 의존하므로 변경 해서는 안됩니다 .
  • 보라-ibid.
  • 제한됨-이 등급의 의무는 시설 변경을 제한합니다.

따라서 이러한 정의를 명령문에 연결

안정적인 패키지는 더 추상적이 있어야한다

  • 의무적 인 패키지 일수록 더 추상적이어야한다
  • 더 많은 신세 패키지는 더 추상적이 있어야한다
  • 더 많은 제약이 패키지는 더 추상적이 있어야한다

안정적이고 불안정한 혼란스러운 단어를 강조하면서 SAP (Stable Abstractions Principle)를 인용 해 보겠습니다.

최대한 안정적인 패키지는 최대한 추상적 인 것이어야합니다. 불안정한 패키지는 구체적이어야합니다. 패키지의 추상화는 안정성 에 비례해야합니다 .

이 혼란스러운 말없이 그것을 명확히하기 :

시스템의 다른 부분에 최대한 견딜 수있는 패키지는 최대한 추상적이어야합니다. 어려움없이 교체 할 수있는 패키지 구체적이어야합니다. 패키지의 추상화는 수정이 얼마나 어려운지 에 비례해야 합니다 .

TL; DR

질문 제목은 다음과 같이 묻습니다.

추상화에 따라 중요한 단점이 있습니까?

추상화를 올바르게 작성하면 (예 : 코드가 많기 때문에 존재 함) 중대한 단점은 없습니다.


0

이것은 패키지가 덜 안정적이고 (변경 될 가능성이 높으면) 더 구체적이어야 함을 의미합니다. 내가 실제로 이해하지 못하는 것은 이것이 왜 그렇습니까?

추상화는 모든 것이 의존하기 때문에 소프트웨어에서 변경하기 어려운 것들입니다. 패키지가 자주 변경되고 추상화가 제공되는 경우 패키지에 의존하는 사람들은 무언가를 변경할 때 많은 코드를 다시 작성해야합니다. 그러나 불안정한 패키지가 구체적인 구현을 제공하는 경우 변경 후에 훨씬 적은 코드를 다시 작성해야합니다.

따라서 패키지가 자주 바뀌면 추상화가 아닌 콘크리트를 더 잘 제공해야합니다. 그렇지 않으면 ... 도대체 누가 그것을 사용할까요? ;)


0

Martin의 안정성 메트릭과 "안정성"의 의미를 명심하십시오.

Instability = Ce / (Ca+Ce)

또는:

Instability = Outgoing / (Incoming+Outgoing)

즉, 패키지의 모든 종속성이 나가면 패키지는 완전히 불안정한 것으로 간주됩니다. 다른 것을 사용하지만 아무것도 사용하지 않습니다. 이 경우, 그 일이 구체적이되는 것만 의미가 있습니다. 또한 다른 코드는 사용하지 않기 때문에 변경하기 가장 쉬운 종류의 코드가 될 것이므로 해당 코드가 수정되면 다른 코드가 손상되지 않습니다.

한편 하나 이상의 것들에 의해 사용되는 패키지와 완전한 "안정성"의 반대 시나리오가 있지만 소프트웨어가 사용하는 중앙 패키지와 같이 자체적으로 아무것도 사용하지 않는 경우, 즉 Martin 은이 일을해야한다고 말합니다 요약. 이는 또한 SOLI (D)의 DIP 부분 인 Dependency Inversion Principle에 의해 강화되며, 기본적으로 종속성이 하위 및 상위 코드 모두에 대한 추상화를 향해 균일하게 흘러야한다고 명시되어 있습니다.

즉, 종속성은 "안정성"으로 균일하게 흐르고,보다 정확하게는 종속성이 나가는 종속성보다 더 많은 들어오는 종속성이있는 패키지로 흘러야하며, 종속성은 추상화로 흘러야합니다. 그 근거의 요점은 추상화가 한 하위 유형을 다른 하위 유형으로 대체하는 호흡 공간을 제공하여 인터페이스를 구현하는 구체적인 부분이 해당 추상 인터페이스에 대한 의존성을 손상시키지 않고 변경되도록 유연성을 제공한다는 것입니다.

추상화에 따라 중요한 단점이 있습니까?

글쎄, 나는 실제로 적어도 내 도메인에 대해 Martin과 동의하지 않으며, 여기서 "안정적인 이유"와 같이 "안정성"에 대한 새로운 정의를 소개해야합니다. 이 경우 종속성이 안정성을 향하여 흘러야한다고 말하지만 추상 인터페이스가 불안정하면 추상 인터페이스가 도움이되지 않습니다 (마틴의 것이 아니라 반복적으로 변경되는 경향이있는 것처럼 "안정한"에 대한 내 정의에 따라). 개발자가 추상화를 올바르게 얻을 수없고 클라이언트가 소프트웨어를 불완전하거나 비효율적으로 모델링하려는 추상적 인 시도를 렌더링하는 방식으로 반복해서 마음을 바꾸는 경우, 더 이상 종속 인터페이스가 끊어지지 않는 변화로부터 시스템을 보호하기 위해 향상된 추상 인터페이스의 유연성을 활용할 수 없습니다. . 제 개인적인 경우에는 AAA 게임에서 볼 수있는 것과 같은 ECS 엔진을 찾았습니다.가장 구체적 : 미가공 데이터에 대한 것이지만, 그러한 데이터는 매우 안정적입니다 ( "변경 될 필요가 없음"). 나는 종종 미래의 변화를 요구할 확률이 SE 결정을 인도하는 데있어 총 커플 링 대 총 커플 링의 비율보다 더 유용한 척도라는 것을 발견했다.

따라서 DIP를 약간 변경하고 해당 구성 요소가 추상 인터페이스인지 아니면 원시 데이터인지에 관계없이 "종속성이 추가 변경이 필요할 가능성이 가장 낮은 구성 요소를 향해야합니다"라고 말하면됩니다. 나에게 중요한 것은 디자인을 획기적으로 변경해야 할 가능성이 있다는 것입니다. 추상화는 무언가가 추상적이어서 확률을 줄인 경우에만 안정성의 맥락에서 유용합니다.

소프트웨어의 요구 사항을 사전에 예측하고 안정적인 (변하지 않은 것처럼) 추상화를 요구하는 적절한 엔지니어와 고객의 경우가 많은 상황에서, 이러한 추상화는 구체적인 구현을 교환하는 데 필요한 모든 호흡 공간을 제공합니다. 그러나 일부 도메인에서는 추상화가 불안정하고 부적절 할 수 있지만 엔진에 필요한 데이터는 훨씬 쉽게 예측하고 안정적으로 만들 수 있습니다. 따라서 이러한 경우 종속성보다는 추상화가 아닌 데이터를 향한 흐름을 유지 관리하는 관점 (시스템 변경 및 확장의 용이성)에서 실제로 더 유리할 수 있습니다. ECS에서 가장 불안정한 부품 (가장 자주 변경되는 부품)은 일반적으로 시스템에 상주하는 기능입니다 (PhysicsSystem예를 들어, 가장 안정적인 부분 (적어도 변경 될 가능성이 가장 높은 부분)은 MotionComponent모든 시스템이 사용하는 원시 데이터 ( 예 :)로만 구성된 구성 요소입니다 .

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