Java中的Memento模式 - 内部类的序列化

时间:2016-11-29 14:11:38

标签: java serialization memento

免责声明 - 这是学期学期项目的一部分。

我们应该使用Memento模式来保存对象状态。该对象是MVC中的模型。所以我现在的方式是(简化):

<Window x:Class="WPF_StackOverFlow_Lab.Test1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WPF_StackOverFlow_Lab"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<DockPanel LastChildFill="False" IsEnabled="{Binding IsWindowEnabled}" MinWidth="724" Background="Red">
    <!-- save notifictaion popup -->
    <Label DockPanel.Dock="Top" Margin="10" FontSize="15" Foreground="Green" Content="Constants Configuration" x:Name="ML_0003" />
    <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="10 0">
        <Label Content="Select Constant Type" Margin="0 0 10 0" />
        <ComboBox Width="150" ItemsSource="{Binding ComboNames}" DisplayMemberPath="Value" SelectedValuePath="Key" SelectedValue="{Binding SelectedComboType}" />
    </StackPanel>
    <ListBox DockPanel.Dock="Top" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Stretch"  Margin="10" ItemsSource="{Binding Combos}" SelectedItem="{Binding SelecetedCombo}" ScrollViewer.CanContentScroll="False" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Margin="0 0 0 5">
                    <Label Content="{Binding Index}" Margin="10 0" Width="20" />
                    <TextBox Width="150" Margin="0" IsEnabled="{Binding IsEditable}" Text="{Binding Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</DockPanel>

我已经读过,由于合理的原因,拥有Seri​​alizable内部类而外部类不是Java。但是,在我的情况下,我不需要在内部类被实例化时使用外部类。内在根本不需要外部。它只是这样构造,以便外部类可以访问内部成员。

这是我的课程Memento描述所说的:

enter image description here

......这也是有道理的。只有模型应该能够访问Memento中的详细信息。 “看守”对象(处理从磁盘保存/检索数据的对象)不应该在对象内部看到。由于Java没有好友类,因此应该采用这种方式。

这是否意味着为了按照建议实现它我不能使用序列化?

修改

我使Memento类静态,以及Stats类,但我仍然得到错误。似乎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 } }

中仍有this引用
Model.Stats

1 个答案:

答案 0 :(得分:0)

非静态内部类的实例具有对其外部类的实例的隐藏引用。这意味着如果要序列化内部类的实例,则外部类的实例将与其一起序列化。如果外部类不可序列化,那么您将获得java.io.NotSerializableException

如果您不希望外部类的实例与内部类的实例一起序列化,那么请创建内部类static

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

static内部类没有对其外部类的实例的引用。