2009-04-19 48 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"); 

我的主要问题是; 你认为哪一个更好的设计?
它是不好的做法隐藏的构造函数赞成静态工厂方法?

我也试图使这个尽可能可测试。 我似乎无法弥补我的想法的唯一原因是因为MyObject类是COM应用程序中另一个对象的包装。

的问题是,这个对象在COM应用程序,它是什么声明方法的任何其他方法之前做可​​以调用声明,但如果我隐藏构造函数,然后添加更多的工作交给申报方法我认为这会使课程的其余部分难以测试,因为我必须先通过Declare方法。

干杯。

回答

1

选项3看起来像你的班级对我来说最干净的API。如果直到调用Declare才能真正使用MyObject,那么将新的和Declare包装到工厂方法中是有道理的,以确保您的类的用户在不首先调用Declare的情况下不尝试使用MyObject。工厂方法也可以帮助保养。

帮助可测试性的一种方法可能是将Declare操作包装在类中的可插入“IDeclarer”接口中。您的生产应用程序将使用调用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; 
    } 
} 
相关问题