Тестируемый дизайн с COM-объектами - PullRequest
1 голос
/ 18 марта 2011

Каков хороший способ разработки для тестирования и расширяемости, когда компонент, используемый для выполнения задачи, может быть компонентом COM или компонентом .NET?Имеет ли смысл полностью обернуть COM-компонент и извлечь интерфейс?Вот простой полностью продуманный интерфейс RCW для COM-компонента, где «abc» - это аббревиатура для производителя компонентов:

public interface IComRobot
{
    void abcInitialize(object o);

    void abcSet(string s, object o);

    void abcBuild();

    void abcExit();
}

Для меня тот факт, что поставщик компонента выбрал префиксвсе методы с чем-то, указывающим на их компанию, несколько раздражают.Проблема в том, что я хочу определить другие компоненты Robot, которые выполняют те же действия, но основная реализация отличается.Создателям роботов было бы совершенно непонятно, когда им нужно реализовывать «abcAnything».

Как мне поступить при создании RobotFactory с простой реализацией, которая работает следующим образом?прикусить пулю и принять префикс abc в моем интерфейсе, что сбивает с толку разработчиков роботов?Должен ли я вызвать зависимость от потребителя робота, чтобы знать, когда он использует робота COM?Ничто из этого не кажется идеальным.Я думаю о дополнительном уровне абстракции (который может решить все, верно?).Примерно так:

public interface IRobot : IDisposable
{
    void Initialize(object o);

    void Set(string s, object o);

    void Build();

    void Exit();
}

public class ComRobotWrapper: IRobot
{
    private readonly IComRobot m_comRobot;

    public ComRobotWrapper()
    {
        m_comRobot = ComRobotFactory.Create();    
    }

    public void Initialize(object o)
    {
        m_comRobot.abcInitialize(o);
    }

    public void Set(string s, object o)
    {
        m_comRobot.abcSet(s, o);
    }

    public void Build()
    {
        m_comRobot.abcBuild();
    }

    public void Exit()
    {
        m_comRobot.abcExit();
    }


    public void Dispose()
    {
        //...RELEASE COM COMPONENT
    }
}

public class ComRobotFactory
{
    public static IComRobot Create()
    {
        return new ComRobot();
    }
}    

Затем я бы изменил и использовал RobotFactory следующим образом:

public class RobotFactory
{
    public static IRobot Create(int i) 
    {
        if (i == 0) return new ComRobotWrapper();
        if (i == 1) return new AdvancedRobot();
        return new SimpleRobot();        
    }
}

public class Tester
{
    // local vars loaded somehow

    public void Test()
    {
        using (IRobot robot = RobotFactory.Create(0))
        {
            robot.Initialize(m_configuration);
            robot.Set(m_model, m_spec);
            robot.Build();
            robot.Exit();
        }
    }
}

Мне интересны мнения об этом подходе.Вы рекомендуете другой подход?Я действительно не хочу брать структуру DI, так что это выходит за рамки.Подводные камни в тестируемости?Я ценю, что вы нашли время подумать над этой длинной проблемой.

1 Ответ

0 голосов
/ 18 марта 2011

Это выглядит на меня. Вы создаете интерфейс, подходящий для вашего домена / приложения, и реализуете его с точки зрения стороннего компонента.

...