Каков хороший способ проектирования для тестирования и расширяемости, когда компонент, используемый для выполнения задачи, может быть либо компонентом 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, так что это выходит за рамки. Являются ли ловушки проверкой? Я ценю, что вы тратите время на рассмотрение этой длительной проблемы.
По-моему, решение «non abc prefix in interface» с «адаптером-реализацией в com-интерфейс» является хорошим решением. Вы решили проблему так, как я бы это сделал. – k3b