2009-04-19 7 views
2

클래스 디자인 문제가 조금 있습니다. 제가 생각하고있는 세 가지 패턴을 개략적으로 설명하겠습니다.클래스 디자인 : 공용 생성자 또는 정적 팩토리 및 COM 객체가 포함 된 개인

예 1

Class MyObject 
{ 
    public MyObject(IWrapper wrapper,string name) 
    {//set properties.} 

    public Void Declare() 
    { 
     //Some COM stuff with IWrapper 
    } 
} 

사용 :

MyObject testobj = new MyObject(fakewrapper,"test"); 
testobj.Declare(); 

예 2

Class MyObject 
{ 
    public MyObject(IWrapper wrapper,string name) 
    { //set properties.} 

    public MyObject Declare() 
    { 
     //Some COM stuff with IWrapper 
     return this; 
    } 
} 

사용 :

MyObject testobj = new MyObject(fakewrapper,"Test"); 
testobj = testobj.Declare(); 

예 3 : 사용하여 개인 생성자

Class MyObject 
{ 
    private MyObject(IWrapper wrapper,string name) 
    {//set properties.} 

    public static MyObject Declare(IWrapper wrapper,string name) 
    { 
     //Some COM stuff with IWrapper 
     return new MyObject(wrapper,name); 
    } 
} 

사용 :

MyObject testobj = MyObject.Declare(fakewrapper,"Test"); 

내 주요 질문이 있습니다; 당신은 어느 쪽이 더 좋은 디자인이라고 생각합니까?
static 팩토리 메서드를 사용하여 생성자를 숨기는 것이 바람직하지 않습니까?

가능한 한 테스트 할 수 있도록 노력 중입니다. MyObject 클래스가 COM 응용 프로그램의 다른 개체를 감싸는 래퍼이기 때문에 마음을 가릴 수없는 유일한 이유가 있습니다.

문제는 이 다른 모든 메서드를 호출하기 전에 메서드가 수행하고있는 COM 응용 프로그램에서 선언되어야하지만, 생성자를 숨긴 다음 Declare에 더 많은 작업을 추가하면 문제가 발생한다는 것입니다. 방법 먼저 Declare 메서드를 먼저 수행해야하기 때문에 나머지 클래스를 테스트하기가 어렵다고 생각합니다.

건배.

답변

1

옵션 3은 나를위한 가장 깨끗한 API처럼 보입니다. Declare가 호출 될 때까지 MyObject를 실제로 사용할 수 없다면 new 클래스와 Declare를 팩토리 메서드로 랩핑하여 클래스 사용자가 먼저 Declare를 호출하지 않고 MyObject를 사용하지 않도록해야합니다. 공장 방법은 유지 보수를 도와 줄 수 있습니다.

테스트 가능성을 돕는 한 가지 방법은 클래스의 플러그 가능한 "IDeclarer"인터페이스에서 Declare 작업을 래핑하는 것일 수 있습니다. 프로덕션 응용 프로그램은 COM 응용 프로그램을 호출하는 IDeclarer 구현을 사용하지만 테스트 코드는 모의 IDeclarer를 연결할 수 있습니다. 아마 이것과 같은 것입니다 (아마도 이것을 조정해야 할 것입니다 ...) :

class MyObject 
{ 
    public IDeclarer Declarer { get; set; } 

    private MyObject(IWrapper wrapper,string name) 
    { 
     // set properties 
    } 

    public static MyObject Declare(IWrapper wrapper,string name) 
    { 
     //Some COM stuff with IWrapper 
     MyObject newMyObject = new MyObject(wrapper,name); 
     return Declarer.Declare(newMyObject); 
    } 
} 

public interface IDeclarer 
{ 
    MyObject Declare(MyObject obj); 
} 

public class ComDeclarer : IDeclarer 
{ 
    public MyObject Declare(MyObject obj) 
    { 
     // do COM work 
     return comObj; 
    } 
} 

public class TestDeclarer : IDeclarer 
{ 
    public MyObject Declare(MyObject obj) 
    { 
     // do nothing... or whatever 
     return testObj; 
    } 
}