プロパティ初期化の順序依存を回避
プロパティ読み込みの制御
load
がプロパティ値を設定する順序にプロパティ値が依存している場合、問題が生じることがあります。
クラスの設計が次の両方に該当するとします。
プロパティの set メソッドが別のプロパティ値を変更する。
プロパティ値が他のプロパティ値から算出される。
この場合、一連のプロパティ値を変更した後のオブジェクトの最終的な状態は、プロパティを設定する順序に左右される可能性があります。この順序への依存関係は、オブジェクトの読み込み結果に影響を及ぼす可能性があります。
関数 load
はプロパティ値を特定の順序で設定します。この順序は、保存されたオブジェクトのプロパティが設定された順序とは異なる場合があります。結果として、読み込まれたオブジェクトには、保存したときとは異なるプロパティ値が設定される可能性があります。
非依存プロパティの復元
プロパティの関数 set が他のプロパティの値を変更する場合は、そのプロパティの Dependent
属性を true
に設定します。MATLAB® は依存プロパティの値の保存または復元をしません。
依存プロパティによって設定された値を保存するには、非依存プロパティを使用します。この場合、関数 load
は保存されたものと同じ値で非依存プロパティを復元します。関数 load
は依存プロパティの set メソッドを呼び出しません。保存されたファイルにそのプロパティの値が存在しないためです。
プライベート ストレージをもつ依存プロパティ
Odometer
クラスは、オブジェクト読み込みの際に、復元するプロパティを制御することによって順序への依存を回避します。
Units
プロパティは依存関係にあります。このプロパティの set メソッドはTotalDistance
プロパティを設定します。したがって、load
はUnits
プロパティの set メソッドを呼び出しません。関数 load は、
TotalDistance
をオブジェクト保存時の値に復元します。
classdef Odometer properties(Constant) ConversionFactor = 1.6 end properties TotalDistance = 0 end properties(Dependent) Units end properties(Access=private) PrivateUnits = 'mi' end methods function unit = get.Units(obj) unit = obj.PrivateUnits; end function obj = set.Units(obj,newUnits) % validate newUnits to be a char vector switch(newUnits) case 'mi' if strcmp(obj.PrivateUnits,'km') obj.TotalDistance = obj.TotalDistance / ... obj.ConversionFactor; obj.PrivateUnits = newUnits; end case 'km' if strcmp(obj.PrivateUnits,'mi') obj.TotalDistance = obj.TotalDistance * ... obj.ConversionFactor; obj.PrivateUnits = newUnits; end otherwise error('Odometer:InvalidUnits', ... 'Units ''%s'' is not supported.', newUnits); end end end end
Odometer
のインスタンスを作成し、次のプロパティ値を設定するとします。
odObj = Odometer;
odObj.Units = 'km';
odObj.TotalDistance = 16;
オブジェクトを保存する際は、次のようになります。
ConversionFactor
は、Constant
プロパティなので保存されません。TotalDistance
は保存されます。Units
はDependent
プロパティなので保存されません。PrivateUnits
は保存され、Units
の現在値に対してストレージを与えます。
オブジェクトを読み込む際は、次のようになります。
ConversionFactor
はクラス定義から得られます。TotalDistance
は読み込まれます。Units
は読み込まれないので、その set メソッドは呼び出されません。PrivateUnits
は保存されたオブジェクトから読み込まれます。
Units
プロパティが Dependent
でない場合、読み込むと、その set メソッドを呼び出し、TotalDistance
プロパティが再び設定されます。
他のプロパティから計算されたプロパティ値
Odometer2
クラスの TripDistance
プロパティは、他の 2 つのプロパティ TotalDistance
および TripMarker
のみに依存しています。
このクラスでは、読み込み時にプロパティ値を初期化する際、TripDistance
プロパティを dependent にすることで順序への依存を回避します。MATLAB は TripDistance
プロパティの値の保存や読み込みを行いませんが、プロパティ get メソッドで TripDistance
の計算に使用する 2 つのプロパティの値は保存して読み込みます。
classdef Odometer2 properties TotalDistance = 0 TripMarker = 0 end properties(Dependent) TripDistance end methods function distance = get.TripDistance(obj) distance = obj.TotalDistance - obj.TripMarker; end end end