팀 / 회사가 프레임 워크 / 컴파일러 / 도구 세트를 제공 할 때 그들은 이미 경험과 모범 사례를 가지고 있습니다. 그들은 그것을 지침으로 공유합니다. 지침은 권장 사항 입니다. 마음에 들지 않으면 무시할 수 있습니다. 컴파일러는 여전히 코드 를 컴파일 합니다 . 비록 때 로마에 ...
이것이 TypeScript 팀이 I접두사 인터페이스를 권장하지 않는 이유 입니다.
이유 # 1 헝가리 표기법 의 시대 가 지났습니다.
I-prefix-for-interface 서포터의 주요 주장은 접두사가 유형이 인터페이스인지 여부를 즉시 파악하는 데 유용하다는 것입니다. 접두사가 즉시 그루 킹 (피킹)에 도움이된다는 진술은 헝가리 표기법에 호소합니다 . I인터페이스 이름, C클래스, A추상 클래스, s문자열 변수, cconst 변수, i정수 변수의 접두사 . 나는 그러한 이름 장식이 식별자 위로 마우스를 가져 가거나 핫키를 통해 유형 정의로 이동하지 않고도 유형 정보를 제공 할 수 있다는 데 동의합니다. 이 작은 이점은 헝가리 표기법의 단점과 아래에 언급 된 다른 이유 보다 큽니다 . 헝가리어 표기법은 현대 프레임 워크에서 사용되지 않습니다. C #에는I이전 이유 (COM)로 인한 인터페이스의 접두사 (그리고 이것은 C #의 유일한 접두사)입니다. 돌이켜 보면 .NET 설계자 (Brad Abrams) 중 한 명이 prefix를 사용하지 않는I 것이 더 나았을 것이라고 생각합니다 . TypeScript는 COM 레거시가 없으므로 I인터페이스에 대한 접두사 규칙 이 없습니다 .
이유 # 2- I접두사가 캡슐화 원칙을 위반 함
블랙 박스가 있다고 가정 해 봅시다. 해당 상자와 상호 작용할 수있는 유형 참조를 얻을 수 있습니다. 인터페이스인지 클래스인지 신경 쓰지 마십시오. 인터페이스 부분 만 사용하면됩니다. 그것이 무엇인지 (인터페이스, 특정 구현 또는 추상 클래스) 알기를 요구하는 것은 캡슐화의 위반입니다.
예 : 코드에서 API Design Myth : Interface as Contract 를 수정해야한다고 가정 해 보겠습니다 (예 : 인터페이스 삭제 ICar및 Car대신 기본 클래스 사용). 그런 다음 모든 소비자에서 이러한 교체를 수행해야합니다. I-prefix는 블랙 박스 구현 세부 사항에 대한 소비자의 암시 적 종속성을 유발합니다.
이유 # 3 잘못된 이름 지정으로부터 보호
개발자는 이름에 대해 제대로 생각하기가 게으 릅니다. 이름 지정은 컴퓨터 과학에서 두 가지 어려운 것 중 하나입니다 . 개발자가 인터페이스를 추출해야 할 때 I클래스 이름에 문자 를 추가하기 만하면 인터페이스 이름을 얻을 수 있습니다. I인터페이스에 대한 접두사를 허용하지 않으면 개발자가 인터페이스에 적합한 이름을 선택하도록 두뇌에 부담을줍니다. 선택한 이름은 접두사뿐만 아니라 의도의 차이를 강조해야합니다.
추상화 사례 : 인터페이스 및 관련 클래스를 정의 해서는 안됩니다 . 추상화이며 계약에 사용되어야합니다. 구현에는 설명적이고 고유 한 이름이 있어야합니다 (예 : .ICarCarCarSportsCar, SuvCar, HollowCar
좋은 예 : WpfeServerAutosuggestManager implements AutosuggestManager, FileBasedAutosuggestManager implements AutosuggestManager.
나쁜 예 : AutosuggestManager implements IAutosuggestManager .
실습에서 나는 Car implements ICar이름 지정 체계 가있는 별도의 인터페이스에서 클래스의 인터페이스 부분을 생각없이 복제 한 많은 사람들을 만났습니다 . 클래스의 인터페이스 부분을 별도의 인터페이스 유형으로 복제한다고해서 마술처럼 추상화로 변환되지는 않습니다. 여전히 구체적인 구현을 얻을 수 있지만 인터페이스 부분이 중복됩니다. 추상화가 좋지 않은 경우 인터페이스 부분을 복제해도 어쨌든 개선되지 않습니다. 추상화를 추출하는 것은 어려운 작업입니다.
참고 : TS에서는 모의 클래스 나 오버로딩 기능을위한 별도의 인터페이스가 필요하지 않습니다. 클래스의 공용 멤버를 설명하는 별도의 인터페이스를 만드는 대신 TypeScript 유틸리티 유형을 사용할 수 있습니다 . Eg Required<T>는 유형의 모든 공용 멤버로 구성된 유형을 구성합니다 T.
export class SecurityPrincipalStub implements Required<SecurityPrincipal> {
public isFeatureEnabled(entitlement: Entitlement): boolean {
return true;
}
public isWidgetEnabled(kind: string): boolean {
return true;
}
public areAdminToolsEnabled(): boolean {
return true;
}
}
일부 공용 멤버를 제외한 유형을 생성하려면 생략 및 제외 조합을 사용할 수 있습니다 .
I접두사를 사용하는 것이 귀하와 귀하의 팀에게 의미가 있다면 그것을 사용하십시오. 그렇지 않다면 아마도 자바 스타일의SomeThing(인터페이스)SomeThingImpl(구현)을 사용하십시오.