Дизайн класса: публичный конструктор или приватный со статической фабрикой и COM-объектом - PullRequest
2 голосов
/ 20 апреля 2009

У меня небольшая проблема с дизайном класса. Я опишу три модели, которые я рассматриваю.

Пример 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, что и делает метод объявления *1038*, прежде чем будет вызван любой другой метод, но если я спрячу конструктор, а затем добавлю больше работы к методу Declare, я думаю, что это затруднит тестирование остальной части класса, потому что мне сначала нужно пройти через метод Declare.

Приветствие.

1 Ответ

1 голос
/ 20 апреля 2009

Вариант 3 кажется мне самым чистым API для вашего класса. Если вы не можете использовать MyObject до тех пор, пока не будет вызван метод Declare, для меня будет иметь смысл заключить метод new и Declare в фабричный метод, чтобы убедиться, что пользователи вашего класса не пытаются использовать MyObject без предварительного вызова Declare. Заводские методы также могут помочь с техническим обслуживанием в будущем.

Одним из способов помочь с тестируемостью может быть обертывание операции Declare в подключаемый интерфейс «IDeclarer» в классе. Ваше производственное приложение будет использовать реализацию IDeclarer, которая вызывает приложение COM, в то время как ваш тестовый код может включать фиктивный 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...