문제

나는 이것이 매우 공개적인 질문이고 다양한 답변을 얻을 수 있다는 것을 알고 있지만 여기에 있습니다.

C#(또는 Java 또는 기타 OO 언어)을 사용할 때 생성자에 몇 개의 변수를 전달해야 하는지를 명시하는 일반 규칙이 있습니까?확장 클래스의 생성자에 전달하는 변수의 수가 감당할 수 없을 만큼 많아지는 것 같습니다.

클래스의 데이터를 캡슐화하기 위해 멤버를 비공개로 선언하고 생성자에서 초기화한 다음 공개 접근자를 사용합니다.

예는 다음과 같습니다.

public class A
{
  private int var1;
  private int var2;
  private int var3;

  //3 variables passed in
  public A(int v1, int v2, int v3)
  {
    var1 = v1;
    var2 = v2;
    var3 = v3;
  }

  //Properties (accessors) here
}

public class B : A
{
  private int var4;
  private int var5;

  //5 variables passed in
  public B(int v1, int v2, int v3, int v4, int v5)
  : base(v1,v2,v3)
  {
    var4 = v4;
    var5 = v5;
  }

  //Properties (accessors) here
}

public class C : B
{
  private int var6;
  private int var7;

  //7 variables passed in !!!
  public C(int v1, int v2, int v3, int v4, int v5, int v6, int v7)
  : base(v1,v2,v3,v4,v5)
  {
    var6 = v6;
    var7 = v7;
  }

  //Properties (accessors) here
}

내 생성자는 일반적으로 정수뿐만 아니라 다른 개체를 전달합니다.자식 클래스의 생성자에 7개의 변수를 전달하기 시작했을 때 내 디자인에 의문이 들기 시작했지만 이를 수행하는 다른 방법을 찾는 데도 어려움을 겪었습니다.

이것은 나쁜 프로그래밍 관행으로 간주됩니까?생성자에 전달해야 하는 변수 수에 일반적인 제한이 있나요?

도움이 되었습니까?

해결책

일반적으로 3 개가 넘는 경우 발견 한 것은 디자인에 대한 빠른 정신 점검을 수행하는 신호입니다. 5 개가 넘는 것이 있다면, 그것은 아마도 디자인에 문제가있을 수 있다는 큰 경고입니다.

그러나 "아마도"라는 단어에 주목합니다. 결국 유일한 규칙은 필요에 따라 기능을 사용하는 데 더 이상 사용하십시오.. 더 많은 매개 변수가 가장 의미가있는 예외와 사례가 항상 있습니다.

매개 변수가 어떻게 든 관련되어 있으면 컨테이너 클래스로 캡슐화해야합니다.

매개 변수가 관련이없는 경우 - 예를 들어 컨테이너 클래스로 그룹화하는 것이 의미가 없습니다. 클래스가 너무 많은 일을하고있을 것입니다. 일반적으로 단일 클래스가 완전히 이질적인 7 가지 정보를 인식 해야하는 이유는 없습니다. 수업을 별도의 수업으로 나누십시오. 예를 들어 매개 변수를 서브 클래스로 3과 4로 위임하는 것이 합리적 일 수 있으며, 예를 들어 다른 클래스에 5, 6 및 7을 다른 클래스로 위임하는 것이 합리적 일 수 있으며, 부모 클래스는 단순히 그들 사이의 작업을 조정합니다.

다른 팁

나에게 정답은 다음과 같습니다.

유효하지 않은 상태에서 객체를 설정하는 데 필요한만큼 많은 변수를 전달해야합니다.

"옵션"인 다른 것들은 특히 C#이 객체 초기화기를 제공하므로 속성으로 떠나는 것을 선호합니다.

"너무 많은"것에 대해 단단하고 빠른 숫자를 넣기가 어렵습니다. 진짜 질문은 이것입니다. 수업은 무엇을하고 있습니까? 수업이 너무 많이하고 있습니까? 그렇다면 수업을 더 작고 간결한 수업으로 나누어야합니다.

생성자 매개 변수는 클래스의 종속성/입력을 정의하는 데 필요한만큼 많은 것을 포함해야합니다. 클래스가 인생에서 하나의 직업을 갖도록 축소되면 생성자 매개 변수가 올바르게 될 것입니다.

다른 사람들이 말했듯이, 이것에 대한 어려운 규칙은 없으며, 실제로는 달라집니다. 그러나 사람의 두뇌가 한 번에 이해할 수있는 것들에 대한 구체적인 증거가 있습니다. 그것은 7 + 또는 -2 규칙입니다.

이 유형의 질문은 Steve McConnell이 작성한 코드에서 매우 잘 답변됩니다. 아직이 책을 읽지 않는 것이 좋습니다.

3.5 프레임 워크에 대해 내가 좋아하는 한 가지 ...

new Foo {
    Street = "909 Rose Ave",
    City = "San Diego",
    State = "CA",
    FName = "Joe",
    LName = "Wazowski",
    ID = "987665454"
};

너무 많은 생성자 또는 너무 많은 매개 변수를 가진 생성자에 대해 더 이상 걱정하지 않습니다.

내 개인적인 규칙입니다 5

더 필요한 경우 구조 나 물체로 감싸십시오.

이것은 다음에 변경됩니다 초기화 할 필요가 없습니다 그 물체. IOC 컨테이너를 사용하여 객체를 초기화하면 생성 매개 변수 수는 기본적으로 무제한입니다.

특히 인스턴스화와 함께 블록으로 변수를 설정할 수있는 최신 기능이므로 생성에 대한 매개 변수 만 사용하는 경향이 있습니다. 가지다 클래스가 생성 될 때 설정하기 위해,이 경우 기본 생성자를 비공개로 만들거나 보호합니다.

예를 들어, 클래스 사각형이있는 경우 생성자 사각형 (이중 너비, 이중 높이)을 만들고 사각형 () 생성자를 비공개로 만드는 것이 합리적 일 수 있습니다.

또한 클래스가 생성자를 통해 속성 값 만 설정해야한다고 생각되면 매개 변수가없는 개인 생성자를 넣을 수 있습니다.

시스템은 사용 방법을 기억하기가 어려워 지 자마자 너무 많은 매개 변수를 가지고 있습니다. 그들이 모두 ints라면 3은 너무 많습니다. 그들이 다른 유형이라면 더 가질 수 있습니다.

이것은 Martin Fowler의 냄새입니다 리팩토링 책. 이것 웹 페이지 도움이되는 표준 리팩토링에 대한 링크가 포함되어 있습니다.

귀하의 경우, 빌더 객체 (매개 변수를 점진적으로 추가 할 수 있고 빌더가 클래스를 파악할 수 있음) 또는 매개 변수 개체를 고려할 수 있습니다.

IMHO, TDD를 사용하는 것은이 문제를 평가하는 데 유용한 관점입니다. CTOR가 단위 테스트 CTOR 또는 Setup ()에 적용하기 어려운 경우 초기화/공장의 인수는 너무 많고 비교적 엄격하게 결합됩니다.

수업을 구성하는 데 필요한 모든 것을 통과해야합니다. 많은 변수를 전달할 때 자주하는 일은 IT를 구성하는 데 필요한 정보를 보유하고 생성자에게 전달하는 객체에 대한 "구성"클래스를 만드는 것입니다. 인스턴스화하는 물체를 크게 단순화하고 더 깨끗한 디자인을 만듭니다.

나는 다른 관점에서 이 질문에 답하려고 노력할 것이다.생성자를 사용하는 두 가지 주요 방법이 있습니다. 매개 변수 수가 너무 많다는 두 가지 생각입니다.

1) 명시적으로 호출되는 생성자

이는 개체를 "새로 만들고" 모든 필수 매개변수 값을 지정해야 하는 일반적인 접근 방식입니다.이것은 여기의 다른 답변으로 완전히 다루어졌습니다.내 개인적인 경험 법칙은 다음과 같습니다.모든 매개변수는 한 줄에 들어가야 하므로 최대 3~4개의 매개변수를 사용합니다.

또한 귀하의 클래스가 미래에 더 많은 매개변수가 필요한 더 많은 사례를 처리할 수 있을 가능성이 높다는 것을 알고 있다면 구조체/클래스를 직접 사용하겠습니다.예:

클래스가 일부 기준에 따라 일부 객체 필터링을 처리해야 한다고 가정해 보겠습니다.처음에는 2~3개의 기준만 있습니다.앞으로 훨씬 더 많은 기준이 있을 가능성이 높다는 것을 알고 처음부터 FilterValue 개체를 직접 보내겠습니다.

2) 암시적으로 생성자를 호출합니다.

일반적인 경우는 다음과 같습니다. 의존성 주입.거의 모든 경우에 모든 생성자 매개변수가 주입되므로 객체를 빌드하는 것은 DI 프레임워크의 업무입니다.

여기서는 필요한 만큼 많은 서비스를 주입할 수 있으므로 "상식"이 적용되지 않습니다.예:

여러 리포지토리의 변경 사항을 집계하는 작업 단위 패턴을 사용하여 데이터 지속성이 수행되는 경우 작업 단위 클래스는 사용된 모든 리포지토리에 주입됩니다.자세한 내용은 이 답변에서 확인할 수 있습니다. 코드 검토.

그런데 메소드에 대한 이론적 최대 매개변수 수는 도달하지 못할 만큼 충분히 높아야 합니다. 씨# 그리고 자바.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top