2011-01-04 3 views
5

「불변 오브젝트」의 클래스를 작성할 경우, 인스턴스의 상태를 변경할 수 없다는 것을 의미합니다. 생성자에 할당 된 모든 필드)를 Java (및 유사한 언어)로 수정 한 경우 수정 된 인스턴스를 만들 수있는 경우가 있습니다. 즉, 인스턴스를 기본으로 사용하고 하나의 속성 값만 다른 새로운 인스턴스를 만드는 것입니다. 다른 값은 기본 인스턴스에서옵니다. 그래서불변의 오브젝트로 사용되는 팩토리와 같은 (java) 메소드

public class Circle { 
    final double x, y; // location 
    final double radius; 

    public Circle(double x, double y, double r) { 
    this.x = x; 
    this.y = y; 
    this.r = r; 
    } 

    // method for creating a new instance, moved in x-axis by specified amount 
    public Circle withOffset(double deltaX) { 
    return new Circle(x+deltaX, y, radius); 
    } 
} 

: 간단한 예제를 제공하기 위해, 하나는 같은 클래스를 가질 수있다 "withOffset"방법은 무엇이라고해야 하는가? (참고 : 그 이름이 무엇이되어야하는지는 모르지만 -이 클래스의 메소드는 무엇이라고 불리는가). 기술적으로는 일종의 팩토리 메서드입니다. 그러나 어쨌든 공장은 기본 속성 만 제공되기 때문에 (정적 메서드이거나 결과 형식이지만 팩토리 형식의 멤버가 아니기 때문에) 나에게 맞지 않는 것처럼 보입니다.

그래서 나는 그러한 방법에 대해 더 나은 용어가 있어야한다고 생각합니다. 이 메소드는 "fluent interface"을 구현하는 데 사용할 수 있으므로 "유창한 팩토리 메소드"일 수 있습니까? 더 나은 제안이 있으십니까?

편집 : 답변 중 하나가 제안한대로 java.math.BigDecimal은 '추가', '빼기'등의 좋은 예입니다.

는 또한 : 나는

편집 (이 방법에 대한 구체적인 이름을 묻는 있지만) 종류의 관련입니다 (더 적은 존 소총에 의해) this question가 있다는 것을 눈치, 월 - 2014 년 : 나의 현재 좋아하는 mutant factory, FWIW입니다 .

+0

나는 그것을 부적절하게 명명 된 방법이라고 부릅니다. – Falmarri

+0

"move"와 "delta"는 기존 인스턴스의 속성의 변경 가능성을 암시합니다 ... – BoltClock

+0

실제 질문을 읽으십시오 - 메소드의 이름을 지정하는 방법을 묻지는 않았지만 메소드의 종류를 무엇이라고 부릅니다. 그러나 다른 사람들이 옆으로 넘어지지 않도록 코드를 약간 편집 할 것입니다. – StaxMan

답변

3

"복사 방법"이라고 부릅니다.

clone() 메서드는 정확한 복사본을 생성하지만 복사 메서드는 대개 묵시적 또는 명시 적 변형을 사용하여 인스턴스의 복사본을 만듭니다. 예를 들어, String#toUpperCase()은 변경 불가능한 String 클래스의 복사 메서드입니다. 변형 된 인스턴스를 복사합니다. 모든 문자를 가져옵니다.

예에서 withOffset() 메서드는 비슷한 복사 방법으로 간주됩니다.

"복사 방법"이라는 용어를 언급하는 자료는 없습니다. C++에서의 사용법에서 "복사"라는 용어를 빌리고 있습니다. 복사 생성자와 Taligent Coding Standards (more info)의 "copy"명명 지침입니다. 는 "유창 인터페이스는"단지 API 스타일 (빌더 패턴 분리)이기 때문에 용어는 "유창 팩토리 메소드"에 관해서는


, 나는 왜 "유창한"차이를 만들 것 모른다. "factory method"라는 용어가 여기에 적용되지 않는다면, 나는 그것을 "유창한 공장 방법"이라고 부르는 것이 어떻게 더 잘 적용되는지를 보지 못한다.

+0

유창한 부분은 유창한 스타일을 지원하기 위해 자주 사용되는 사실에 기반한 제안이었습니다. 그러나 유창한 스타일이 불변성을 요구하지는 않습니다 (또는 필연적으로 홍보하는 것과 같지 않습니다). "복사 방법"이 합리적으로 들리면 누구나 더 좋은 제안이 있는지 보자. (실제로 복사 생성자를 문제의 참조로 언급하려고했지만 가능한 혼란을 제거하려고 시도했습니다.) – StaxMan

1

이것은 실제로 공장 방법처럼 보이지 않습니다. 서명만으로도은 다른 호출에서 연결될 수 있다고 알려주지 만 새로운 인스턴스를 생성한다고 가정하지는 않습니다. 이 사용 사례는 append ("a")를 허용하는 StringBuilder와 더 비슷합니다. "비"). 물론 매번 새로운 StringBuilder를 반환 할 수 있습니다 (서클 에서처럼).

디자인 상 공장이 아닙니다. (인터페이스를 추출하고 그 메소드에 대한 JavaDoc을 작성하는 것을 생각해 보라. "나는 불변이므로 새로운 인스턴스를 리턴해야한다"- 왜 그런가?) 클래스가 변경되지 않는다는 사실은 구현 세부 사항이다.

편집 : Perahs 더 좋은 예는 BigInteger입니다. 그 또한 불변이므로. 새로운 인스턴스를 반환하고 아주 잘 귀하의 경우와 유사

BigInteger multiply(long v) 

: 다중 (BigInteger를)과 함께, 그것은 패키지 개인 방법을 제공합니다. 이것은 단순히 초기 객체와 동일한 유형의 결과를 반환하는 연산입니다. 공장이 아니기 때문에 이런 종류의 작업이 실제로 자체 이름에 어울리는 것은 아니라고 생각합니다.

+0

나는 팩토리 방식이 아니라는 점에 동의합니다. , 그래서 나는 더 나은 용어를 찾기를 바랐다. BigInteger가 좋은 예입니다. 그러나 이것을 넘어, 불변성은 여기에서 매우 중요한 측면입니다. 명확하게 구현 세부 사항이 아닙니다.이 메소드를 사용한 작업뿐만 아니라 전체 객체가 변경 가능해야합니다. 어쩌면 당신은 불변의 객체 스타일이나 이점에 익숙하지 않을 수 있습니까? 멀티 스레딩과 동시 데이터 구조를 통해 엄청난 도움을줍니다. StringBuilder를 사용하면 인스턴스를 반환하는 것이 체인 연결을 허용하는 편리한 방법 일뿐입니다. – StaxMan

+0

나는이 메소드가 변경 불가능하다고 말한 적이 없다. 불변성은 내 글의 Circle 클래스 객체를 참조한다. "implementatin 세부 사항"나는 그것을 분류하고 실제 구현을 무시하기 위해 그 메소드를 보려고하기 때문에 말했습니다. 내가 말하고자하는 것은 그것이 (인터페이스에서 선언 된) 추상 메소드라면, 당신이이 구현처럼 _all_ 구현이 필요하지는 않을 것입니다. 따라서이 동작이이 메서드에 필수적인 것은 아니라고 생각합니다. –

+0

나는 더 나은 예제를 발견했다 : String.concat() - CharSequence 인터페이스에서 온 것은 아니지만. javadoc에서는 "인수 문자열의 길이가 0이면이 String 객체가 반환됩니다." X 오프셋이 0이면 동일한 작업을 수행 할 수 있으므로 새 객체도 필요하지 않습니다. –

3

Hrm ... 그것은 돌연변이 된 버전의 개체를 만듭니다. 아마도 돌연변이 팩토리라고해야할까요? :-)

+0

Hehe, 나는 그것을 좋아한다. :) – StaxMan