Programing

Java에서 많은 매개 변수를 사용하여 생성자 관리

crosscheck 2020. 8. 20. 07:37
반응형

Java에서 많은 매개 변수를 사용하여 생성자 관리


일부 프로젝트에는 체인을 따라 내려갈 때 더 많은 매개 변수를 추가하는 클래스 계층 구조가 있습니다. 맨 아래에서 일부 클래스는 최대 30 개의 매개 변수를 가질 수 있으며이 중 28 개는 수퍼 생성자로 전달됩니다.

나는 Guice와 같은 것을 통해 자동화 된 DI를 사용하는 것이 좋겠지 만 몇 가지 기술적 이유 때문에 이러한 특정 프로젝트는 Java로 제한됩니다.

유형에 따라 인수를 알파벳순으로 구성하는 규칙은 작동하지 않습니다. 유형이 리팩토링되면 (인수 2로 전달한 원이 이제 Shape가 됨) 갑자기 순서가 잘못 될 수 있기 때문입니다.

이 질문은 구체적이고 "그게 당신의 문제라면, 당신은 디자인 수준에서 잘못하고있다"는 비판으로 가득 차있을 수 있지만, 저는 단지 어떤 관점을 찾고 있습니다.


빌더 디자인 패턴이 도움이 될 수 있습니다. 다음 예를 고려하십시오.

public class StudentBuilder
{
    private String _name;
    private int _age = 14;      // this has a default
    private String _motto = ""; // most students don't have one

    public StudentBuilder() { }

    public Student buildStudent()
    {
        return new Student(_name, _age, _motto);
    }

    public StudentBuilder name(String _name)
    {
        this._name = _name;
        return this;
    }

    public StudentBuilder age(int _age)
    {
        this._age = _age;
        return this;
    }

    public StudentBuilder motto(String _motto)
    {
        this._motto = _motto;
        return this;
    }
}

이렇게하면 다음과 같은 코드를 작성할 수 있습니다.

Student s1 = new StudentBuilder().name("Eli").buildStudent();
Student s2 = new StudentBuilder()
                 .name("Spicoli")
                 .age(16)
                 .motto("Aloha, Mr Hand")
                 .buildStudent();

필수 필드를 생략하면 (아마 이름이 필요함) Student 생성자가 예외를 throw하도록 할 수 있습니다. 그리고 어떤 종류의 인수 순서를 추적 할 필요없이 기본 / 선택 인수를 가질 수 있습니다. 이러한 호출의 순서가 동일하게 잘 작동하기 때문입니다.


객체 내부에 관련 매개 변수를 캡슐화 할 수 있습니까?

예 : 매개 변수가 다음과 같은 경우


MyClass(String house, String street, String town, String postcode, String country, int foo, double bar) {
  super(String house, String street, String town, String postcode, String country);
  this.foo = foo;
  this.bar = bar;

대신 다음을 가질 수 있습니다.


MyClass(Address homeAddress, int foo, double bar) {
  super(homeAddress);
  this.foo = foo;
  this.bar = bar;
}


아마도 당신이하고 싶은 것은 Builder 클래스가있는 것입니다. 그런 다음 다음과 같이 할 수 있습니다.

MyObject obj = new MyObjectBuilder().setXxx(myXxx)
                                    .setYyy(myYyy)
                                    .setZzz(myZzz)
                                    // ... etc.
                                    .build();

See page 8 and following of this Josh Bloch presentation (PDF), or this review of Effective Java


Well, using the builder pattern might be one solution.

But once you come to 20 to 30 parameters, I would guess that there is a high relationship between the parameters. So (as suggested) wrapping them into logically sane data-objects probably makes the most sense. This way the data object can already check the validity of constraints between the parameters.

For all of my projects in the past, once I came to the point to have too many parameters (and that was 8 not 28!) I was able to sanitize the code by creating a better datamodel.


As you are constrained to Java 1.4, if you want DI then Spring would be a very decent option. DI is only helpful in places where the constructor parameters are services or something that does not vary during runtime.

If you have all of those different constructors due to the fact that you want variable options on how to construct an object, you should seriously consider using the Builder pattern.


The best solution is not having too much parameters in the constructor. Only parameters really needed in constructor, are params that are need to correctly initialize the object. You can have constructors with multiple parameters, but also have a constructor with only the minimum parameters. The additional constructors call this simple constructor and after that setters to set the other params. This way you can avoid the chain-problem with more and more params, but also have some convenience-constructors.


I can really recommend using Immutables or POJOBuilder when using the builder pattern.


Refactoring to reduce the number of parameters and depth of you inheritance hierarchy is pretty much all I can think of because, nothing is really going to help keep 20-something parameters straight. You're just going to have to every single call while looking at the documentation.

One thing you could do, is to group some logically grouped parameters into their own higher level object, but that has it's own problems.

참고URL : https://stackoverflow.com/questions/222214/managing-constructors-with-many-parameters-in-java

반응형