Programing

단일 방법을 사용하는 클래스 - 최상의 접근 방식?

c10106 2022. 4. 25. 21:19
반응형

단일 방법을 사용하는 클래스 - 최상의 접근 방식?

내가 단일 기능을 수행하는 수업이 있다고 해.기능을 수행한 후에는 파괴할 수 있다.이러한 접근방식 중 하나를 선호할 이유가 있는가?

// Initialize arguments in constructor
MyClass myObject = new MyClass(arg1, arg2, arg3);
myObject.myMethod();

// Pass arguments to method
MyClass myObject = new MyClass();
myObject.myMethod(arg1, arg2, arg3);

// Pass arguments to static method
MyClass.myMethod(arg1, arg2, arg3);

나는 다른 상황에 대한 가이드라인을 얻기 위해, 세부사항에 대해 의도적으로 모호하게 생각하고 있었다.그러나 나는 실제로 Math.random()과 같은 간단한 도서관 기능을 염두에 두고 있지는 않았다.나는 어떤 구체적이고 복잡한 작업을 수행하지만 그것을 하기 위해서는 한 가지 (공용) 방법만 필요한 수업을 더 생각하고 있다.

나는 정적인 방법으로 가득 찬 유틸리티 수업을 좋아했었다.그들은 그렇지 않으면 이중화와 유지관리의 지옥을 야기할 도우미 방법을 대대적으로 통합했다.그것들은 사용하기 쉽고, 즉흥적이지 않고, 폐기되지 않고, 그냥 잊어버릴 뿐이다.나는 이것이 내가 무심코 서비스 지향 아키텍처를 만들려고 한 첫 시도였다고 생각한다. 즉, 그들의 일을 그저 해낸 많은 상태 비저장 서비스들 뿐이고 다른 것은 아무것도 아니다.그러나 체계가 성장함에 따라 용이 오고 있다.

다형성
UtilityClass라는 방법이 있다고 가정합시다.행복하게 윙윙거리는 어떤 방법.갑자기 기능성을 약간 바꿀 필요가 있다.기능성은 대부분 동일하지만 그래도 몇 개 정도는 바꿔야 한다.정적인 방법이 아니었다면, 우리는 파생 클래스를 만들 수 있었고 필요에 따라 방법 내용을 변경할 수 있었다.정적인 방법이기 때문에, 우리는 할 수 없다.물론, 이전 방법의 전후에 기능만 추가하면 새로운 클래스를 만들 수 있고 그 안에 있는 오래된 클래스를 부를 수 있지만, 그건 역겹기만 하다.

인터페이스 문제
정적 방법은 논리적인 이유로 인터페이스를 통해 정의할 수 없다.그리고 우리가 정적 방법을 무시할 수 없기 때문에, 정적 클래스는 우리가 그들의 인터페이스로 그것들을 전달해야 할 때 쓸모가 없다.이것은 전략 패턴의 일부로 정적 클래스를 사용할 수 없게 만든다.우리는 인터페이스 대신 대의원을 통과함으로써 몇몇 문제를 해결할 수도 있다.

테스트
이것은 기본적으로 위에서 언급한 인터페이스 문제와 관련이 있다.구현을 상호 변경하는 능력은 매우 제한적이기 때문에 생산 코드를 테스트 코드로 대체하는 데도 문제가 있을 것이다.다시 말하지만, 실제 물건 대신 포장지를 받을 수 있으려면 코드의 많은 부분을 바꿔야 할 겁니다.

포스터스 블롭
정적 방법은 대개 효용 방법으로 사용되며 효용 방법은 대개 다른 목적을 가지므로, 우리는 곧 큰 세분류를 일관성 없는 기능성으로 채울 것이다. 이상적으로는 각 세분류는 시스템 내에서 단일 목적을 가져야 한다.나는 그 목적이 잘 규정되어 있는 한 그 수업의 5배를 받는 것이 훨씬 더 낫다.

파라미터 크리프
우선 그 작고 귀여운 순진한 정적 방법은 하나의 매개 변수를 취할 수도 있다.기능성이 커짐에 따라 몇 가지 새로운 매개변수가 추가된다.곧 선택 사항인 추가 매개변수가 추가되므로, 우리는 메소드의 오버로드(또는 기본값을 지원하는 언어로만 추가)를 만든다.머지않아 10개의 파라미터를 사용하는 방법이 있다.처음 3개만 필요한데, 변수 4-7은 선택사항이다.하지만 매개변수 6이 지정되면 7-9도 기입해야 한다...이 정적 방법이 하는 일을 하는 단일한 목적을 가진 클래스를 만들었다면, 우리는 생성자에 필요한 파라미터를 가져다가, 사용자가 속성이나 복수의 상호의존적 값을 동시에 설정하는 방법을 통해 선택적 값을 설정하도록 허용함으로써 이것을 해결할 수 있었다.또한, 어떤 방법이 이 정도의 복잡성으로 성장했다면, 어쨌든 그것은 그 자신의 반에 있을 필요가 있을 것이다.

소비자에게 이유 없이 클래스의 인스턴스 생성 요구
가장 일반적인 주장 중 하나는, 왜 우리 클래스의 소비자들이 이 단일 방법을 실행하기 위한 인스턴스를 만들도록 요구하면서 그 이후에는 그 예를 사용하지 않는가?클래스의 인스턴스를 만드는 것은 대부분의 언어에서 매우 값싼 작업이기 때문에 속도는 문제가 되지 않는다.소비자에게 코드 라인을 추가하는 것은 향후 훨씬 더 유지 보수 가능한 솔루션의 기반을 마련하기 위한 낮은 비용이다.마지막으로, 인스턴스를 만들지 않으려면 쉽게 재사용할 수 있는 클래스의 싱글톤 래퍼를 만드십시오. 이렇게 하면 클래스가 상태 비저장 상태라는 요구사항이 만들어지지만,만일 그것이 무국적자가 아니라면, 당신은 여전히 모든 것을 처리하는 정적 포장 방법을 만들 수 있고, 동시에 장기적으로 당신에게 모든 혜택을 줄 수 있다.마지막으로, 당신은 또한 싱글톤인 것처럼 즉석화를 숨기는 수업을 만들 수 있다: MyWrapper.인스턴스는 새 MyClass()를 반환하는 속성이다.

오직 시스만이 절대성을 다룬다.
물론 내가 정적인 방법을 싫어하는 것에는 예외가 있다.부풀어 오를 위험이 없는 진정한 효용 클래스는 정적 방법의 훌륭한 사례 - 시스템이다.예로 변환하십시오.그러나 향후 유지보수에 대한 요구사항이 없는 프로젝트가 일회성이라면 전체 아키텍처는 그다지 중요하지 않다. 즉, 정적 아키텍처든 비 정적 아키텍처든, 실제로 중요하지 않다. 개발 속도는 중요하지 않다.

표준, 표준, 표준!
인스턴스(instance) 메소드를 사용한다고 해서 정적 메소드를 사용하지 못하게 되는 것은 아니며, 그 반대의 경우도 마찬가지다.차별화 뒤에 추리가 있고 표준화가 되어 있는 한.다양한 구현 방법을 통해 확장되는 비즈니스 계층을 살펴보는 것보다 더 나쁜 것은 없다.

나는 정적인 방법이 더 좋다.클래스는 사물을 나타내지 않기 때문에 그 사물을 예로 든다는 것은 이치에 맞지 않는다.

자신의 방법만을 위해 존재하는 클래스는 정적으로 남겨두어야 한다.

기능을 실행하기 위해 클래스의 인스턴스를 생성할 이유가 없는 경우 정적 구현을 사용하십시오.왜 이 클래스의 소비자가 필요하지 않은 인스턴스를 만들도록 하는가?

사물의 상태를 살릴 필요가 없다면 애당초 그것을 인스턴스화할 필요가 없다.나는 당신이 매개 변수를 전달하는 단일 정적 방법을 사용할 것이다.

나는 또한 수십 가지의 관련없는 정적 방법을 가지고 있는 거대한 Utils 클래스에 대해 경고할 것이다.이것은 서둘러서 흐트러지고 다루기 어려워질 수 있다.관련 방법이 별로 없는 수업이 많은 편이 좋다.

나는 정적 방법 형식이 더 나을 것이라고 말하고 싶다.그리고 나는 수업도 정적으로 만들거야, 그렇게 하면 너는 실수로 수업의 인스턴스를 만드는 것에 대해 걱정할 필요가 없을거야.

나는 정말로 이곳의 상황이 어떤지 모르지만, 나는 이것을 arg1, arg2, arg3가 속한 수업들 중 하나에 하나의 방법으로 넣는 것을 볼 것이다. 만약 당신이 의미 있게 그 수업들 중 하나가 그 방법을 소유할 것이라고 말할 수 있다면.

나는 제공된 정보에 근거하여 대답하기 어렵다고 제안하고 싶다.

내 직감은 만약 네가 한 가지 방법만을 택할거고, 수업을 즉시 버릴거라면, 모든 변수를 취하는 정적 수업으로 만들라는 것이다.

물론 이 한 가지 방법만으로 왜 단일 클래스를 만들어야 하는지 정확히 말하기는 어렵다.대다수가 추측하고 있는 전형적인 "유틸리티 클래스" 상황인가?아니면 어떤 종류의 규칙 수업을 시행하고 있는가? 그 중 미래에는 더 많은 규칙이 있을 것이다.

예를 들어, 그 클래스를 플러그로 꽂을 수 있도록 하십시오.그런 다음 한 가지 방법에 대한 인터페이스를 만들고, 모든 매개 변수를 생성자가 아닌 인터페이스로 전달하고 싶을 겁니다. 하지만 정적이 되는 것은 원치 않을 겁니다.

너의 수업은 정적이 될 수 있니?

만약 그렇다면, 나는 그것을 '유틸리티' 수업으로 만들어서 모든 단기능 수업을 할 것이다.

만약 이 방법이 무국적 상태여서 그것을 전달할 필요가 없다면, 그것을 정적인 것으로 정의하는 것이 가장 타당하다.방법을 전달할 필요가 있는 경우 제안된 다른 접근 방식 중 하나가 아닌 대리인을 사용하는 것을 고려해 보십시오.

간단한 애플리케이션 및internal도우미들, 난 정적인 방법을 쓸거야구성요소가 있는 응용프로그램의 경우, Managed Extensibility Framework가 마음에 든다.여기 내 API를 통해 찾을 수 있는 패턴을 설명하기 위해 내가 쓰고 있는 문서에서 발췌한 것이 있다.

  • 서비스
    • 에 의해 정의I[ServiceName]Service접점
    • 인터페이스 유형별로 내보내고 가져오는 중.
    • 단일 구현은 호스트 애플리케이션에 의해 제공되며 내부적으로 또는 확장에 의해 소비된다.
    • 서비스 인터페이스의 메소드는 스레드 안전하다.

의도된 예로서:

public interface ISettingsService
{
    string ReadSetting(string name);

    void WriteSetting(string name, string value);
}

[Export]
public class ObjectRequiringSettings
{
    [Import]
    private ISettingsService SettingsService
    {
        get;
        set;
    }

    private void Foo()
    {
        if (SettingsService.ReadSetting("PerformFooAction") == bool.TrueString)
        {
            // whatever
        }
    }
}

나는 건설업자의 모든 것을 할 것이다.다음과 같다:

new MyClass(arg1, arg2, arg3);// the constructor does everything.

또는

MyClass my_object(arg1, arg2, arg3);

한 가지 더 고려해야 할 중요한 문제는 시스템이 다중 스레드 환경에서 실행될 것인지, 그리고 정적 방법이나 변수를 갖는 것이 스레드 세이프가드가 될 것인지...

시스템 상태에 유의해야 한다.

너는 그 상황을 함께 피할 수 있을지도 몰라.다시 반응해서 더 좋은 결과를 얻도록 하라구.arg1.myMethod1(arg2, arg3). arg1을 arg2 또는 arg3와 교환한다.

arg1 클래스를 제어할 수 없는 경우 다음과 같이 꾸미십시오.

class Arg1Decorator
    private final T1 arg1;
    public Arg1Decorator(T1 arg1) {
        this.arg1 = arg1;
    }
    public T myMethod(T2 arg2, T3 arg3) {
        ...
    }
 }

 arg1d = new Arg1Decorator(arg1)
 arg1d.myMethod(arg2, arg3)

그 추론은 OOP에서 데이터가 함께 속하는 데이터와 처리 방법이 그것이다.게다가 마크가 말한 모든 장점도 얻을 수 있어.

만약 당신의 클래스의 속성이나 클래스의 인스턴스(instance)가 생성자나 당신의 방법에 사용되지 않는다면, 방법은 '정적인' 패턴처럼 디자인되도록 제안되지 않는다. 정적 방법은 항상 '도움말' 방식으로 생각되어야 한다.

단지 무언가를 하고 싶은지 아니면 하고 싶은지 그리고 돌려주고 싶은지에 따라 당신은 이렇게 할 수 있다.

public abstract class DoSomethingClass<T>
{
    protected abstract void doSomething(T arg1, T arg2, T arg3);
}

public abstract class ReturnSomethingClass<T, V>
{
    public T value;
    protected abstract void returnSomething(V arg1, V arg2, V arg3);
}

public class DoSomethingInt extends DoSomethingClass<Integer>
{
    public DoSomethingInt(int arg1, int arg2, int arg3)
    {
        doSomething(arg1, arg2, arg3);
    }

    @Override
    protected void doSomething(Integer arg1, Integer arg2, Integer arg3)
    {
        // ...
    }
}

public class ReturnSomethingString extends ReturnSomethingClass<String, Integer>
{
    public ReturnSomethingString(int arg1, int arg2, int arg3)
    {
        returnSomething(arg1, arg2, arg3);
    }

    @Override
    protected void returnSomething(Integer arg1, Integer arg2, Integer arg3)
    {
        String retValue;
        // ...
        value = retValue;
    }
}

public class MainClass
{
    static void main(String[] args)
    {
        int a = 3, b = 4, c = 5;

        Object dummy = new DoSomethingInt(a,b,c);  // doSomething was called, dummy is still around though
        String myReturn = (new ReturnSomethingString(a,b,c)).value; // returnSomething was called and immediately destroyed
    }
}

참조URL: https://stackoverflow.com/questions/205689/class-with-single-method-best-approach

반응형