背景
SoS(システムオブシステムズ)において、
他の同じ粒度のSoSと境界をまたいでデータの連携をするという場面がある。
その際にデータの不整合があっては決していけない。データの安全性が非常に求められる。
そこでオブジェクト指向の【不変オブジェクト】の設計スタイルを抽象化して
システムのスケールにまでその設計思想を盛り込んだ独自アイデアを記載する。
不変オブジェクトについて
通常のシステム内のオブジェクトの設計は、【値の不整合を避けたい】というリスク回避動機が伴う。
これに対して特に何も施策を打っていない状況下で、
下図のオブジェクトAが、クラスBやCから呼び出される前の属性aの値が10であったとする。
仮にこのAの持つ処理が、属性aに5を足して呼び出し元へ戻すというロジックであったとする。
BはAの処理を呼び出し、aの値を10→15へ変更しその値を戻してもらったとする。
このあとCがAを呼び出すが、Cは呼び出す前にaが10のつもりで呼び出しているので、
なぜか20が値として返ってきてしまい困惑する。
このように何もデータの不整合リスクに対する処置をしていないと思わぬバグを発生させる。
そこで値が不用意に変更されないようにイミュータブルに設計しておくことが求められる。
また下図のように呼び出される側に不変オブジェクト(赤)や可変オブジェクト(緑)が混在していると、
呼び出し元のClientは自分が呼び出す相手が、不変に設計されているのか?
それとも可変に設計されているのか?わからず、安心して呼び出すことができない。
そのため仮に可変オブジェクトを用いるなら、
そのクラスが存在するコンポーネント内の物はすべて可変にするなどのわかりやすい設計が求められるであろう。(下図)
しかも可変パッケージに存在するGやHは、状態変化が容易なものである場合に限り、
リスク低減のため不変にしてしまうことが良いと考えられる。
ここでもちろんインスタンスが大量に生成されるリスクから、パフォーマンスの低下が考えられるが、
近年の優秀なハードの性能がそのリスクを大幅に低減してくれるため、
不変にすることのメリットの方が上回るといえる。
この考え方をシステムオブシステムズのスケールでの設計にも取り入れようと考えた。
その考察を以下で行う。
上記でのクラスを1つのシステムに見立てて考察した。
システムオブシステムズでの不変設計
簡単のためにシステムA、B、Cのみで、かつAにはクラスS、Tだけ存在することにする。
※図は模式図のためシステムBから直接オブジェクトSやTが参照されるわけではない。
必ずシステムAのバウンダリなどを介してS、Tに行きつくが、この図ではそこは本質的に重要部分でないので省略した。
このときSoSでの情報の連携をする際には、上記の不変オブジェクトの考察から
【必ずオブジェクトは不変オブジェクト設計】にすることがマストである。
でないと、システムBを呼び出すようなシステムDがいた場合に、
値の不整合がなぜだか起きていて、その発生源を探すのに
システムB内のオブジェクトの設計を解析して、さらにシステムA内のオブジェクトの設計を解析して~~
とめちゃくちゃ苦労することが容易に想像がつく。
仮にシステムA内のオブジェクトを不変オブジェクトになるように設計していたとしても、
システムB側で可変になるような設計をしてしまっていた場合には、
やはりデータの不整合リスクを回避することは困難になる。
以上のことから、SoSでシステム間を連携させる場合には、
必ず連携をする予定のシステム側でデータの不整合が起きないように、
すべてのオブジェクトに対して不変オブジェクト設計がされていることが保証されたうえで
SoSとして連携させるという手段を取るのが安全性を担保できるといえる。
また、SoSの1つのリソースとしてそのシステムが使用されている場合、
そのシステムに新しいクラスを追加する場合にもやはり不変に設計しなくてはならない。
最近のシステムは不変に設計されているものが多いと聞きますが、
いずれにしても古いシステムなどをSoSの1つのリソースとして使用する際には、
あらかじめ不変に設計されているかの要チェックが必要であり、
この不変に設計するっていうのをアーキテクチャガイドラインに必ず載せることを個人的に推奨したい。