2011-03-18 3 views
1

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

public interface IComRobot 
{ 
    void abcInitialize(object o); 

    void abcSet(string s, object o); 

    void abcBuild(); 

    void abcExit(); 
} 

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

Как мне создать RobotFactory с простой реализацией, которая работает так?

public class RobotFactory 
{ 
    public static IRobot Create(int i) 
    { 
     // // problem because ComRobot implements IComRobot not IRobot 
     if (i == 0) return new ComRobot(); 
     if (i == 1) return new AdvancedRobot(); 
     return new SimpleRobot();   
    } 
} 

Должен ли я укусить пулю и принять префикс 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, так что это выходит за рамки. Являются ли ловушки проверкой? Я ценю, что вы тратите время на рассмотрение этой длительной проблемы.

+0

По-моему, решение «non abc prefix in interface» с «адаптером-реализацией в com-интерфейс» является хорошим решением. Вы решили проблему так, как я бы это сделал. – k3b

ответ

0

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

Смежные вопросы