2016-08-01 4 views
2

최근 인터페이스로 추상 클래스를 사용하는 몇 가지 예제를 실행했지만 추상 인터페이스에 팩토리 생성자를 추가하여 의미가 "새로 추가"될 수 있습니다. 예를 들어이 서비스의팩토리 생성자가있는 추상 클래스의 이점은 무엇입니까?

abstract class WidgetService { 
    factory WidgetService() = ConcreteWidgetService; 

    Widget getWidget(); 
    void saveWidget(Widget widget); 
} 

class ConcreteWidgetService extends BaseWidgetService implements WidgetService { 

    WidgetService(); 

    Widget getWidget() { 
     // code to get widget here 
    } 

    void saveWidget(Widget widget) { 
     // code to save widget here 
    } 
} 

용도는과 같이 다른 서비스 또는 구성 요소에있을 것입니다 : 선 위의 것 본질적으로 "새로운"업이 샘플에 대한 이해를 바탕으로

WidgetService _service = new WidgetService(); 

WidgetService는 일반적으로 Dart 분석기로부터 경고를 생성하고, 서비스 변수는 실제로 WidgetService의 팩토리 생성자에 ConcreateWidgetService를 할당하여 ConcreateWidgetService의 인스턴스가됩니다.

이 접근법에 이점이 있습니까? 내 OOP 경험에서 필자는 구체적인 유형을 알지 못했을 때 프로그램을 작성하기 위해 추상 클래스/인터페이스를 사용했습니다. 여기에서는 우리가 구체적인 타입을 추상 팩토리 생성자에 즉시 할당하는 것 같습니다. 내 두 번째 질문은이 인스턴스에 왜 모든 ConcreteWidgetService를 여기에서 직접 사용하지 않을 것인가?

답변

2

예를 들어 이점은 제한적이지만 더 복잡한 상황에서는 이점이 더 명확 해집니다.

팩토리 생성자를 사용하면 생성자가 반환하는 항목을보다 세부적으로 제어 할 수 있습니다. 서브 클래스 또는 이미 존재하는 (캐시 된) 인스턴스의 인스턴스를 리턴 할 수 있습니다.

이 생성자 매개 변수에 따라 다른 구체적인 구현을 반환 할 수 있습니다

abstract class WidgetService { 
    WidgetService _cached; 
    factory WidgetService(String type) { 
     switch(type) { 
     case 'a': return new ConcreteWidgetServiceA(); 
     case 'b': return new ConcreteWidgetServiceA(); 
     default: return _cached ??= new DummyWidgetServiceA(); 
     } 
    } 
    Widget getWidget(); 
    void saveWidget(Widget widget); 
} 

귀하의 예는 준비는보다 유연한 접근 방식에 결국 확장 될 것으로 보인다.

2

다트에서는 모든 클래스도 자동으로 인터페이스됩니다. 실제로 '클래스를 만드는 것'이기 때문에 '인터페이스'라는 인스턴스를 만드는 것에 이상한 것은 없습니다.

일부 추상 클래스의 목적은 인터페이스를 정의하는 것이지만 인터페이스 자체를 '기본 구현'으로 반환하는 팩토리 생성자가 있습니다. 예를 들어

:

void main() { 
    var v = new Map(); 
    print(v.runtimeType); 
} 

인쇄 : _InternalLinkedHashMap-Map의 (현재) 디폴트의 구현.

코어 라이브러리 사용자는 Map 인스턴스를 만들고 실제로 구현 된 내용을 몰라도 해당 인스턴스를 사용할 수 있습니다. 라이브러리 작성자는 다른 사람의 코드를 위반하지 않고 구현을 변경할 수 있습니다.

물론 다른 클래스도 Map을 구현할 수 있습니다.

코드 샘플의 경우 WidgetService _service = new WidgetService();은 분석기 경고를 생성하지 않습니다. 이 example on DartPad을보십시오 (샘플에 몇 가지 오류가 수정되었습니다). 대신

factory WidgetService() = ConcreteWidgetService; 

:

나는 처음에 혼란스러워했다

factory WidgetService() => new ConcreteWidgetService(); 

그러나 작동하는 것 같다.