2010-11-25 5 views
5

전달할 매개 변수가 7 개인 공용 클래스가 있습니다. 지금은 그 중 3 개를 생성자에게 전달하고 나머지 4 개는 클래스의 공용 메소드로 전달할 수 있습니다. 이와 같이 :7 개 이상의 매개 변수 처리

 

Public Class AClass{ 
    private XClass axClass; 
    private String par4; 
    private String par5; 
    private String par6; 
    private String par7; 

    public AClass(String par1, String par2, String par3){ 
     aXClass = new XClass(par1,par2,par3); 
    } 

    public execute(String par4,String par5, String par6, String par7){ 
     //this is needed because they are used in other private methods in this class 
     this.par4 = par4; 
     this.par5 = par5; 
     this.par6 = par6; 
     this.par7 = par7; 

     //call other private methods within this class. 
     //about 7 lines here 
    } 

} 

 

내 질문은 클래스의 클라이언트에게 매개 변수를 전달하도록 요청하는 올바른 방법입니까?

+0

나는 constructor에 전달해야하는 것이 상황에 달려 있다고 생각한다. AClass와 XClass가하는 일과이 7 개의 매개 변수는 무엇인지 자세히 설명 할 수 있습니까? – Emil

+1

"10 개의 매개 변수가있는 프로 시저가있는 경우 일부 프로 시저가 누락되었을 수 있습니다." -Alan Perlis :-) – missingfaktor

답변

9

7 개의 매개 변수를 생성자에 전달하는 것을 막아서는 안됩니다. Java의 메소드에 전달할 수있는 매개 변수의 최대 개수가 있는지 모르겠지만 최대 값이 있으면 7보다 높습니다.

클래스 및 공용 메서드를 만들 때 해당 클래스를 사용하고 액세스하는 방법에 대한 인터페이스를 만듭니다. 그래서 기술적으로 당신이 지금까지 한 것은 정확합니다. 클래스 의뢰인에게 인수를 요청하는 것이 "올바른 방법"입니까? 인터페이스 설계자는 당신에게 달려 있습니다. 7 개 매개 변수가 전달되고 내가봤을 때

나의 첫번째 본능은 자동으로 요청했다 "그들은 자신의 클래스에서 함께 잘 갈 것 의미 할 수 있습니다 일부 또는 이러한 모든 매개 변수 사이에 어떤 관계가 있습니까?" 그것은 당신이 당신의 코드를 보면서 당신이 다루는 어떤 것일 수 있습니다. 그러나 이것이 바로 디자인의 문제이며 정확성의 문제는 아닙니다.

+0

좋은 대답. "옳은 길"은 없으며 분명히 우월한 선택이 없습니다. 최선의 판단을 내려야합니다. –

+0

7 개의 매개 변수가 모두 String이므로 모두 생성자에 있으면 사람들을 혼란스럽게하지 않습니까? 7 개의 매개 변수에 대한 setter 및 getter가있는 더미 데이터 객체를 만드는 경우 클라이언트는이 데이터 유형에 대해 알아야합니다.이 목적을 위해 올바른 접근 방식입니까? – sarahTheButterFly

+0

오, 절대적으로 사람들을 혼란스럽게 할 수 있습니다.그러나 기술적 인 문제와는 반대로 설계상의 문제입니다. 그래서 그 매개 변수가 무엇인지 살펴보고 다른 클래스에 캡슐화 할 수있는 방법이 있는지 살펴 보도록 제안한 것입니다. 예를 들어, 7 명 모두가 일부 팀의 선수 일 수 있습니다. 그런 다음 플레이어 이름 목록이 포함 된 Team 클래스를 만든 다음 여러 개의 플레이어 이름 문자열 대신 Team 인스턴스를 전달하는 것이 더 바람직 할 수 있습니다. – Marvo

1

이 매개 변수를 저장하고 함수에 전달하는 클래스/해시 맵을 만들 수 없습니까?

public excute(Storageclass storageClass){ 
     //this is needed because they are used in other private methods in this class 
     this.par4 = storageClass.getPar4(); 
     this.par5 = storageClass.getPar5(); 
     this.par6 = storageClass.getPar6(); 
     this.par7 = storageClass.getPar7(); 

     //or 
     this.storageClass = storageClass; 
    } 
+0

Java의 "Named Parameter"관용어에 대한 몇 가지 토론이 있습니다. http://stackoverflow.com/questions/1988016/named-parameter-idiom-in-java – HostileFork

1

실제로이 문제는 나타나지 않습니다. 또한

class SomeClass { 
    private String a; 
    private String b; 
    .... 
    public SomeClass(Request r) { 
     this.a = r.get("a"); 
     this.b = r.get("b"); 
     ... 
    } 

    public void execute(Request other) { 
     this.d = other.get("d"); 
     this.e = other.get("d"); 
     ... 
    } 
} 

참조 :이 같은 "요청"개체 또는 무언가 만들 수있는 경우

자식 클래스의 사용을 모른 채 http://c2.com/cgi/wiki?TooManyParameters

1

을, 나는이 있음을 말할 수있다 본질적으로 당신이 한 일에 아무런 문제가 없습니다.

주 당신이 당신의 AClass의 변수

private XClass axClass;

를 선언해야한다는 생각.

그러나 나는 '할 수 있습니다 ....'라고 말하면 다른 방법으로 선언하는 데 문제가 있습니까?

+0

감사합니다. 나는 그것을 편집했다. 생성자에서 이들 모두를 선언해도 아무런 문제가 없습니다. 내가 의미했던 것은 3과 4로 나눌 수 있었다. – sarahTheButterFly

1

개체가 생성자가 호출 된 후에 100 % 사용할 준비가되어 있어야하기 때문에 나는별로 신경 쓰지 않습니다. 그것은 당신의 모범으로 쓰여진 것이 아닙니다.

execute 메소드에 전달 된 매개 변수를 단순히 소비 할 수 있고 클라이언트의 관심 대상 메소드 인 경우 클래스의 데이터 멤버가 될 이유가 없습니다.

궁극적 인 목표에 대해 더 많이 알지 못하면 말할 수 없습니다. 그러나 나는이 구현을 다시 생각할 것이다.

+0

안녕하세요! 미안, 인사하고 싶다. 아마도 적절하지는 않지만 :) – sarahTheButterFly

+0

완벽하게 좋아, Sarah. 미국에 계시다면 내일 좋은 휴가를 보내시기 바랍니다. – duffymo

+0

hehe. 나는 미국에 없다. 하지만 고마워. 그리고 내일도 여기 있습니다 - 호주. 당신의 휴가를 즐기십시오 :) – sarahTheButterFly

1

을 호출하지 않고 par4-7을 알 필요가있는 AClass.someMethod()을 도입하려는 경우 분명히 생성자의 매개 변수를 전달해야합니다.한편

: 당신은 par1-3와이 개체의 인스턴스를 구성하고 전화 외에 그 으로 의미있는 일을 할 수 있다면 excute() 다음 개체가 전체 일곱 개 매개 변수보다 더 적은으로 구성 할 수 있도록하는 것이 합리적이다 .

그러나 내 자신의 미학은 특정 방법을 작동시키고 다른 방법이 실패 할 수있는 "모드"의 수를 제한하려고 시도하는 것입니다. 이상적으로, 완벽하게 구성된 객체는 프로그래머가 호출 할 수있는 모든 메소드를 실행할 준비가되어 있습니다. 나는 생성자에 대한 매개 변수의 수에 대해 너무 우려하는 것보다 디자인 문제에 대해 걱정할 것입니다.

그러나 다른 사람들이 지적했듯이, 때로는 이러한 매개 변수를 자연스럽게 그룹화하여 고유 한 개체를 가질 자격이 있습니다. 예를 들어, (x, y, 너비, 높이)를 지나가는 대신에 많은 API에서 직사각형 객체를 사용합니다.

+0

또한 : http://en.wiktionary.org/wiki/execute의 철자가 의도적입니까, 의도적입니까? 일반적으로 나는 typo를 언급 할 가치가 없다고 가정 할 것이지만, 잠깐 전에 subGridRowColapsed라는 메소드를 jqGrid API로 만든 메소드를 보았습니다 ... doublecheck을해야합니다. http://www.trirand.com/jqgridwiki/doku.php?id=wiki:subgrid&s[]=expand – HostileFork

+0

죄송합니다. 의도하지 않았습니다. 오식. : P – sarahTheButterFly

1

다른 사람들이 이미 썼기 때문에 7 가지 매개 변수를 전달하는 것이 기술적으로 정확합니다. 그렇다고 말할 수 있다면 '사용자에게 친숙하지 않습니다'.

이 클래스에 대해 많이 쓰지 않았으므로 하나의 작은 것을 제안 할 수 있습니다. 생성자에서 단지 XClass 개체를 생성하는 것이므로이 개체를 전에 만들어서 단일 매개 변수로 전달하는 것이 정상적입니다. 이 같은

뭔가 :

... 
XClass aXClass = new XClass(par1, par2, par3); 
AClass aClass = new AClass(aXClass); 
... 

그리고 이것은 생성자입니다 :

public AClass(XClass aXClass) { 
     this.aXClass = aXClass; 
} 
6

에 의해 제안 내가 대신 많은 생성자 매개 변수의 Builder Pattern 가고 싶어 Effective Java 항목 2 : 많은 건축가와 직면했을 때 건축업자를 고려하십시오.

public class Dummy { 

    private final String foo; 
    private final String bar; 
    private final boolean baz; 
    private final int  phleem; 

    protected Dummy(final Builder builder) { 
     this.foo = builder.foo; 
     this.bar = builder.bar; 
     this.baz = builder.baz; 
     this.phleem = builder.phleem; 
    } 

    public String getBar() { 
     return this.bar; 
    } 

    public String getFoo() { 
     return this.foo; 
    } 

    public int getPhleem() { 
     return this.phleem; 
    } 

    public boolean isBaz() { 
     return this.baz; 
    } 

    public static class Builder { 
     private String foo; 
     private String bar; 
     private boolean baz; 
     private int  phleem; 

     public Dummy build() { 
      return new Dummy(this); 
     } 

     public Builder withBar(final String bar) { 
      this.bar = bar; 
      return this; 
     } 

     public Builder withBaz(final boolean baz) { 
      this.baz = baz; 
      return this; 
     } 

     public Builder withFoo(final String foo) { 
      this.foo = foo; 
      return this; 
     } 

     public Builder withPhleem(final int phleem) { 
      this.phleem = phleem; 
      return this; 
     } 

    } 

} 

당신은 다음과 같이 인스턴스화 것 :

Dummy dummy = new Dummy.Builder() 
        .withFoo("abc") 
        .withBar("def") 
        .withBaz(true) 
        .withPhleem(123) 
        .build(); 

좋은 부분 :이 생성자 매개 변수의 모든 혜택을받을 (ctor에 여기

을 설명하기 위해 간단한 클래스의 매개 변수 예 당신이 그것을 원한다면 불변성), 그러나 당신은 또한 읽을 수있는 코드를 얻는다.

+0

+1, 나는이 대답을 두 번째. – missingfaktor

+1

"필수"매개 변수가 모두 설정되었는지 확인하려면 build() 메서드에 대한 검사를 추가해야합니다.이 매개 변수는 7 개의 매개 변수가있는 생성자와 완전히 동일합니다 (예 : 사용자 설정 "null"과 "null"기본값). 이것이 바로이 솔루션의 단점입니다. – naab

+1

@naab 요즘에는 빌더 생성에 https://immutables.github.io/ 프레임 워크를 사용하고 싶습니다. 이 기능을 기본적으로 상자에 추가합니다. –

관련 문제