2012-02-14 3 views
5

개체가 있다고 가정 해 보겠습니다. 차별화 된 여러 가지 방법이 있습니다. 어쩌면 얼룩 같아 질지 모르지? (반 패턴에서와 같이 "blob") 이러한 메서드는 별개의 세트로 작동하며 실제로 기능을 수행하지는 않습니다.새로운 방법은 어디에 있습니까?

Car 
# methods related to suburban driving 
    ->foo1 
    ->foo2 
# methods related city driving 
    ->bar3 
    ->bar4 

자 이제 내 차 객체가 지원할 수있는 사례 중 하나 인 "도로 주행 중"을 추가하고 싶다고 가정 해 보겠습니다. 만약 내가 Car 객체에 메소드를 추가한다면, 더 많은 BLOB를 만드는 것이 아닌가?

Car (augmented) 
# methods related to suburban driving 
    ->foo1 
    ->foo2 
# methods related city driving 
    ->bar3 
    ->bar4 
# methods related off road driving 
    ->blah5 
    ->blah6 

해야하는 I :

A : 서브 클래스 자동차. 내가 OffRoadCar 자동차 개체를 확장 할 수 있습니다. 그러나 Car와 OffRoadCar가 동일한 데이터/상태를 공유하고 메소드에 의해서만 다른 경우에는 어떻게 될까요? OffRoadCar는 자동차보다 구체적으로 "작동"하지만 더 이상 구체적으로 설명되지 않으며 고유 한 필드가 없습니다. 따라서 OffRoadCar를 인스턴스화하는 것은 의미가 없습니다.

OffRoadCar extends Car 
# methods related off road driving 
    ->blah5 
    ->blah6 

B : 정적 메소드 차량용 소비한다. OffRoadAdventure-> Embark (자동차)처럼. 따라서 OffRoadAdventure 클래스는 Car 객체를 가져 와서 그 객체를 사용합니다.

C#에서는 이것을 확장 메서드라고 부릅니다.

다른 방법으로 넣으십시오. 블롭 반 패턴에 대한 해결책은 무엇입니까? 서브 클래 싱인가요? 확장 메소드입니까?

또 다른 이유는 내가 다른 클래스/패키지를 포함하는 것과 같이 비용이 발생한다면 어떻게해야할까요? 핵심 수업의 사용자가 결코 사용하지 않을 무언가를 끊임없이 지불하는 것을 원하지 않습니다. 소수에 대한 비용을 명시하는 것이 대다수의 비용 절감에 가치가 있다고 생각합니다. 그리고 의존성 그래프가 더 정확 해집니다 (blob과 유사하지 않습니다).

PS - 구현 언어는 Perl입니다.

+0

자동차는 수업이어야합니까? 자동차가 실제로 ICar (인터페이스) 일 수 있습니까? 나는 상속에 대한 구성의 경로를 제안 할 것이다. – OnResolve

+0

자동차는 이미 사용중인 실제 수업입니다. (실제로 ORM 아티팩트입니다.) –

답변

0

나는 당신이 올바른 길에 있다고 생각합니다. 우아한 해결책은 OffRoadCar을 Car에서 상속 받고 Drive() 메서드를 재정의하는 것입니다. 그런 식으로, 당신은 말할 수 :

Car myCar = new OffRoadCar(); 
myCar.Drive(); 

이는 서브 클래스에서 오버라이드 (override) Drive() 메소드를 호출, 당신은 하나의 "덩어리"에 gazillion 방법으로 끝낼하지 않습니다. 펄

@Override 
public void Drive() 
{ 
/* code */ 
} 
2

당신이 무스와 역할에서 좋은 모습을 복용해야한다 : 여기 OffRoadCar에서 Drive() 방법처럼 보일 수 있습니다 방법입니다.

package Suburban; 
use Moose::Role; 

requires 'wheels'; 

sub 'foo1' { 
    ... 
} 


sub 'foo2' { 
    ... 
} 

package City; 
use Moose::Role; 

requires 'wheels'; 

sub 'bar3' { 
    ... 
} 


sub 'bar4' { 
    ... 
} 

package Offroad; 
use Moose::Role; 

requires 'wheels'; 

sub 'blah5' { 
    ... 
} 


sub 'blah6' { 
    ... 
} 

package UltraCar; 
use Moose; 

with qw/ Offroad City Suburban /; 
has 'wheels' => (is => 'rw', isa => 'Int', default => 4); 

package RentalCar; 
use Moose; 

with qw/ City Suburban /; 
has 'wheels' => (is => 'rw', isa => 'Int', default => 4); 

package Tricycle; 
use Moose; 

with qw/ Offroad /; 
has 'wheels' => (is => 'rw', isa => 'Int', default => 3); 

런타임에 역할을 추가하거나 제거 할 수도 있습니다.

+1

이 문제는 BLOB 문제를 어떻게 해결합니까? 역할/인터페이스는 동일한 계약을 수행하는 서로 다른 클래스 용입니다. –

+1

블롭의 문제점은 객체의 모든 기능을 단일 위치로 롤백한다는 것입니다. 역할을 사용하면 이질적인 기능을 별도의 테스트 가능한 코드 모듈로 분리 한 다음 필요에 따라 객체에 적용 할 수 있습니다. 런타임에는 그렇습니다. 여전히 'blobby god object'를 가지고 있지만, 그 시점에서 그 반 패턴에 대한 문제가 다시 발생하기 때문에 걱정하지 않아도됩니다. 런타임에 역할을 적용 할 수 있기 때문에 필요한 기능 만 롤에 추가 할 수 있으며 불필요한 성능 저하를 방지 할 수 있습니다. – Oesor

+0

수정 사항이 더 명확합니다. 그러나 기술적 인 한계에 따라 Moose를 사용할 수 없습니다. 나는 네가하는 말을 알았다. –

0

Car 클래스를 서브 클래스 화하는 대신 Decorator pattern의 형식을 사용할 수 있습니다.

여기에서 기본 ORM 클래스와 데코레이터 (예 : OffRoadDecorator)는 공통 인터페이스를 구현하고 각 데코레이터의 동작을 원래 클래스에 동적으로 추가 할 수 있습니다.

가장 큰 차이점은 동일한 Car 클래스에서 여러 장식자를 사용할 수 있다는 점입니다. 이러한 상호 작용 방법은 구현에 달려 있습니다. OffRoadDecoratorSuburbanDecorator을 사용하여 수업을 꾸미는 것을 막을 수있는 방법은 없으며 데코레이터 내에서 그 자동차가 의미하는 바를 정확하게 결정할 수 있습니다.

(내가 어떤 코드 예제를 제공하지 않는 PS 죄송합니다,.. 내 펄이 다른 예제 this page에서보세요 단순히 끔찍한) 마크

0
정말

되지 않음 대답 내가 얼마나 깊이 확실하지 않다 당신은 이것에 들어가고 싶지만, 당신은 Method Resolution Order 아이디어를 들여다 볼 수 있습니다. 메서드에 대한 표준 깊이 우선 검색 대신 mro을 사용하면 광범위한 첫 번째 검색을 수행 할 수 있습니다. CPAN의 this pagebrian d foyUse the C3 method resolution order in multiple inheritance 문서를 참조하십시오.

0

교외, 도시 및 Offroad 알고리즘과 같은 운전 소리. Strategy Pattern은 Context being car (컨텍스트 인 자동차)에 도움이 될 수 있습니다.

관련 문제