당신은 어떤 돌연변이 방법이없는 interface
을 제공합니다. 그런 다음 작성자에게만 알려진 변경 가능한 구현을 제공합니다. 당신이 사방 Person
개체를 반환하는 경우이 시점에서
public interface Person
{
String getName();
}
public class MutablePerson implements Person
{
private String name;
public MutablePerson(String name)
{
this.name = name;
}
@Override
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
는, 누군가가 반환 된 객체를 수정하는 유일한 방법은 속임수와
MutablePerson
로 다시 캐스팅하는 것입니다. 실제로 코드가 완전한 해킹이 아니면 변경 가능한 객체는 변경되지 않습니다.
Person person = new MutablePerson("picky");
// someone is cheating:
MutablePerson mutableAgain = (MutablePerson)person;
mutableAgain.setName("Phoenix");
// person.getName().equals("Phoenix") == true
실제 구현이 변경 가능한주의 할 것이다, 따라서 그들은 그것을 변경 캐스트 할 수 있습니다 젊은 프로그래머의 무리와 함께 처리하지 않을 경우, 당신은 넣을 수 있다는 장점과 불변성의 안전을 제공 함께 무한한 생성자가 없거나 빌더를 사용합니다 (실제로 변경 가능한 버전은 빌더입니다). 변경 가능한 버전을 악용하는 개발자를 피하는 좋은 방법은 변경 가능 버전을 패키지 전용으로 두어 패키지 만 알 수 있도록하는 것입니다. 이 아이디어의 부정은 이것이 동일한 패키지에서 인스턴스화 될 경우에만 작동한다는 것입니다. 그러나 DAO가 여러 패키지 정의 구현 (예 : , MySQL, Oracle, Hibernate, Cassandra 등 모든 패키지가 동일한 패키지를 돌려주고, 패키지가 어수선하게 흩어지는 것을 피하기 위해 서로 분리되어 있기를 바랍니다.
실제 키는 사람들이 추가 인터페이스를 구현하는 것을 제외하고는 Mutable 개체에서 빌드해서는 안됩니다. 확장하고, 불변의 서브 클래스를 돌려주는 경우, 정의에 의해 가변 오브젝트를 공개하면 (자) 불변은 아닙니다. 예를 들면 :
public interface MyType<T>
{
T getSomething();
}
public class MyTypeImpl<T> implements MyType<T>
{
private T something;
public MyTypeImpl(T something)
{
this.something = something;
}
@Override
public T getSomething()
{
return something;
}
public void setSomething(T something)
{
this.something = something;
}
}
public interface MyExtendedType<T> extends MyType<T>
{
T getMore();
}
public class MyExtendedTypeImpl<T>
extends MyTypeImpl<T>
implements MyExtendedType<T>
{
private T more;
public MyExtendedTypeImpl(T something, T more)
{
super(something);
this.more = more;
}
@Override
public T getMore()
{
return more;
}
public void setMore(T more)
{
this.more = more;
}
}
이 자바 Collection
의 구현 했어야하는 방식은 정직입니다. 읽기 전용 인터페이스는 Collections.unmodifiable
구현을 대체 할 수 있으므로 예기치 않게 변경 불가능한 객체의 변경 불가능한 버전을 사용하지는 않습니다. 바꾸어 말하면, 당신은 불변성을 결코 숨겨서는 안되지만, 당신은 변경 가능성을 숨길 수 있습니다.
그런 다음 진정으로 수정할 수없는 변경 불가능한 인스턴스를 뿌리면 개발자가 정직하게 유지할 수 있습니다. 나는 그 문이 잘 나가셨 아니라고 생각
public class MyTypeImmutable<T> implements MyType<T>
{
private final T something;
public MyTypeImmutable(T something)
{
this.something = something;
}
@Override
public T getSomething()
{
return something;
}
}
정말 멋진 예제가 가득합니다 !! +1 – Tivie