2016-11-29 10 views
0

면책 조항 - 이것은 학교 학기 프로젝트의 일부입니다.Java의 메멘토 패턴 - 내부 클래스의 serialization

개체 상태를 저장하려면 Memento 패턴을 사용해야합니다. 이 객체는 MVC의 모델입니다. 그래서 지금 (간체)되어있는 방법은 :

public class Model { 
    // ... 
    public static class Memento implements Serializable { 
     protected Stats stats; 

     public Memento(Stats stats) { 
      this.stats = stats; 
     } 
    } 

    public static class Stats implements Serializable { 
      protected int score; 
      protected int cannonPos; 
      protected int cannonAngle; 
      protected int cannonSpeed; 
      protected int totalShotsFired = 0; 
      protected int enemiesHit; 
      protected transient List<StatsObserver> observers = new ArrayList<StatsObserver>(); 
      // + getters etc 
    } 
} 

나는 외부 클래스가없는 동안 직렬화 내부 클래스를 가진 것은 합리적인 이유가 자바에서 정말 불가능하다는 것을 읽었습니다. 그러나 내 경우에는 내부 클래스가있을 때 외부 클래스를 인스턴스화 할 필요가 없습니다. 내부는 전혀 외부가 필요하지 않습니다. 외부 클래스가 내부 구성원을 액세스 할 수 있도록이 구조로만 구성됩니다.

enter image description here

... 그뿐만 아니라 의미가 있습니다 :

이 내 과정의 유품 설명의 말씀입니다. 모델 만이 Memento 내부의 세부 정보에 액세스 할 수 있어야합니다. "Caretaker"객체 (디스크에서 /로 데이터 저장/검색을 처리하는 객체)는 객체 내부에서 보지 않아야합니다. Java에는 친구 클래스가 없으므로이 방법이 있어야합니다.

제안 된대로 구현하려면 직렬화를 사용할 수 없습니까?

편집 :

내가 메멘토 클래스는 정적뿐만 아니라 통계 클래스했다,하지만 난 여전히 오류를 얻고있다. 아직 Model.Stats

java.io.NotSerializableException: cz.melkamar.adp.shooter.model.Model 
    - field (class "cz.melkamar.adp.shooter.model.Model$Stats", name: "this$0", type: "class cz.melkamar.adp.shooter.model.Model") 
    - object (class "cz.melkamar.adp.shooter.model.Model$Stats", [email protected]) 
    - field (class "cz.melkamar.adp.shooter.model.Model$Memento", name: "stats", type: "class cz.melkamar.adp.shooter.model.Model$Stats") 
    - root object (class "cz.melkamar.adp.shooter.model.Model$Memento", [email protected]) 
+0

클래스'Model' 또는 내부 클래스'Stats'에는 직렬화되지 않는 객체에 대한 참조를 보유하는 멤버 또는 (익명) 멤버가 있습니다. – Jesper

답변

0

비 정적 내부 클래스의 인스턴스에 this 참조가 외부 클래스의 인스턴스에 대한 숨겨진 참조가 한 것 같다. 즉, 내부 클래스의 인스턴스를 직렬화하려는 경우 외부 클래스의 인스턴스가 함께 직렬화됩니다. 외부 클래스가 직렬화 가능하지 않으면 java.io.NotSerializableException이됩니다.

는 외부 클래스의 인스턴스가 내부 클래스의 인스턴스와 함께 직렬화하지 않으려면, 다음 내부 클래스 static합니다

public class Model { 
    // ... 
    public static class Memento implements Serializable { 
     protected ModelData data; 
     // ... 
    } 
} 

static 내부 클래스는이하지 않습니다 외부 클래스의 인스턴스에 대한 참조.

+0

(.. 내가 의견을 쓰는 중이었습니다.) 정적이라는 용어는 나를 혼란스럽게했고 지금까지는 "중첩 된 정적 클래스"가 의미하는 것을 실제로 찾지 않았습니다. "정적 멤버", "정적 메서드"또는 C# 유사 정적 클래스의 의미로 정적이 아닙니다. 그래도 여전히 NotSerializableException이 발생합니다. 수정 된 질문을보십시오. –

+0

연속성은 "전염성이있다". 'Memento'의 모든 멤버 변수의 타입 또한 직렬화 가능해야합니다. 예를 들어,'ModelData'도 직렬화 가능해야하고'ModelData'가 참조하는 모든 타입도 반드시 같아야합니다. – Jesper

+0

자바 직렬화를 사용하지 않는 것이 좋지만 다른 메커니즘을 사용하여 객체 상태를 저장하는 것이 좋습니다 JSON 또는 XML과 같은 잘 알려진 표준 형식을 기반으로합니다. 자바 직렬화는 이해하기 어려운 바이너리 형식을 사용하며 소스 코드에 매우 밀접하게 연결됩니다 (멤버 변수를 추가하면 더 이상 직렬화 된 객체를 읽을 수 없습니다). – Jesper