현재 작업에서 상당히 많이 나오는 것은 일어날 필요가있는 일반화 된 프로세스가 있다는 것입니다. 그러나 그 프로세스의 이상한 부분은 특정 변수의 값에 따라 약간 다르게 일어날 필요가 있습니다. 이것을 처리하는 가장 우아한 방법이 무엇인지 확실히 확신하십시오.
우리가 다루는 국가에 따라 약간 다른 방식으로 일을하는 예를 사용하겠습니다.
그래서 나는 수업을 가지고 있습니다 Processor
.
public class Processor
{
public string Process(string country, string text)
{
text.Capitalise();
text.RemovePunctuation();
text.Replace("é", "e");
var split = text.Split(",");
string.Join("|", split);
}
}
일부 국가에서는 이러한 작업 중 일부만 수행하면됩니다. 예를 들어, 6 개국 만이 대문자 사용 단계를 요구합니다. 분할 할 캐릭터는 국가에 따라 다를 수 있습니다. 'e'
국가에 따라 악센트를 교체해야 할 수도 있습니다.
분명히 다음과 같이하면 해결할 수 있습니다.
public string Process(string country, string text)
{
if (country == "USA" || country == "GBR")
{
text.Capitalise();
}
if (country == "DEU")
{
text.RemovePunctuation();
}
if (country != "FRA")
{
text.Replace("é", "e");
}
var separator = DetermineSeparator(country);
var split = text.Split(separator);
string.Join("|", split);
}
그러나 세계에서 가능한 모든 국가를 다룰 때는 매우 번거로워집니다. 그럼에도 불구하고,이 if
문장은 논리를 읽기 어렵게 만듭니다 (적어도 예보다 복잡한 방법을 상상한다면), 순환 복잡성은 매우 빠르게 시작됩니다.
그래서 지금 나는 이런 식으로 뭔가를하고 있습니다 :
public class Processor
{
CountrySpecificHandlerFactory handlerFactory;
public Processor(CountrySpecificHandlerFactory handlerFactory)
{
this.handlerFactory = handlerFactory;
}
public string Process(string country, string text)
{
var handlers = this.handlerFactory.CreateHandlers(country);
handlers.Capitalier.Capitalise(text);
handlers.PunctuationHandler.RemovePunctuation(text);
handlers.SpecialCharacterHandler.ReplaceSpecialCharacters(text);
var separator = handlers.SeparatorHandler.DetermineSeparator();
var split = text.Split(separator);
string.Join("|", split);
}
}
처리기 :
public class CountrySpecificHandlerFactory
{
private static IDictionary<string, ICapitaliser> capitaliserDictionary
= new Dictionary<string, ICapitaliser>
{
{ "USA", new Capitaliser() },
{ "GBR", new Capitaliser() },
{ "FRA", new ThingThatDoesNotCapitaliseButImplementsICapitaliser() },
{ "DEU", new ThingThatDoesNotCapitaliseButImplementsICapitaliser() },
};
// Imagine the other dictionaries like this...
public CreateHandlers(string country)
{
return new CountrySpecificHandlers
{
Capitaliser = capitaliserDictionary[country],
PunctuationHanlder = punctuationDictionary[country],
// etc...
};
}
}
public class CountrySpecificHandlers
{
public ICapitaliser Capitaliser { get; private set; }
public IPunctuationHanlder PunctuationHanlder { get; private set; }
public ISpecialCharacterHandler SpecialCharacterHandler { get; private set; }
public ISeparatorHandler SeparatorHandler { get; private set; }
}
똑같이 나는 정말로 마음에 들지 않습니다. 로직은 여전히 모든 팩토리 생성에 의해 가려져 있으며 원래 방법 만보고 "GBR"프로세스가 실행될 때 어떤 일이 발생하는지 확인할 수 없습니다. 또한 스타일 등에서 많은 클래스 (이보다 복잡한 예제에서)를 생성하게됩니다. 즉 GbrPunctuationHandler
, UsaPunctuationHandler
구두점 중에 발생할 수있는 모든 가능한 동작을 파악하려면 여러 클래스를 살펴 봐야합니다. 손질. 분명히 나는 10 억 개의 if
진술을 가진 거대한 클래스 하나를 원하지 않지만 약간 다른 논리를 가진 20 개의 클래스도 어색합니다.
기본적으로 나는 일종의 OOP 매듭에 빠져 있고 그것을 풀기위한 좋은 방법을 모른다고 생각합니다. 이 유형의 프로세스에 도움이 될 패턴이 있는지 궁금합니다.
if (country == "DEU")
확인하십시오 if (config.ShouldRemovePunctuation)
.
country
PreProcess
일부 국가에 따라 다르게 구현 될 수 있는 기능 이있는 것 같습니다.DetermineSeparator
모든 국가에 사용할 수 있습니다PostProcess
. 모두protected virtual void
기본 구현으로 구현할 수 있으며Processors
국가별로 구체적으로 지정할 수 있습니다.