2017-10-03 2 views
0

DDD 원칙에 따르면 값 개체는 자체 수명주기가없는 값을 인코딩하는 데 사용되지만 값은 그대로 사용하는 것이 좋습니다. 설계 상 이러한 객체는 불변으로 만들어집니다. 이들은 종종 프리미티브를 대체하기 때문에 코드가 의미 론적이며 오류에 안전합니다.변경 불가능한 값 개체의 변형 작업을위한 전략

이론적 근거는 매우 합리적이지만 때로는 일부 성가신 작업으로 이어집니다. 예를 들어, 어드레스가 라인을 따라 값 객체로 부호화하는 경우 고려해야 사용자가 주소의 한 필드를 변경하기위한 애플리케이션에서

class Address extends ValueObject { 
    public Address(String line1, String line2, String postalCode, String String country) { 
     ... 
    } 

    ... 
} 

를, 그 특이한 없을 것이다. 코드에서이를 달성하려면 다음과 같이해야합니다.

String newCity = ...; 

Address newAddress = new Address(
    oldAddress.getLine1(), 
    oldAddress.getLine2(), 
    oldAddress.getPostalCode(), 
    newCity, 
    oldAddress.getCountry()); 

이것은 매우 반복적이며 지나치게 자세한 코드로 이어질 수 있습니다. 불변의 가치 객체를 유지하면서 이것을 피하기위한 좋은 전략은 무엇입니까?

내 자신의 아이디어 :

  1. 개인 세터,이 같은 헬퍼 메소드를 사용 수 :

    public Address byChangingPostalCode(String newPostalCode) { 
        Address newAddress = this.copy(); 
        newAddress.setPostalCode(newPostalCode); 
        return newAdress; 
    } 
    

    단점은 객체가 이제 더 이상 불변이 아니라만큼이다 그건 사적인 것으로서, 문제가되어서는 안된다, 그렇지?

  2. 가치 개체를 대신 본격적인 개체로 만듭니다. 결국 장시간 수정해야 할 필드의 필요성은 수명주기가 있음을 나타냅니다. 나는 이것이 도메인 디자인보다는 개발자 편의성에 관한 것이기 때문에 이것으로 확신하지는 못한다.

나는 당신의 제안을 기쁘게받을 것입니다! 귀하의 제안에 대한

UPDATE

감사합니다! 나는 개인적인 세터와 교정 방법을 가지고 갈 것이다.

+0

사용 언어를. 예 : F # :'let newAddress = {oldAddress with PostalCode = 10005}' – guillaume31

답변

3

변경할 수없는 값이 다른 불변의 값을 반환하는 데는 아무런 문제가 없습니다.

Address newAddress = oldAddress.correctPostalCode(...); 

이것은 도메인 모델 내에서 내가 선호하는 방법입니다.

또 다른 가능성은 build 정말 유비쿼터스 언어의 일부가 아니므로 나는만큼 그 일을 좋아하지 않아

Address new Address = AddressBuilder.from(oldAddress) 
         .withPostalCode(...) 
         .build() 

빌더를 사용하는 것입니다. 이것은 단위 테스트에서 사용할 가능성이있는 구조입니다. API에 대한 전체 주소가 필요하지만 테스트 자체는 세부 정보의 하위 집합에만 의존합니다. 이 같은 헬퍼 메소드를 사용 할 수

+0

빌더 패턴을 생각 나게 해줘서 고마워. 그것이 도메인에서 보호되어야한다는 점에 동의하는 반면 개인적으로 또는 테스트와 마찬가지로 사용할 수 있습니다. –

1

개인 세터 :

내 선호하는 솔루션은 값 객체를 변화하고 있습니다.메소드의 이름은 유비쿼터스 언어에서 가져와야하지만 팀/프로그래밍 언어 규칙에 결합 할 수 있습니다. PHP에는 알려진 규칙이 있습니다. 불변의 명령 메소드 이름은 "with"로 시작합니다. 예 : withCorrectedName($newName).

개체는 완전히 상수가 아니어야하며 변경 불가능한 개체로만 간주되어야합니다.

가치 개체를 대신 본격적인 개체로 만듭니다.

더 이상 ValueObject가 아니므로 안됩니다!

+0

이러한 메서드의 명명 규칙을 고수하는 것은 매우 합리적인 것입니다. 감사! –

0

나는 파생 방법으로이 문제를 해결합니다 : 등등

Address newAddress = oldAddress.derive(newPostalCode); 

Address newAddress = oldAddress.derive(newLine1); 

그리고 ... 불변의 유형은 일류 시민

관련 문제