문제

나는 내가 작업하고 있는 프레임워크에 구문 설탕을 제공하는 방법을 생각해 왔습니다.나는 Immitable 객체만을 다루고 싶습니다.

불변 개체가 있고 그 개체의 수정된 버전을 만들고 싶다고 가정해 보겠습니다.귀하의 견해로는 단일 정적 팩토리 메소드를 사용하는 인스턴스화할 수 없는 클래스가 OO 원칙을 위반합니까?


문자열을 사용하는 예:

public final class LOWERCASE {

    private LOWERCASE() {}

    public static String string( final String STRING ) {

      return STRING.toLowerCase();
    }
}

따라서 이 예에서 다음과 같이 작성할 수 있습니다.

String lowercaseString = LOWERCASE.string( targetString );

나는 매우 읽기 쉽다고 생각합니다.


그러한 접근 방식에 대한 조항이 있습니까?

도움이 되었습니까?

해결책

메소드 당 하나의 클래스를 만드는 것이 좋은 생각이라고 생각하지 않습니다. 대신 eG stringUtils라는 정적 전용 메소드 클래스를 만들고 메소드를 구현할 수 있습니다. 이런 식으로 당신은 다음을 호출 할 것입니다.

String lowercasestring = stringUtils.lowercase (TargetString);

이것은 또한 타이핑하는 동안 Intellisense 도움을 제공합니다. 수업 목록은 그렇지 않으면 너무 커질 것입니다. 이 간단한 예제조차도 둘 이상의 소문자 클래스를 구현하여 CulutureInfo를 고려해야하는 상황을 충족시킬 수도 있습니다.

나는 이것이 어떤 식 으로든 원칙을 깨뜨 리거나 나쁜 디자인이라고 생각하지 않습니다. 예를 들어 다른 언어에서는 Methods를 String 클래스에 직접 추가 할 수 있습니다. 끝나는 방법! 원래 객체가 수정되었음을 나타냅니다. 다른 모든 메소드는 수정 된 사본을 반환합니다. Ruby on Rails 프레임 워크는 String 클래스에 몇 가지 방법을 추가하며 이것이 좋은 기술인지 아닌지에 대한 논쟁이 있습니다. 그래도 확실히 편리합니다.

다른 팁

일반적으로 불변의 물체에서는 개체의 수정 된 버전을 반환하는 메소드가 있습니다. 따라서 불변의 컬렉션이있는 경우 정렬 () 메소드가있어서 정렬 된 새 컬렉션을 반환 할 수 있습니다. 그러나 문자열 예에서는 문자열 클래스를 만질 수 없기 때문에 이것은 불가능합니다.

당신의 접근 방식은 매우 읽기 쉬우 며, 이와 같은 에지 케이스는 완벽하다고 생각합니다. 당신이 스스로 쓰는 불변의 대상의 경우, 나는 객체 자체에 대한 방법을 가질 것입니다.

C#의 불변의 대상에 대한 Eric Lippert의 시리즈 그건 그렇고 아주 좋습니다.

제 생각에, 그러한 공장 수업의 유일한 요점은 수업이 다른 종류의 불변의 대상을 제공 한 경우입니다.

전:

public final class Lowercase {

  private Lowercase() {}

  public static String string( final String string ) {

   return new String( string.toLowerCase() );
  }

  public static Foo foo( final Foo f ) {
     boolean isLowerCase = true;
     return new Foo(f, isLowerCase );
  }
}

그렇지 않으면 문자열 클래스에서 tolowercase ()와 같은 불변 클래스 자체에서 메소드를 구현해야합니다.

어느 쪽이든, 나는 이것이 어떤 oo 원칙이라고 생각하지 않습니다.

나는 에릭의 말에 동의한다.불변 객체에는 항상 정적 메소드보다는 객체의 수정된 버전을 반환하는 메소드가 있어야 합니다.JDK에도 예제가 있습니다:

  • 문자열.하위 문자열(int)
  • BigDecimal.movePointLeft(int)

이 방법을 사용하면 수정하려는 인스턴스를 메서드의 인수로 전달할 필요가 없다는 이점이 있습니다.String 또는 Integer와 같은 클래스의 경우 래퍼 클래스를 사용하는 것을 선호합니다.그런 다음 해당 객체가 생성되는 시점을 제어할 수 있습니다(래퍼 클래스의 생성자 또는 클래스의 메서드 중 하나를 통해).Integer 클래스를 사용하는 경우 모든 사람이 인스턴스를 생성할 수 있으므로 이를 제어하는 ​​것이 훨씬 더 복잡합니다.

반면에 당신의 예는 다음과 같은 일부 유틸리티 클래스로 간주됩니다. StringUtils Apache commons-lang 패키지 중 하나입니다.당신이 이와 같은 것을 만들고 싶었다고 생각하므로 이것을 살펴보십시오.(바퀴를 재발명하지 마세요)

new String() 코드 냄새입니다 - 거의입니다 언제나 불필요한 불변성String. 한 번 a String 인스턴스에는 값이 있으며 인스턴스는 결코 다른 값을 가지지 않습니다.

다음 방법에서 new String() 중복 :

public static String string( final String string ) {
    return new String( string.toLowerCase() );
}

toLowerCase() 새로운 (다른)를 반환합니다. String 사례 - new String() 여기에서 유익한 일을하지 않습니다. String 인스턴스가 반환되었습니다 toLowerCase()

다음은 개념을 보여주는 작은 그루비 스크립트입니다 (희망 - 이것은 스크립팅 언어의 Java입니다) :

String a = 'CamelCase'
String b = a.toLowerCase()

println "a='${a}'"
println "b='${b}'"

생산

a='CamelCase'
b='camelcase'

주목하십시오 a 변하지 않았습니다 - 그것은 불변입니다. b 새로운 것입니다 String 값.

마찬가지입니다 BigDecimal.movePointLeft() 또는 다른 방법으로 BigDecimal a BigDecimal - 새로운 인스턴스로 원래 인스턴스를 변경하지 않습니다.

좋아, 이제 질문에 답하기 위해 :

작업 세트가 있습니다 Strings 응용 프로그램에서 유용한 목적을 수행하는 것은 훌륭한 아이디어입니다. 공장을 사용하는 것은 아마도 같은 것에 필요하지 않을 것입니다 String, 그러나 건설에 약간의 노력이 필요한 다른 불변의 계급 일 수 있습니다.

기본 클래스를 연장 할 수없는 경우, String, ㅏ static method@kgiannakakis에 설명 된 S 클래스는 괜찮습니다.

그렇지 않으면, "불변"클래스가 응용 프로그램의 일부인 경우 클래스 선언/정의에 액세스 할 수있는 경우, 모델에서 새 인스턴스를 반환하는 방법. BigDecimal, String, 등이 바람직합니다. 이것은 본질적으로 @erik hesselink, @bruno conde 및 @reallyinsane이 말한 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top