의존성 주입 대 정적 메소드 클래스에 접근하는 방법에 대해 다른

문자열을 받아들이고 문자열을 출력하는 메소드를 사용하여 클래스에 접근하는 방법에 대해 다른 개발자와 오늘 흥미로운 토론을했습니다.

다음과 같은 예를 위해 완전히 구성된 것을 상상해보십시오.

public string GetStringPart(string input)
{
   //Some input validation which is removed for clarity

   if(input.Length > 5)
        return input.Substring(0,1);

   if(input.Substring(0,1) == "B")
        return input.Substring(0,3);

   return string.empty;
}

문자열 입력을 기반으로 한 논리가있는 함수는 DI를 사용하여 프로젝트에 추가되고 DI 컨테이너가 있습니다. 이 새로운 클래스를 인터페이스와 함께 추가하고 필요한 곳에 주입하거나 정적 클래스로 만들겠습니까? 각각의 장단점은 무엇입니까? 왜 어디서나 필요할 때 액세스하지 않고 생성자 주입과 함께 사용하도록하고 싶습니까?



답변

이것이 주입되어야 할 이유가 없습니다. 이것은 단지 함수 일 뿐이며 종속성이 없으므로 호출하십시오. 순수한 것처럼 보이길 원한다면 정적 일 수도 있습니다. 어려움없이 단위 테스트를 작성할 수 있습니다. 다른 클래스에서 사용되는 경우에도 단위 테스트를 작성할 수 있습니다.

의존성이없는 함수를 추상화 할 필요가 없습니다.

이것이 복잡해지면 인터페이스를 생성자 또는 메소드에 전달하는 것이 필요합니다. 그러나 GetStringPart위치 등을 기반으로 복잡한 논리 가 없다면 그 길을 따라 가지 않을 것입니다 .


답변

이유는 다음과 같습니다

class DOSClient {
    OrderParser orderParser;
    string orderCode;

    DOSClient(OrderParser orderParser, string ordercode) {
        this.orderParser = orderParser;
        this.ordercode = ordercode;
    }
    void DisplayOrderCode() {
        Console.Write( "Prefix: " + orderParser.GetStringPart(ordercode) );
        ...
    }
}

class GUIClient {
    OrderParser orderParser;
    string orderCode;
    GUI gui;

    GUIClient(OrderParser orderParser, string ordercode, GUI gui) {
        this.orderParser = orderParser;
        this.ordercode = ordercode;
        this.gui = gui;
    }

    void DisplayOrderCode() {
        gui.Prefix( orderParser.GetStringPart(ordercode) );
        ...
    }
}

 

class OrderParserUS : IOrderParser {

    public string GetStringPart(string input)
    {
        //Some input validation which is removed for clarity

        if(input.Length > 5)
            return input.Substring(0,1);

        if(input.Substring(0,1) == "B")
            return input.Substring(0,3);

        return string.empty;
    }
}

class OrderParserEU : IOrderParser {

    public string GetStringPart(string input)
    {
        //Some input validation which is removed for clarity

        if(input.Length > 6)
            return input.Substring(0,1);

        if(input.Substring(0,1) == "#")
            return input.Substring(0,3);

        return string.empty;
    }
}

정적 방법을 사용 GetStringPart하면 이전 동작을 파괴하거나 조건부 논리로 오염시키지 않고 동작을 변경할 수있는 방법이 없습니다 . 정적은 변장에서 악의적 인 전역이라는 것이 사실이지만, 다형성을 비활성화한다는 사실은 그들에 대한 나의 주요 불만입니다. 정적 메소드는 OOP 언어에서 일류 클래스가 아닙니다. 메서드에 상태가없는 개체도 살도록 개체를 제공함으로써 메서드를 이식 가능하게 만듭니다. 변수의 값처럼 동작을 전달할 수 있습니다.

여기서 유럽에 배포 할 때와 미국에 배포 할 때 약간 다르게 작동해야하는 시스템을 상상했습니다. 그 대신 어느 한 시스템이 다른 시스템에 필요한 코드 만 포함하도록 강제 실행하면 클라이언트에 어떤 순서 구문 분석 오브젝트가 삽입되는지 제어하여 동작을 변경할 수 있습니다. 이를 통해 지역 세부 사항의 확산을 포함 할 수 있습니다. 또한 기존 파서를 건드리지 않고도 OrderParserCanada를 쉽게 추가 할 수 있습니다.

그것이 당신에게 아무런 의미가 없다면, 이것에 대한 좋은 주장은 실제로 없습니다.

BTW GetStringPart는 끔찍한 이름입니다.