#c# #design-patterns #refactoring
#c# #шаблоны проектирования #рефакторинг
Вопрос:
У меня ситуация, когда я использую пользовательский плагин specflow. Используя пользовательский плагин specflow, у меня есть два разных проекта, скажем, Project_A и Project_B. Оба проекта имеют свой собственный репозиторий.
Project_A имеет класс ниже (пожалуйста, найдите фрагмент кода) :
public class CustomTestGeneratorProvider : IUnitTestGeneratorProvider
{
public CustomTestGeneratorProvider (CodeDomHelper codeDomHelper)
{
_unitTestGeneratorProvider = new
NUnit3TestGeneratorProvider(codeDomHelper);
CodeDomHelper = codeDomHelper;
}
public UnitTestGeneratorTraits GetTraits()
{
return _unitTestGeneratorProvider.GetTraits();
}
public void SetTestClass(TestClassGenerationContext generationContext, string featureTitle,
string featureDescription)
{
_unitTestGeneratorProvider.SetTestClass(generationContext, featureTitle, featureDescription);
generationContext.Namespace.Imports.Add(new CodeNamespaceImport("Com.MyOrg.Custom.Core.Feature"));
generationContext.TestClass.BaseTypes.Add("MyOrgTest");
}
public void SetTestClassCategories(TestClassGenerationContext generationContext,
IEnumerable<string> featureCategories)
{
_unitTestGeneratorProvider.SetTestClassCategories(generationContext, featureCategories);
}
Project_B имеет класс ниже (пожалуйста, найдите фрагмент кода) :
public class CustomTestGeneratorProvider : IUnitTestGeneratorProvider
{
public CustomTestGeneratorProvider (CodeDomHelper codeDomHelper)
{
_unitTestGeneratorProvider = new
NUnit3TestGeneratorProvider(codeDomHelper);
CodeDomHelper = codeDomHelper;
}
public UnitTestGeneratorTraits GetTraits()
{
return _unitTestGeneratorProvider.GetTraits();
}
public void SetTestClass(TestClassGenerationContext generationContext, string featureTitle,
string featureDescription)
{
_unitTestGeneratorProvider.SetTestClass(generationContext, featureTitle, featureDescription);
}
public void SetTestClassCategories(TestClassGenerationContext generationContext,
IEnumerable<string> featureCategories)
{
_unitTestGeneratorProvider.SetTestClassCategories(generationContext, featureCategories);
}
Если вы посмотрите на метод SetTestClass в классе, он имеет другую реализацию логики. Это единственный метод, который становится для меня поддержкой. Обратите внимание, что оба проекта выполняют одно и то же, но пользователь для них разный. Во время выпуска, если я что-то изменю в Project_A, я должен позаботиться или подумать и о Project_B.
Я хотел бы свести к минимуму это обслуживание. Что я должен сделать, чтобы сократить обслуживание?. Как избежать дублирования кода? в таком сценарии.
Комментарии:
1. создание некоторых интерфейсных / базовых классов и ссылок на версии в обоих проектах?
Ответ №1:
Возьмите все общие части классов и создайте из них абстрактный базовый класс. Оставьте SetTestClass
метод abstract
.
Поместите этот класс в отдельную dll:
public abstract class TestGeneratorProvider : IUnitTestGeneratorProvider
{
public CustomTestGeneratorProvider (CodeDomHelper codeDomHelper)
{
_unitTestGeneratorProvider = new
NUnit3TestGeneratorProvider(codeDomHelper);
CodeDomHelper = codeDomHelper;
}
public UnitTestGeneratorTraits GetTraits()
{
return _unitTestGeneratorProvider.GetTraits();
}
public abstract void SetTestClass(TestClassGenerationContext generationContext, string featureTitle,
string featureDescription)
public void SetTestClassCategories(TestClassGenerationContext generationContext,
IEnumerable<string> featureCategories)
{
_unitTestGeneratorProvider.SetTestClassCategories(generationContext, featureCategories);
}
}
В проекте A добавьте ссылку на эту dll, унаследуйте этот класс и предоставьте соответствующую SetTestClass
реализацию:
public class CustomTestGeneratorProvider : TestGeneratorProvider
{
public override void SetTestClass(TestClassGenerationContext generationContext, string featureTitle,
string featureDescription)
{
_unitTestGeneratorProvider.SetTestClass(generationContext, featureTitle, featureDescription);
generationContext.Namespace.Imports.Add(new CodeNamespaceImport("Com.MyOrg.Custom.Core.Feature"));
generationContext.TestClass.BaseTypes.Add("MyOrgTest");
}
}
И сделайте то же самое в проекте B:
public class CustomTestGeneratorProvider : TestGeneratorProvider
{
public override void SetTestClass(TestClassGenerationContext generationContext, string featureTitle,
string featureDescription)
{
_unitTestGeneratorProvider.SetTestClass(generationContext, featureTitle, featureDescription);
}
}
Ответ №2:
Создайте отдельный проект с этим классом и «базовой реализацией» для методов. Если вам нужно внести изменения исключительно в один, используйте переопределение, чтобы переопределить метод.
Ссылка: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/override