인수가 많은 생성자를 피하십시오


10

그래서 다른 클래스의 객체를 만드는 팩토리가 있습니다. 가능한 클래스는 모두 추상 조상에서 파생됩니다. 팩토리에는 구성 파일 (JSON 구문)이 있으며 사용자 구성에 따라 작성할 클래스를 결정합니다.

이를 위해 팩토리는 JSON 구문 분석에 boost :: property_tree를 사용합니다. 그는 ptree를 통해 어떤 콘크리트 객체를 만들지 결정합니다.

그러나 product-objects에는 많은 필드 (속성)가 있습니다. 구체적인 클래스에 따라, 객체는 약 5-10 개의 속성을 가지게되며, 앞으로는 더 많은 속성을 가질 수 있습니다.

따라서 객체 생성자가 어떻게 생겼는지 잘 모르겠습니다. 두 가지 해결책을 생각할 수 있습니다.

1) 제품의 생성자는 모든 속성을 매개 변수로 예상하므로 생성자는 10 개 이상의 매개 변수로 끝납니다. 이것은 추악하고 읽을 수없는 길고 읽을 수없는 코드 줄로 이어질 것입니다. 그러나 팩토리는 JSON을 구문 분석하고 올바른 매개 변수로 생성자를 호출 할 수 있다는 장점이 있습니다. 제품 클래스는 JSON 구성으로 인해 생성되었음을 알 필요가 없습니다. JSON 또는 구성이 전혀 없다는 것을 알 필요는 없습니다.

2) 제품의 생성자는 property_tree 객체라는 하나의 인수 만 기대합니다. 그런 다음 필요한 정보를 구문 분석 할 수 있습니다. 구성의 정보가 누락되었거나 범위를 벗어난 경우 각 제품 클래스가 올바르게 반응 할 수 있습니다. 공장은 여러 제품에 어떤 인수가 필요한지 알 필요가 없습니다. 공장은 또한 잘못된 구성의 경우 대응 방법을 알 필요가 없습니다. 그리고 생성자 인터페이스는 통합되고 작습니다. 그러나 단점으로, 제품은 JSON에서 필요한 정보를 추출해야하므로 제품 구성 방법을 알고 있습니다.

나는 해결책 2)를 선호하는 경향이 있습니다. 그러나 이것이 좋은 공장 패턴인지 확실하지 않습니다. JSON 구성으로 생성되었음을 제품에 알리는 것이 어떻게 든 잘못된 느낌입니다. 다른 한편으로, 신제품은 매우 간단하게 소개 될 수 있습니다.

그것에 대한 의견이 있습니까?



1
나는 당신의 링크를 따랐다. 래칫 괴물의 최고 답변에 예가 있습니다. 그러나이 "빌더"접근법은 어떤 문제를 해결합니까? 코드 라인 DataClass data = builder.createResult ();가 있습니다. 그러나 createResults ()-method는 여전히 10 개의 매개 변수를 DataClass 객체로 가져와야합니다. 그러나 어떻게? 추상화 계층이 하나 더있는 것 같지만 DataClass의 생성자는 더 작아지지 않습니다.
lugge86

빌더와 프로토 타입을 살펴보십시오.
Silviu Burcea

Silviu Burcea, 했어요 그러나 빌더를 사용할 때 빌더는 어떻게 매개 변수를 제품으로 가져 옵니까? 어딘가에 뚱뚱한 인터페이스가 있어야합니다. 빌더는 하나 이상의 계층이지만 매개 변수는 제품 클래스로 들어가야합니다.
lugge86

1
클래스가 너무 크면 생성자 인수를 바꾸어도 너무 크지 않습니다 .
Telastyn

답변:


10

옵션 2를 사용하지 않을 것입니다. 왜냐하면 부스트 속성 트리 파싱으로 객체의 구성을 영원히 뒤얽었기 때문입니다. 많은 매개 변수가 필요한 클래스에 익숙하다면 인생과 같은 많은 매개 변수가 필요한 생성자에 익숙해야합니다!

코드 가독성이 주요 관심사 인 경우 빌더 패턴을 사용할 수 있습니다. 기본적으로 명명 된 인수가 없기 때문에 c ++ / java stopgap입니다. 다음과 같은 결과가 나타납니다.

MyObject o = MyObject::Builder()
               .setParam1(val1)
               .setParam2(val2)
               .setParam3(val3)
             .build();

이제 MyObject는 개인 생성자를 갖게되는데, 생성자 :: build에서 호출됩니다. 좋은 점은 10 개의 매개 변수가있는 생성자를 호출 해야하는 유일한 장소라는 것입니다. 부스트 특성 트리 팩토리는 빌더를 사용하며, 이후 MyObject를 직접 또는 다른 소스에서 구성하려는 경우 빌더를 거치게됩니다. 또한 빌더는 기본적으로 각 매개 변수를 전달할 때 명확하게 이름을 지정할 수 있으므로 더 읽기 쉽습니다. 이것은 분명히 상용구를 추가하므로 지저분한 생성자를 호출하거나 기존 매개 변수 중 일부를 구조체 등으로 묶는 것과 비교할 가치가 있는지 결정해야합니다. 테이블에 다른 옵션을 던지기 만하면됩니다.

https://en.wikipedia.org/wiki/Builder_pattern#C.2B.2B_Example


5

두 번째 방법을 사용하지 마십시오.

그것은 확실히 해결책이 아니며 팩토리가있는 앱의 일부 대신 비즈니스 로직에서 클래스를 인스턴스화 할뿐입니다.

어느 한 쪽:

  • 비슷한 것을 나타내는 것으로 보이는 특정 매개 변수를 객체로 그룹화하십시오.
  • 현재 클래스를 여러 개의 작은 클래스로 나눕니다 (10 개의 매개 변수를 가진 서비스 클래스를 갖는 것은 클래스가 너무 많은 것처럼 보입니다)
  • 클래스가 실제로 서비스가 아니라 대신 값 객체 인 경우 그대로 두십시오.

작성하는 오브젝트가 실제로 데이터를 보유하는 클래스가 아닌 경우 코드를 리팩토링하고 큰 클래스를 작은 클래스로 분할해야합니다.


bsiness 논리는 제품을 반환하는 팩토리를 사용하므로 비즈니스 논리에는 JSON / ptree 항목이 표시되지 않습니다. 그러나 construcotr에 파서 코드가 있다고 생각하면 잘못되었습니다.
lugge86

이 클래스는 임베디드 시스템을위한 GUI의 위젯을 나타내므로, 5 개 이상의 속성이 나에게는 괜찮은 것 같습니다 : x_coord, y_coord, backgroundcolor, framesize, framecolor, text ...
lugge86

1
@ lugge86 팩토리를 사용하여 JSON을 구문 분석하므로 new비즈니스 로직 내부에서 객체를 호출 하거나 구성하지 않아도 디자인이 좋지 않습니다. 체크 할 일을 일을 찾지 Miško Hevery에 의해 이야기 는 암시 공장 접근 방식은 테스트 및보기의 읽기 지점 모두에서 나쁜 이유를 더 깊이 설명합니다. 또한 클래스는 데이터 객체 인 것처럼 보이며 일반적으로 일반 서비스 클래스보다 많은 매개 변수를 갖는 것이 좋습니다. 나는 너무 귀찮게하지 않을 것입니다.
Andy

나는 공장 접근 방식에 대해 기분이 좋지만 귀하의 링크를 따라 생각할 것입니다. 그러나이 주제에서는 공장에 문제가 없습니다. 문제는 여전히 제품을 설정하는 방법입니다.
lugge86

"매개 변수가 10 개인 서비스 클래스를 갖는 것은 클래스가 너무 많은 일을하는 것처럼 보입니다."머신 러닝이 아닙니다. 모든 ML 알고리즘에는 수많은 조정 가능한 매개 변수가 있습니다. ML을 코딩 할 때이를 처리하는 올바른 방법이 무엇인지 궁금합니다.
Siyuan Ren

0

옵션 2가 거의 옳습니다.

개선 된 옵션 2

JSON 구조 객체를 가져 와서 비트를 선택하고 팩토리 생성자를 호출하는 작업을 수행하는 "전면"클래스를 만듭니다. 그것은 공장에서 만든 것을 가져 와서 클라이언트에게 제공합니다.

  • 팩토리는 그러한 JSON이 존재한다는 것을 전혀 모릅니다.
  • 클라이언트는 팩토리에 필요한 특정 비트를 알 필요가 없습니다.

기본적으로 "프론트 엔드"는 2 명의 Bob에게 다음 과 같이 말합니다 . " 수정 된 고객을 처리하므로 엔지니어가 필요하지 않습니다! 사람들에게 기술이 있습니다!" 불쌍한 톰. "고객과 공사를 분리합니다.이 결과는 매우 응집력있는 공장입니다"; 그는 일을 계속했을 수도 있습니다.

너무 많은 인수?

클라이언트 용이 아닙니다-프론트 엔드 통신.

프론트 엔드-공장? 10 개의 매개 변수가 아닌 경우 압축 해제를 해제하는 것이 가장 좋습니다. 원래 JSON이 아니라면 DTO입니다. JSON을 공장으로 전달하는 것보다 낫습니까? 내가 말하는 것과 같은 차이점.

개별 매개 변수를 전달하는 것이 좋습니다. 깨끗하고 응집력있는 공장의 목표를 고수하십시오. @DavidPacker 답변 의 우려를 피하십시오 .

"너무 많은 주장"완화

  • 팩토리 또는 클래스 생성자

    • 특정 클래스 / 객체 구성에 대한 인수 만 취합니다.
    • 기본 매개 변수
    • 선택적 매개 변수
    • 명명 된 인수
  • 프런트 엔드 인수 그룹화

    • 위의 생성자 시그니처에 의해 유도 된 인수 값을 검사, 평가, 유효성 검증, 설정 등을 수행합니다.

"공장은 그런 JSON도 존재한다는 것을 전혀 모른다"-그렇다면 공장은 무엇인가? 제품 및 소비자 모두에서 제품 생성에 대한 세부 정보를 숨 깁니다. 왜 또 다른 수업이 도움이됩니까? 나는 공장에서 말하는 JSON으로 괜찮습니다. 하나는 XML 파싱을위한 다른 팩토리를 구현하고 미래에 "Abstract Factory"를 구현할 수 있습니다.
lugge86

Mr. Factory : "어떤 개체를 원하십니까? ... 저것은 무엇입니까? 어떤 클래스 개체를 만들지 말씀해주십시오." 구성 파일 JSON은 밥 삼촌이 "구현 세부 사항"이라고 말한 것처럼 데이터 소스입니다. 다른 출처 및 / 또는 다른 형태 일 수도 있습니다. 일반적으로 특정 데이터 소스 세부 사항에서 분리하려고합니다. 소스 나 형태가 바뀌더라도 공장은 바뀌지 않습니다. 소스 + 파서가 있고 분리 된 모듈로 공장을 사용하면 둘 다 재사용 할 수 있습니다.
radarbob
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.