状態をクラスで表現するときに、ポリモフィズムを使うよりもEitherを使った方がスマートに表現できると思います。
ポリモフィズムを使ったパターン
「申込がない」状態をいわゆるNullオブジェクトで表現

参考:サービスクラス
class OrderService {
void order(UserId id) {
Order order = orderRepository.findBy(id);
// orderがExistのときは例外をスロー
Exist exist = order.order();
orderRepository.order(exist);
}
}
Existにorderを実装しなくてはならないのが微妙。例えばCompleteとかCancelなど、状態が増えた時に使われない機能をいっぱい実装しなきゃいけなくなります。
Eitherを使ったパターン

これならorderはNotExistのみ実装すればOK。 また、以下のような状態遷移表を書いたときにOrderに表をそのまま記述できる利点もあります。
| 申込なし | 申込あり | |
|---|---|---|
| 申し込む | 申込ありに遷移 | エラー |
class Order {
Either<NotExist, Exist> value;
Validation<String, Exist> order(){
return value.fold(
n -> Validation.valid(n.order()), // 申込なしの処理
e -> Validation.invalid("order is already exist") // 申込ありの処理
);
}
}
状態が3つ以上のときどうする?
こんなの作ってみました。
4つ以上は気が向いたら作ります。