디자인 : 객체를 매개 변수로 사용하는 별도의 클래스 방법과 객체 방법?


14

예를 들어 다음을 수행하는 것이 좋습니다.

Pdf pdf = new Pdf();
pdf.Print();

또는:

Pdf pdf = new Pdf();
PdfPrinter printer = new PdfPrinter();
printer.Print(pdf);

또 다른 예:

Country m = new Country("Mexico");
double ratio = m.GetDebtToGDPRatio();

또는:

Country m = new Country("Mexico");
Country us = new Country("US");
DebtStatistics ds = new DebtStatistics();
double usRatio = ds.GetDebtToGDPRatio(us);
double mRatio = ds.GetDebtToGDPRatio(m);    

마지막 예에서 나의 관심사는 국가에 대해 알고 싶어 할 수있는 끝없는 통계가 있다는 것입니다. 그들은 모두 국가 개체에 속합니까?

예 :

Country m = new Country("Mexico");
double ratio = m.GetGDPToMedianIncomeRatio();

이것들은 단순한 비율이지만 통계가 방법을 보증하기에 충분히 복잡하다고 가정합니다.

객체에 내재 된 작업과 객체에 대해 수행 할 수 있지만 그 일부는 아닌 작업 사이의 선은 어디에 있습니까?

답변:


16

PDF 예제를 시작점으로 삼아 살펴 보겠습니다.

http://en.wikipedia.org/wiki/Single_responsibility_principle

단일 책임 원칙 (Single Responsibility Principle)은 대상이 단 하나의 목표를 가져야한다고 제안합니다. 이것을 명심하십시오.

http://en.wikipedia.org/wiki/Separation_of_concerns

우려의 분리 원칙은 클래스에 중복되는 기능이 없어야 함을 알려줍니다.

이 두 가지를 살펴보면 논리가 의미가있는 경우에만 해당 클래스가 처리해야하는 경우에만 논리가 클래스에 들어가도록 제안합니다.

이제 PDF 예제에서 문제는 누가 인쇄를 담당합니까? 무슨 의미가 있습니까?

첫 번째 코드 스 니펫 :

Pdf pdf = new Pdf();
pdf.Print();

이것은 좋지 않습니다. PDF 문서는 자체 인쇄되지 않습니다. 프린터에 의해 인쇄됩니다. 따라서 두 번째 코드 스 니펫이 훨씬 좋습니다.

Pdf pdf = new Pdf();
PdfPrinter printer = new PdfPrinter();
printer.Print(pdf);

이것은 말이됩니다. PDF 프린터는 PDF 문서를 인쇄합니다. 더 좋은 방법은 프린터가 PDF 프린터 나 사진 프린터가되어서는 안됩니다. 최고의 성능으로 전송 된 자료를 인쇄 할 수있는 프린터 여야합니다.

Pdf pdf = new Pdf();
Printer printer = new Printer();
printer.Print(pdf);

간단합니다. 적절한 방법을 사용하십시오. 분명히, 항상 그렇게 간단한 것은 아닙니다. 국가 통계를 예로 들어 보겠습니다.

Country m = new Country("Mexico");
double ratio = m.GetDebtToGDPRatio();

귀하의 우려는 n 개의 통계 가있을 수 있으며 Country 클래스에 있으면 안된다는 것입니다. 사실입니다. 그러나 모델 이 특정 통계 만 요구하는 경우이 모델링 예제가 실제로 적합 할 수 있습니다.

이 경우 국가가 모델 및 현재 요구 사항에 따라 자체 통계를 계산할 수 있어야한다는 것을 논리적으로 말할 수 있습니다.

그리고 거기에 문제가 있습니다 : 당신의 요구 사항은 무엇입니까? 귀하의 요구 사항은 세계를 모델링하는 방식, 이러한 요구 사항이 충족되는 컨텍스트를 주도합니다.

실제로 다수 / 가변 수의 통계가있는 경우 두 번째 예가 더 적합합니다.

Country m = new Country("Mexico");
DebtStatistics ds = new DebtStatistics();
double usRatio = ds.GetDebtToGDPRatio(m);

더 좋은 방법은 국가를 매개 변수로 사용하는 통계라는 추상 슈퍼 클래스 또는 인터페이스를 사용하는 것입니다.

interface StatisticsCalculator // or a pure abstract class if doing C++
{
   double getStatistics(Country country); // or a pure virtual function if in C++
}

DebtToGDPRatioStatisticsCalculator 클래스는 StatisticsCalculator를 구현합니다.

InfantMortalityStatisticsCalculator 클래스는 StatisticsCalculator를 구현합니다 ...

그리고 등등. 일반화, 위임, 추상화로 이어집니다. 통계 수집은 특정 추상화 (통계 수집 API) 를 일반화 하는 특정 인스턴스에 위임 됩니다 .

이것이 귀하의 질문에 100 % 대답하는지 모르겠습니다. 결국, 우리는 불가침의 법에 근거한 완벽한 모델을 가지고 있지 않습니다 (EE 사람들처럼). 그리고 그것은 당신이 결정해야 할 공학적 결정입니다. 가장 좋은 방법은 OO 원칙 (및 일반적으로 좋은 소프트웨어 모델링 원칙)에 익숙해지는 것입니다.


1
StatisticsCalculator 인터페이스 및 전략 패턴의 후속 사용에 +1 그리고 철저히 잘 생각 된 답변
edwardsmatt

3
현재로서는 이것을 완전히 해체 할 시간이 충분하지 않지만, 프린터 클래스는 시간이 지남에 따라 모든 종류의 문서 클래스와 밀접하게 결합 된 신 클래스가 될 것임을 지적해야합니다. Pdf.Print가 바람직 할 것입니다. 그러나 그것은 모두 '단일 책임'을 어떻게 정의 하느냐에 달려 있습니다. ;-)
Steven A. Lowe

@Steve-당신이 제안하는 것은 끔찍한 아이디어입니다 (PDF는 print ()를 구현합니다). 실제 인쇄가 어떻게 구현되는지는 반영하지 않습니다. 내가 아는 모든 운영 체제 및 인쇄 API는에 대한 추상화를 제공합니다 Printer. XP / Vista 시스템의 프린터 목록 (또는 / var / spool 또는 * nix의 해당 항목)을보십시오. 각 응용 프로그램은 문서 개체를 해당 프린터 중 하나로 직렬화합니다. Word 프린터 나 텍스트 프린터 또는 PDF 프린터가 없습니다. 인쇄 장치에만 해당되는 문서 만 있고 문서 유형에만 해당 되는 프린터는 없습니다.
luis.espinal

2
+1 나는 당신이 한 말을 깊이 생각하고 있습니다. @Steve and luis : God 객체에 대한 토론에서 누락 된 부분은 일반적인 Printer 객체가 ASCII 또는 비트 맵과 같은 몇 가지 표준 형식을 받아 들여야한다고 생각합니다 (pdf에도 불구하고) 아마도 합리적 일 것입니다. 특정 문서 유형 (예 : ms 단어 문서)을 이러한 표준 형식 중 하나로 변환하는 것은 일부 클래스의 책임이어야합니다.
사용자

2
아마도 PDF는 Canvas 인터페이스 또는 Image 객체로 렌더링하여 Printer 객체로 처리 할 수 ​​있어야합니다.
Winston Ewert

4

나는 둘 다 다른 것보다 확실히 낫다고 생각합니다. pdf.Print ()를 사용하는 것이 더 빠르지 만 다음과 같은 경우 PdfPrinter 클래스를 사용하는 것이 좋습니다.

  • 프린터 인스턴스를 관리해야합니다
  • pdf.Print (...) 복잡성을 날려 버릴 수있는 다양한 옵션과 작업이 있습니다 (예 : 인쇄 취소, 추가 서식 등).

그렇지 않으면 나는 그것에 매달리지 않을 것입니다.


좋고 실질적인 답변; 시간은 이것이 어떻게 진화해야하는지 말할 것입니다
Steven A. Lowe

1
짧은 제안은 SRP를 적용 할 때 로직과 데이터 를 모두 살펴보고 더 일찍 분리 하지 않는 것을 후회할지 여부를 결정 하는 것입니다. Pdf클래스 당 프린터 별 설정을 저장할 때의 문제점은 함께 저장 Pdf되어서는 안되며 파일에 저장되지만 프린터 별 설정은 사용자 / 컴퓨터 프로파일과 함께 저장되어야한다는 것입니다.
rwong
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.